当前位置: 首页 > 工具软件 > DIND > 使用案例 >

容器中的容器——利用Dind实现开箱即用的K3s

钱京
2023-12-01

代码的结构如下:

.
├── Dockerfile # 构建 dind-k3s
├── README.en.md
├── README.md
├── docker-entrypoint.sh # 容器启动脚本
└── utils
├── daemon.json # dockerd 配置文件
├── dind.conf # dockerd k3s 的进程管理配置文件
├── k3s-conf.yaml # k3s 配置文件
└── supervisord.conf # supervisord 配置文件
项目中的关键文件是 Dockerfile,全文如下:

FROM ubuntu:20.10
LABEL auther=“guox@goodrain.com”
WORKDIR /app

安装必要的依赖

RUN sed -i -e ‘s/ports.ubuntu.com/mirrors.aliyun.com/g’
-e ‘s/archive.ubuntu.com/mirrors.aliyun.com/g’
-e ‘s/security.ubuntu.com/mirrors.aliyun.com/g’ /etc/apt/sources.list
&& apt update
&& apt install -y supervisor iptables wget vim
&& rm -rf /var/lib/apt/lists/*

安装 docker k3s kubectl

根据构建环境的 CPU 架构区分下载地址

RUN Arch=“KaTeX parse error: Undefined control sequence: \ at position 10: (arch)"; \̲ ̲ case "Arch” in
‘x86_64’)
docker_url=‘https://download.docker.com/linux/static/stable/x86_64/docker-20.10.11.tgz’;
k3s_url=“https://github.com/rancher/k3s/releases/download/v1.22.3+k3s1/k3s”
kubectl_url=“https://storage.googleapis.com/kubernetes-release/release/v1.22.3/bin/linux/amd64/kubectl”
;;
‘aarch64’)
docker_url=‘https://download.docker.com/linux/static/stable/aarch64/docker-20.10.11.tgz’;
k3s_url=“https://github.com/rancher/k3s/releases/download/v1.22.3+k3s1/k3s-arm64”
kubectl_url=“https://storage.googleapis.com/kubernetes-release/release/v1.22.3/bin/linux/arm64/kubectl”
;;
esac
&& wget -O docker.tgz “KaTeX parse error: Undefined control sequence: \ at position 13: docker_url" \̲ ̲ && tar xzf doc…k3s_url”
&& wget -O /usr/local/bin/kubectl “$kubectl_url”

文件的变更是最频繁的变更,把拷贝文件的过程放在安装软件包、下载大体积资源的后面,可以更合理的利用镜像构建缓存,极大的节约构建时间

ADD . .

配置文件的处理

RUN chmod +x /usr/local/bin/k3s /usr/local/bin/kubectl /app/docker-entrypoint.sh
&& mkdir -p /app/logs/ /app/k3s
&& cp utils/dind.conf /etc/supervisor/conf.d/dind.conf
&& cp utils/daemon.json /etc/docker/
&& cp utils/k3s-conf.yaml /app/k3s/config.yaml
&& cp utils/supervisord.conf /etc/supervisor/supervisord.conf

VOLUME [ “/var/lib/docker”, “/app/k3s” ]

启动脚本

ENTRYPOINT [ “/app/docker-entrypoint.sh” ]
CMD ["/usr/bin/supervisord"]
安装相关资源
最开始,我们需要在 dind-k3s 镜像中安装 docker 、k3s、kubectl 以及相关的软件包。这一操作被定义在了 Dockerfile。在安装过程中,可以根据执行构建操作的宿主机的 CPU 架构,选择对应的包进行安装。目前支持 x86_64 以及 arm64 两种架构。除此之外,dockerd 想要正常运行,还需要安装 iptables 软件包。同时安装的 supervisor 用于容器内部进程管理,放在后文中详细说明。所使用的版本列表如下:

Docker :20.10.11
K3s:v1.22.3+k3s1
Kubectl:v1.22.3
配置文件的处理
下一个重要步骤,是将 utils 下的配置文件,和启动脚本拷贝到镜像中,并且将配置文件分发到正确的位置中去。

实用 Tip:

文件的变更是最频繁的变更,把拷贝文件的过程放在安装软件包、下载大体积资源的后面,可以更合理的利用镜像构建缓存,极大的节约构建时间。

构建缓存的机制是,每执行一条指令,将会形成一个镜像层作为构建缓存。下一次构建时,有变化的指令之前的构建操作会引用上次构建已经形成的构建缓存。所以,应该尽量将耗时时间长的安装包、下载包的操作,放在靠前的 RUN 指令中执行。

启动脚本与CMD命令
最后,指定启动脚本和 CMD 命令。我在启动脚本中添加了一些试验性的逻辑操作,如变更 dockerd 启动参数之类的,大家可以自行参考。

在这里,我想重点解释的是启动脚本和 CMD 之间的关系。在 ENTRYPOINT 和 CMD 同时出现时,CMD 会作为参数传递给 ENTRYPOINT。当前的配置等效于 /app/docker-entrypoint.sh /usr/bin/supervisord 。所以,在 /app/docker-entrypoint.sh 脚本的最后,添加了 exec $@ 来承接后续的参数。

ENTRYPOINT [ “/app/docker-entrypoint.sh” ]
CMD ["/usr/bin/supervisord"]

等效于

bash -c /app/docker-entrypoint.sh /usr/bin/supervisord
Supervisor 进程管理工具
鉴于 dind-k3s 容器中,注定有至少两个进程 (docker、 k3s)要启动,那么就有必要引入一个进程管理工具来托管它们。在容器中使用 systemd 管理进程需要做很多特殊的操作,我转而选择了 supervisor 进行进程管理。

项目中的 utils/supervisord.conf 是 supervisord 本身所使用的配置文件,主要负责配置其日志路径,以及 被托管的进程配置文件的位置 。我将其定义为 /etc/supervisor/conf.d/*.conf ,符合要求的配置文件,其内部定义的进程都会受到 supervisord 的监管。换句话说,我需要将 docker 、 k3s 的启动方式定义到配置文件,放到上面说的路径中,容器启动时,supervisord 会负责带起它们的进程。

定义好的配置如下:

[program:dind]
priority=20
command=/usr/local/bin/dockerd
user=root
autostart=true
autorestart=true
restartpause=10
stdout_logfile=/app/logs/dind.log
stdout_logfile_maxbytes=10mb
stdout_logfile_backups=3
redirect_stderr=true

[program:k3s]
depends_on=dind
priority=20
command=/usr/local/bin/k3s server --config /app/k3s/config.yaml
user=root
autostart=true
autorestart=true
restartpause=10
stdout_logfile=/app/logs/k3s.log
stdout_logfile_maxbytes=10mb
stdout_logfile_backups=3
redirect_stderr=true
dockerd 的配置文件为 /etc/docker/daemon.json,自定义的参数追加,参考 /app/docker-entrypoint.sh。

k3s 的配置文件为 /app/k3s/config.yaml,该文件位于持久化目录中,修改其配置,只需要在宿主机直接修改该文件后重启 dind-k3s 容器。

supervisord 提供很多高级功能,在这里被用到的包括:

依赖关系,这个是最重要的,k3s 开始启动需要在 dockerd 启动完成之后。

自动重启策略

日志输出路径、分割、尺寸限定

构建镜像
一切准备就绪,可以开始构建镜像了,构建命令需要在项目根目录下执行。

docker build -t dind-k3s .
经过检测,镜像可以在 x86_64 以及 arm64 环境下构建成功并使用。

启动容器
镜像构建完成后,需要以特权模式启动容器实例。

sudo docker run -d
–name=my-dind-k3s
–privileged
-v ~/data/docker:/var/lib/docker
-v ~/data/k3s:/app/k3s
dind-k3s
亚马逊测评 www.yisuping.cn

 类似资料: