K8s 1.21使用containerd运行时如何实现容器内运行容器功能?
K8s 1.21 containerd运行时环境下实现Pod内运行容器的方案
方案1:直接复用原有Docker DinD配置(零改造成本)
K8s的底层运行时替换为containerd后,不会影响Pod内的程序运行逻辑,你之前在用的Docker DinD方案可以直接照搬使用,无需做任何调整:
- 继续使用你之前的
docker:dind镜像 - 保留原有的特权模式配置、
/var/lib/docker存储挂载、cgroup路径挂载等配置即可 - Pod内部运行的dockerd完全独立于宿主机的containerd运行时,原有操作逻辑、命令完全不变
方案2:共享宿主机containerd套接字(轻量高性能,无额外运行时开销)
如果你不想在Pod内部额外运行独立的容器运行时进程,可以选择直接调用宿主机的containerd实现容器创建,整体性能损耗极低,适合不需要隔离运行时的场景:
- 配置步骤:
- 将宿主机的
/run/containerd/containerd.sock文件绑定挂载到Pod内的相同路径 - 确保Pod内的运行用户对该套接字文件有读写权限,推荐使用root用户运行容器,或者手动修改挂载后sock文件的权限
- 在Pod的镜像中安装containerd客户端工具:
ctr(containerd原生命令行)、nerdctl(兼容Docker CLI的containerd客户端)均可,也可以单独安装docker-ce-cli包,继续使用你熟悉的docker命令
- 将宿主机的
- 验证方式:在Pod内执行
ctr namespaces list,如果能正常返回宿主机的containerd命名空间列表则说明配置生效 - 注意:建议你在操作时指定专属的自定义namespace(如
ctr -n my-dind-ns <命令>),避免误操作影响宿主机上的K8s系统容器
方案3:嵌套运行containerd(完全隔离,原生适配containerd生态)
如果你希望完全适配containerd生态,不需要在内部运行docker,可以选择在Pod内独立运行一套containerd运行时,和原Docker DinD逻辑完全一致,和宿主机运行时完全隔离:
- 配置要求:
- 给Pod开启特权模式:
privileged: true,或者最小化赋权,添加SYS_ADMIN、NET_ADMIN等必要的CAP权限 - 绑定挂载宿主机的
/sys/fs/cgroup路径到Pod内,或者用tmpfs挂载该路径 - 使用内置containerd、runc、CNI插件的基础镜像,也可以自行打包对应镜像
- 给Pod开启特权模式:
- 操作步骤:
- Pod启动后,在内部执行
containerd &后台启动运行时,或者用systemd执行systemctl start containerd启动 - 执行
ctr version,如果同时返回client和server的版本信息,说明内部containerd运行成功,后续就可以通过ctr/nerdctl工具在内部创建、管理容器
- Pod启动后,在内部执行
注意事项
- 特权模式存在较高的安全风险,生产环境使用时请严格限制Pod的权限范围,只授予必要的CAP权限,不要随意开启全量特权
- 共享宿主机套接字方案下,所有在Pod内创建的容器实际都运行在宿主机上,删除资源时请做好校验,避免误删K8s系统组件
- 三种方案可以根据你的实际场景选择,零改造优先选方案1,追求性能优先选方案2,纯containerd生态优先选方案3
内容的提问来源于stack exchange,提问作者Rajendar Talatam
相关产品推荐
相关产品推荐

