containerd配置国内镜像加速
因为新版本 k8s 底层容器运行时换成了 containerd,所以记录一下镜像加速配置方法顺便学习下这个看着让人一脸问号的 containerd
相较于传统 Docker 镜像加速配置方法,containerd 的配置实在是略显麻烦啊…
1. containerd 简介
1.1 Kubernetes CRI 与 containerd
在早期的 K8s 版本中,kubelet
组件直接与 Docker Daemon 交互来管理容器。但社区考虑扩展性为了使 K8s 能够支更多样的容器运行时(如 rkt, Kata Containers),社区推出了容器运行时接口(Container Runtime Interface, 即CRI)。CRI 是一套标准的、基于 gRPC 的 API 规范,它解耦了 kubelet
与具体容器运行时之间的强依赖关系。
containerd
正是 CRI 规范的一种标准实现工具。经过近两年发展 kubelet
已经不再与 Docker Daemon 对话,而是通过 CRI 接口,向 containerd
发出指令,如“拉取这个镜像”、“创建 Pod 沙箱”、“启动容器”等。
工作流程如下:

从图中可见,当 K8s 需要部署一个 Pod 时:
kubelet
接收到指令,分析 Pod 定义中所需的容器镜像kubelet
通过 CRI 的PullImage
RPC 调用,请求containerd
确保该镜像存在于本地containerd
检查本地镜像存储。如果镜像不存在,它将负责根据自身的配置从远程镜像仓库拉取镜像
这里的关键点在于,执行镜像拉取操作的直接负责人是 containerd
,因此,加速配置必须在 containerd
层面进行,才能对 K8s 集群生效。
1.2 需要加速的镜像
registry.k8s.io
: K8s 官方镜像仓库,存放着 k8s 核心组件的容器镜像docker.io
: 全球最大的公共镜像中心,平时使用到的大部分容器镜像都存在里面gcr.io
: Google 镜像仓库,存放 Google 相关的一些容器镜像quay.io
: RedHat 运营的镜像仓库,也有许多核心开源项目的镜像存在里面ghcr.io
: GitHub 运营的镜像仓库,有很多开源项目的镜像也会选择存放在里面
在国内节点部署、使用 k8s 的时候,前面两个镜像必须要配置加速,否则必然是会镜像拉取失败的,剩下几个按需配置即可。
2. 配置解析
认识一下这个看着比 Docker 麻烦很多的配置文件。
2.1 config.toml
的结构
containerd
的主配置文件位于 /etc/containerd/config.toml
,采用 TOML
格式。TOML 格式具有清晰的层级结构和良好的可读性,现在在云原生项目中出现的频率确实是明显多了很多!
containerd
配置文件的整体架构是 “插件化” 形式, 文件里面也是众多插件的配置条目。CRI 服务本身也是其众多插件中的一个,其官方名称为 io.containerd.grpc.v1.cri
。因此所有与 CRI 相关的配置,都必须放置在这个插件的命名空间下。
具体来看下这个配置项:
[plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
[plugins."..."]
:表示这是一个插件配置区块"io.containerd.grpc.v1.cri"
:指定了配置的目标是 CRI 插件。.registry
:表示我们正在配置该插件的registry
(镜像仓库)相关功能.mirrors
:进一步指定是配置镜像的mirrors
(这里即是我们的镜像加速器)."docker.io"
:明确了此配置块只针对docker.io
这个上游仓库生效
官方背书: 每个配置项都拥有唯一的、不会产生冲突的路径、具有清晰的配置导向,也为未来新增更多功能插件而不会破坏现有结构提供了保障
在我看来: 真是挺麻烦的!
2.2 进一步分析
关键配置区块:
1 | [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"] |
简单搂一眼这个部分源码,该配置对应的源码定义在 containerd/pkg/cri/apis/config/config.go
中:
1 | // Registry is registry settings "plugins.cri.registry" |
从源码中我们可以得到几个关键信息:
Mirrors
是一个map[string]Mirror
类型:key
(即"docker.io"
)是原始仓库地址,value
是Mirror
结构体。从这里可以看出我们可以为不同仓库配置不同加速镜像源Endpoint
是一个[]string
类型(字符串切片): 这表明containerd
原生即支持配置多个endpoint
- 源码注释明确指出 “The endpoint will be tried in order.”:
containerd
会按照数组中定义的顺序,依次尝试连接endpoint
来拉取镜像。一旦其中一个成功,它就会停止尝试并开始下载。
3. 快速配置
上面都是顺带简单了解下 containerd 的内容,现在回到镜像加速源具体配置方法
3.1 生成默认配置
1 | mkdir -p /etc/containerd |
3.2 配置方法
编辑 /etc/containerd/config.toml
文件,找到 [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
部分,替换补充以下内容。这是一个涵盖了绝大部分场景的推荐配置:
1 | # /etc/containerd/config.toml |
额外说明:
sandbox_image
: 这是 Pod 沙箱的镜像。kubeadm
等工具在初始化时会检查并拉取它。强烈建议将其也指向国内的镜像地址,否则集群初始化可能会在第一步就失败…- 镜像源选择: 上述配置的镜像仅为个人设置且当前时间点(2024-11-06)可用的,有些镜像是爱发电的,不保证哪天会突然暴毙!如已有失效的自行更改就好
3.3 验证
修改配置后,必须重启 containerd
才能使其加载新配置
1 | systemctl daemon-reload |
这里注意下验证配置是否生效,不能使用 docker pull
,而应该使用 crictl
工具。crictl
是一个专门用于与 CRI 兼容的容器运行时进行交互的命令行工具
1 | # 拉取一个docker.io的镜像进行测试 |
如果命令能够快速成功返回,并且没有出现网络超时错误,说明配置已正确生效