docker支持IPV6

这两天因为某个需求,一直在研究这个问题。

网上都看了,什么ipv6 subnet daemon.json 之类的,都是一通抄,还是没有能说明白关键联系的,很多都是抄的碎片化信息。

因为说不清楚关联,所以就没法在实际环境中结合实际灵活解决问题。

docker的版本

docker的版本问题。初步结论是:docker engine 的版本大于等于20.10.2 。参见:https://zhuanlan.zhihu.com/p/342633966

经过验证,如果版本不对,在配置daemon.json时,就会报错,令人莫名, 实际是版本的ipv6支持问题,不支持新字段。

注意:系统默认的docker版本是跟这个系统的代码版本库走的,所以想要最新的docker版本,首先要确认自己的系统,否则要手动安装。

daemon.json

这个也是网上看到最多的:

{
  "ipv6": true,
  "fixed-cidr-v6": "fd00::/80",
  "experimental": true,
  "ip6tables": true
}

在跳过了docker版本的坑,这里就可以配置了。这里核心的是那个fixed-cidr-v6, 很多人看不懂这个,不知道这个要怎么改,这个就要自己实际弄懂ipv6的子网了,要根据自己的外网IPV6地址,配置实际的子网段。请google搜索 "ipv6 subnet"。

测试docker获取ipv6能力

docker run --rm -it busybox ping -6 -c4 ipv6-test.com
docker run --rm -it busybox ifconfig

正常返回,就说明系统的docker ipv6能力正常

在线免费托管docker的平台选择

  1. dockerhub,目前在用,由于其商业化策略导致的不可控变化,打算放弃
  2. github,Container Registry:因为访问不稳定和token的问题,暂时不考虑
  3. gitlab,Container Registry
  4. ECR, amazon出品,这里不考虑,因为账号体系的原因

所以暂时就一个可选项:gitlab

放一个相关的比较参考图:
file

github 容器注册服务器介绍

你可以在ghcr.io上存储和管理你的Docker和OCI镜像。

关于容器注册服务器支持类型

  • Docker Image Manifest V2, Schema2
  • Open Container Initiative 规格

容器服务器支持外部layer,比如windows 镜像。

登陆容器注册服务器

登陆ghcr.io建议使用GITHUB_TOKEN工作流来提高安全性。

  1. 创建一个PAT。设置好权限
  2. 建议将PAT设置为环境变量
    $ export CR_PAT=YOUR_TOKEN
  3. 通过CLI登陆容器注册服务器
    $ echo $CR_PAT | docker login ghcr.io -u USERNAME --password-stdin
    > Login Succeeded

发布容器镜像

$ docker push ghcr.io/OWNER/IMAGE_NAME:latest
or
$ docker push ghcr.io/OWNER/IMAGE-NAME:2.5

当第一次发布容器时,默认是私有的,需要改变可见性,需要自己去设置:Configuring a package's access control and visibility

获取镜像

通过digest获取精准镜像

  1. 获取digest,通过docker inspect或者docker pull命令,然后拷贝得到的SHA值
    $ docker inspect ghcr.io/OWNER/IMAGE_NAME
  2. 删除本地镜像
    $ docker rmi  ghcr.io/OWNER/IMAGE_NAME:latest
  3. 通过@YOUR_SHA_VALUE 获取精准的镜像
    $ docker pull ghcr.io/OWNER/IMAGE_NAME@sha256:82jf9a84u29hiasldj289498uhois8498hjs29hkuhs

通过名字

docker pull ghcr.io/OWNER/IMAGE_NAME

通过名字和版本

$ docker pull ghcr.io/OWNER/IMAGE_NAME:1.14.1

获取当前最新版

$ docker pull ghcr.io/OWNER/IMAGE_NAME:latest

编译镜像

$ docker build -t hello_docker .

tagging镜像

  1. 找到image id
    $ docker images
    > REPOSITORY                                            TAG                 IMAGE ID            CREATED             SIZE
    > ghcr.io/my-org/hello_docker         latest              38f737a91f39        47 hours ago        91.7MB
    > ghcr.io/my-username/hello_docker    latest              38f737a91f39        47 hours ago        91.7MB
    > hello-world                                           latest              fce289e99eb9        16 months ago       1.84kB
  2. 通过ID和镜像名字和托管的主机来tag对应的镜像
    $ docker tag 38f737a91f39 ghcr.io/OWNER/NEW_IMAGE_NAME:latest

baota宝塔docker制作

这两天瞎折腾,因为数据库不一致的问题,一气之下把baota image删掉了,很多跟数据库相关的服务都歇了。

宝塔自用,在nas环境配合下数据库,搞个网络环境还是很方便的。

再重新拉取baota镜像时,发现怎么也访问不了,看日志,也没发现什么线索,所以才萌生了自己搞个docker的念头,主要是想定位下问题。

根据官方 www.bt.cn 最新的安装脚本制作了最新的 docker镜像:
https://gitlab.com/hiproz/baota-centos7-docker

特点:

  1. 和一般宝塔docker不同的是,采用延后安装的方式,支持将整个/www暴露出来,这样就可以将应用数据特别是数据库数据映射到用户空间,不至于不小心删除docker时,整个数据库数据丢失。
  2. 支持自动重新安装,如果系统发生未知问题,无法通过系统内更新,可以通过外部脚本的need_update 来更新。

docker的使用

docker run -tid --name baota --restart always -v /your-local-dir:/www -p your-local-port:8888 registry.gitlab.com/hiproz/baota-centos7-docker

安装进度日志

查看 run.log

默认登录路径和账号密码

查看映射路径下的default.txt, 注意要使用实际映射的端口,default.txt显示的是系统内部的端口。

如何修改已经创建docker的运行参数

update 命令

eg:

docker container update --restart=always 容器名字

修改container的配置文件

  • 先停止容器
  • 停止docker: systemctl stop docker
  • 修改配置文件,配置文件路径为/var/lib/docker/containers/容器ID,对应的配置文件为hostconfig.json和config.v2.json
  • 启动docker: systemctl start docker
  • 启动容器

注意,重启docker很重要,否则修改完的配置文件,重启容器后会被还原

Failed to get D-Bus connection: Operation not permitted

在docker中启用systemd时,过程中出现:
Failed to get D-Bus connection: Operation not permitted

原因

systemd维护系统服务程序,它需要特权去会访问Linux内核。而容器并不是一个完整的操作系统,只有一个文件系统,而且默认启动只是普通用户这样的权限访问Linux内核,也就是没有特权,所以自然就用不了!

解决

添加授权:
docker run -d -name centos7 --privileged=true centos:7 /usr/sbin/init

增加授权会提高风险,需要仔细评估具体的运行脚本和命令,避免对宿主造成安全风险

为什么有必要在docker中使用systemd

为什么要在docker中使用systemd

根据Walsh所说,容器中没有systemd最大的问题是它“退回到了使用初始化脚本之前。”每个镜像作者都在容器内创建自己的疯狂的启动脚本,而不是使用软件包作者精心制作的启动脚本。他演示了在具有systemd的容器内,服务初始化是何尝的简单,创建一个运行Apache httpd服务器的容器,其Dockerfile只有三行:

FROM fedora
RUN yum -y install httpd; yum clean all; systemctl enable httpd;
CMD [ "/sbin/init" ]

参考:
1. https://lwn.net/Articles/676831/ http://dockone.io/article/1093 (翻译)