K3s 内置 cri-dockerd 全解析:`--docker` 标志如何让 Docker 运行时在 Kubernetes 1.24+ 继续可用
K3s 内置 cri-dockerd 全解析--docker标志如何让 Docker 运行时在 Kubernetes 1.24 继续可用【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3sKubernetes 上游在 1.24 分支移除了 kubelet 内置的 dockershim导致 Docker 不再被 kubelet 直接支持。本文以 K3s 仓库中的架构决策记录ADRdocs/adrs/cri-dockerd.md 为骨架完整还原 K3s 从要求用户自行部署 cri-dockerd到将 cri-dockerd 内嵌进 K3s 二进制的决策过程并结合 pkg/agent/cridockerd 等源码深入讲解--docker标志背后的启动流程、参数生成、平台差异与验证手段。读完本文你将理解 Docker 运行时在 K3s 中的官方支持方式并能直接上手配置与排障。一、决策背景dockershim 移除与 Docker 运行时的身份转变1.1 上游变化Kubernetes 1.24 移除 dockershim自 Kubernetes 1.24 分支起上游不再在 kubelet 中内置 dockershim。这意味着kubelet 不再直接支持 Docker 容器运行时docker守护进程本身仍然存在但 kubelet 无法再通过原生的 dockershim 路径与它通信继续使用 Docker 就必须引入一个中间翻译层——cri-dockerd将CRIContainer Runtime InterfaceAPI 翻译为 Docker API。1.2 K3s 社区对 Docker 的依赖CI 与开发环境的现实需求K3s 经常被用在 CI 或开发环境中这些场景下以 Docker 作为容器运行时非常方便镜像链路统一、调试工具链成熟、与本地 Docker 环境一致。然而用户往往并不具备自行安装和管理 cri-dockerd 的能力——它不像 Docker 本身那样易于获取和运维。因此这个问题对 K3s 团队而言并非简单的删掉一个 flag而是关系到大量社区用户的迁移路径。ADR 中记录的内部讨论也印证了这一点有观点认为应尽量缩小维护面Less surface area for bug fixes and CVEs不主动为 Docker 提供便利也有观点认为 K3s 主打 lightweight1.24 恰好是减重的好时机关键分歧在于不内置 dockershim 的情况下用户能否自行组合 cri-dockerd 达到同等效果。讨论中确认用户完全可以手动安装并启动 cri-dockerd然后运行k3s agent --container-runtime-endpointunix:///var/run/cri-dockerd.sock但这需要额外操作体验成本较高。这段讨论最终指向一个折中方案K3s 既不在 kubelet 里塞回 dockershim维持上游方向也不再让用户手工组装 cri-dockerd而是把 cri-dockerd 直接嵌入 K3s 进程。二、第一轮决策不内置 dockershim让用户自行部署 cri-dockerd在讨论之后K3s 最初采纳的是最小化内置路线明确不包含 dockershim要求用户自行部署 cri-dockerd再通过--container-runtime-endpoint指向 cri-dockerd 的 socket相应地--docker标志被移除/禁用在 1.24 的早期版本中使用--docker会直接返回错误提示用户改为安装并使用 cri-dockerd。这一方案虽然保持了二进制体积和代码维护面的克制但对社区造成了明显冲击——正如 ADR 中所记录社区反馈K3s 仓库 issue #5741 等显示K3s 大量用于 CI 和开发环境Docker 运行时是刚需而 cri-dockerd 相对 Docker 本身更难获取、更难管理用户并不具备自行安装维护的条件。三、最终决策Accepted内嵌 cri-dockerd--docker成为 drop-in 替代面对社区反馈K3s 团队于2022-07-29更新了决策状态为 Accepted核心内容如下我们将在 K3s 中内嵌 cri-dockerd并在使用--docker标志时启动它。这是对 K3s 此前kubelet 内置 dockershim行为的 drop-in无感替换方案既满足了用户对 K3s 支持 Docker 容器运行时的既有预期也降低了用户迁移到 Kubernetes 1.24 的难度。该决策同时带来了两个明确的后果二进制与镜像体积增加自解压二进制和 Docker 镜像的体积会增加数 MB多出的正是内嵌的 cri-dockerd 及其依赖维护负担转移K3s 团队需要承担 cri-dockerd 的持续跟进更新以及将 Docker 作为容器运行时进行支持的责任。从当前仓库源码来看这一决策已被完整落地--docker标志不仅没有报错还会启动内嵌的 cri-dockerd见下文源码解析。四、源码级实现解析--docker背后发生了什么4.1 启动入口cridockerd.Run核心实现位于 pkg/agent/cridockerd/cridockerd.go。在 executor 层--docker对应的运行时启动函数是Embedded.Docker见 pkg/executor/embed/embed.go它直接调用cridockerd.Run(ctx, cfg)。整个启动流程分三步配置初始化调用setupDockerCRIConfig(ctx, cfg)探测 Docker 守护进程信息见下文 4.3生成 cri-dockerd 参数通过getDockerCRIArgs(cfg)构造完整的命令行参数然后基于 Mirantis/cri-dockerd 的cmd.NewDockerCRICommand创建命令并异步执行command.ExecuteContext(ctx)等待服务就绪通过 pkg/agent/cri/cri.go 中的cri.WaitForService以 1 秒间隔轮询 cri-dockerd 的 gRPC socket直到 CRI 服务可用Version调用成功才返回确保 kubelet 启动时后端已就绪。若 cri-dockerd 进程异常退出非context.CanceledK3s 会通过signals.RequestShutdown触发整体关停启动过程中的 panic 也会被 recover 并记录完整堆栈后以 Fatal 级别退出cridockerd.goL35-L46。4.2 参数生成getDockerCRIArgs完整参数表getDockerCRIArgscridockerd.go负责把 K3s 内部配置翻译成 cri-dockerd 可识别的 CLI 参数。下表汇总了各参数的来源与默认值cri-dockerd 参数K3s 配置来源说明--container-runtime-endpointcfg.CRIDockerd.Addresscri-dockerd 对外提供的 CRI socketLinux 下为unix:///run/k3s/cri-dockerd/cri-dockerd.sock--cri-dockerd-root-directorycfg.CRIDockerd.Root数据目录默认DataDir/agent/cri-dockerd--streaming-bind-addr固定值127.0.0.1:10010容器流式exec/log服务监听地址与 types.go 中的StreamServerPort 10010呼应--log-levelcfg.CRIDockerd.Debug或环境变量Debugtrue时设为debugCRIDOCKERD_LOG_LEVEL环境变量优先级更高--ipv6-dual-stackcfg.AgentConfig.NodeIPs节点 IP 同时含 IPv4 与 IPv6双栈时设为true--docker-endpointcfg.ContainerRuntimeEndpoint指向 Docker 守护进程 socket无unix://前缀时自动补全--cni-conf-dir/--cni-bin-dircfg.AgentConfig.CNIConfDir/CNIBinDir指定 CNI 配置与二进制目录--network-plugincfg.AgentConfig.CNIPlugin使用--docker时固定为cni--pod-infra-container-imagecfg.AgentConfig.PauseImage沙箱pause镜像CLI 默认值为rancher/mirrored-pause:3.10.2见 pkg/cli/cmds/agent.go--runtime-cgroupscgroups 探测结果通过cgroups.CheckCgroups()获取 runtime cgroup 路径后传入这些参数行为均由单元测试 cridockerd_test.go 的Test_UnitGetDockerCRIArgs覆盖验证测试点包括默认参数恒存在、debug 与CRIDOCKERD_LOG_LEVEL覆盖关系、--docker-endpoint前缀补全、CNI 参数透传、network-plugincni开关以及双栈--ipv6-dual-stack判定。4.3 平台差异与配置联动cridockerd 的 socket 与 Docker 客户端配置按操作系统区分文件以 build tag 隔离Linuxconfig_linux.gosocketPrefix unix://CRI socket 为unix:///run/k3s/cri-dockerd/cri-dockerd.sock见 pkg/agent/config/config_linux.gosetupDockerCRIConfig会基于 Docker 官方 clientclient.FromEnvWithAPIVersionNegotiation连接 Docker 守护进程并调用c.Info(ctx)探测其CgroupDriver——若为systemd则把cfg.AgentConfig.Systemd置为true该值后续用于设置kubelet 的--cgroup-driver标志保证 kubelet 与 Docker 的 cgroup 驱动一致Windowsconfig_windows.gosocketPrefix npipe://CRI socket 为npipe:////.pipe/cri-dockerd见 pkg/agent/config/config_windows.gosetupDockerCRIConfig为空实现禁用构建nocridockerd.go存在no_cri_dockerdbuild tag可把 cri-dockerd 从二进制中剔除此时Run直接返回错误cri-dockerd disabled at build time。4.4 配置装配--docker如何接管运行时在 agent 配置装配阶段pkg/agent/config/config.go可以看到完整的运行时选择逻辑当nodeConfig.Docker true时调用applyCRIDockerdOSSpecificConfig设置平台相关 socket强制开启CNIPlugin true并将AgentConfig.RuntimeSocket指向 cri-dockerd 的 socket——kubelet 通过该地址接入 CRI当仅设置了--container-runtime-endpoint未加--docker时RuntimeSocket直接指向该外部 CRI socket否则走默认的 containerd 路径applyContainerdOSSpecificConfig。同时CRIDockerd.Root默认落在DataDir/agent/cri-dockerdCRIDockerd.Debug与全局 debug 开关联动见 config.go。4.5 CLI 标志面向用户的入口相关 CLI 标志定义在 pkg/cli/cmds/agent.go--docker(agent/runtime) (experimental) Use cri-dockerd instead of containerd——注意它仍被标注为 experimental--container-runtime-endpointDisable embedded containerd and use the CRI socket at the given path; when used with --docker this sets the docker socket path——即与--docker搭配使用时该参数的含义变为Docker 守护进程的 socket 路径对应 cri-dockerd 的--docker-endpoint无前缀时自动补unix://。五、实操指南在 K3s 上启用 Docker 运行时5.1 基础用法直接加--docker在 K3s 节点server 或 agent上启用 Docker 运行时最简单的方式curl -sfL https://get.k3s.io | sh -s - --docker或对已有集群的 agent 节点k3s agent --docker --server https://server:6443 --token token执行后 K3s 会启动内嵌 cri-dockerd监听unix:///run/k3s/cri-dockerd/cri-dockerd.sockWindows 为npipe:////.pipe/cri-dockerd将 kubelet 的RuntimeSocket指向该 socket自动启用 CNI 插件--network-plugincniflannel 等网络组件照常工作。5.2 指定 Docker 守护进程 socket若 Docker 未使用默认 socket可借助--container-runtime-endpoint指定 Docker 地址此时它不再表示 CRI 端点而是 docker-endpointk3s agent --docker --container-runtime-endpoint unix:///var/run/docker.sock从源码可知未带unix://前缀的路径会被自动补全两种写法等价该行为有单元测试覆盖。5.3 调整日志级别与调试传--debug给 K3s 会把 cri-dockerd 的--log-level置为debug也可直接设置环境变量CRIDOCKERD_LOG_LEVEL其优先级高于--debug派生值测试用例验证了CRIDOCKERD_LOG_LEVELtrace/warn均能覆盖默认 debug 设置。5.4 自定义 pause 镜像通过--pause-image可指定 cri-dockerd 使用的沙箱镜像--pod-infra-container-image仓库中该 flag 的默认值为rancher/mirrored-pause:3.10.2。在离线环境airgap下这一参数对于确保沙箱镜像可用尤为关键。5.5 验证是否生效# 查看 cri-dockerd socket 是否存在 ls -l /run/k3s/cri-dockerd/cri-dockerd.sock # 查看节点使用的运行时 kubectl get node -o wide若节点 Ready 且 kubelet 日志中显示 runtime 指向 cri-dockerd即表示 Docker 运行时链路已打通。六、总结从弃用 dockershim到内置 cri-dockerd的演进脉络回顾整个决策链Kubernetes 上游移除 dockershim → K3s 最初要求用户自装 cri-dockerd → 社区反馈CI/开发环境强依赖 Docker推动 K3s 将 cri-dockerd 内嵌进自解压二进制 →--docker标志成为对旧有 dockershim 行为的 drop-in 替代。这一演进在 cri-dockerd.md 中被完整记录并在当前仓库的pkg/agent/cridockerd、pkg/agent/config、pkg/executor/embed等模块中落地实现。值得留意的是其代价同样明确二进制与镜像体积增加数 MB且 K3s 需要持续跟进 cri-dockerd 上游并承担 Docker 运行时的支持责任。对于运维者而言理解这一取舍与实现细节有助于在 CI/开发场景中更自信地使用--docker也能在排查运行时为何指向 cri-dockerd socket等问题时快速定位到正确的代码路径与参数来源。【免费下载链接】k3sLightweight Kubernetes项目地址: https://gitcode.com/GitHub_Trending/k3/k3s创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
上一篇/下一篇内容由系统自动关联
返回资讯列表 →