一、为什么要配置 insecure registry

当你在学习环境或内网环境中使用不带正式证书的 Harbor 或其他 HTTP 仓库时,Containerd 默认不会直接信任它。

这时就需要在 Containerd 配置中显式告诉运行时:

  • 某个仓库地址允许通过 HTTP 访问
  • 相关镜像拉取请求可以跳过 HTTPS 校验逻辑

否则即使镜像仓库本身可访问,Containerd 也可能无法正常拉取镜像。

二、配置 insecure registry 时最重要的注意点

原始笔记里强调了几个非常关键的点:

  • Kubernetes 集群中的所有节点都要完成配置
  • config.toml 不是直接给 ctr 命令使用的配置入口
  • Docker 拉取的镜像和 Containerd 本身没有直接关系

这三点非常重要,尤其第三点最容易误导初学者:Docker 能拉到镜像,不代表 Containerd 也一定能拉到同一份镜像。

三、如何在 Containerd 中配置 insecure registry

示例里是在每个 Kubernetes 节点的 /etc/containerd/config.toml 中增加镜像仓库镜像配置:

[plugins."io.containerd.grpc.v1.cri".registry.mirrors."10.0.0.13"]
  endpoint = ["http://10.0.0.13/"]

配置完成后,重启 Containerd:

systemctl restart containerd

原始笔记是在 master 和两个 node 节点上都进行了同样处理,这一点很符合实际生产思路:镜像拉取能力必须在所有可能调度 Pod 的节点上保持一致。

四、如何验证仓库配置是否生效

配置完成后,可以先在任意节点上直接拉取镜像测试:

ctr i pull 10.0.0.13/public-service/nginx:1.21.6 --plain-http

这里的 --plain-http 代表显式使用 HTTP,而不是 HTTPS。

然后检查镜像列表:

ctr i ls

如果能看到目标镜像,说明基本的仓库访问链路已经打通。

五、私有仓库拉取时还要注意什么

如果 Harbor 或目标仓库本身是私有的,那么除了仓库地址配置正确之外,还需要在拉取镜像时补充认证信息,例如:

ctr i pull 10.0.0.13/public-service/nginx:1.21.6 --plain-http --user admin

更稳妥的做法通常是使用:

User[:password]

但发布给团队或公开材料时,实际密码最好不要写死在命令里,应该通过安全方式注入或现场输入。

六、为什么 Kubernetes 特别关心 k8s.io 命名空间

Containerd 的命名空间和 Kubernetes 的命名空间不是一回事。

这里的 Containerd Namespace 更像运行时内部的资源隔离视图。默认情况下:

  • Containerd 默认命名空间是 default
  • Kubernetes 相关镜像和容器通常都在 k8s.io

这也是为什么在 Kubernetes 节点上处理镜像时,很多操作都需要显式带上:

-n k8s.io

七、如何把镜像拉到 k8s.io 命名空间

如果你希望镜像直接被 Kubernetes 使用,可以这样拉取:

ctr -n k8s.io i pull 10.0.0.13/public-service/nginx:1.21.6 --plain-http

验证:

ctr -n k8s.io i ls | grep nginx

这一步的意义在于让镜像直接进入 Kubernetes 相关的运行时命名空间,从而减少后续调度与引用时的歧义。

八、如何验证 Kubernetes 是否真的能引用这份镜像

最直接的测试方式,就是创建一个 Deployment:

kubectl create deploy test02 --image=10.0.0.13/public-service/nginx:1.21.6

然后检查 Pod 状态:

kubectl get po | grep test02

如果 Pod 成功进入 Running,就说明下面几件事都同时成立:

  • Containerd 仓库配置正确
  • 节点已能访问镜像仓库
  • 镜像已在运行时可用
  • Kubernetes 能顺利引用这份镜像

九、为什么有时镜像已经在本地,Pod 还是拉取失败

原始笔记里提到一个很实用的判断:如果前面的操作都完成了,但 Pod 依然显示 ErrImagePullImagePullBackOff,很多时候不是仓库不可用,而是镜像拉取策略导致的。

典型情况是:

  • Pod 默认或显式使用了 Always
  • 即使节点已有镜像,Kubernetes 仍尝试重新拉取

此时通常可以把镜像拉取策略改为:

IfNotPresent

这样会更符合本地已有镜像的使用预期。

十、Containerd 命名空间到底该怎么理解

Containerd Namespace 是一套运行时资源隔离机制,用于区分不同容器、镜像和任务的逻辑归属。

它和 Kubernetes Namespace 的区别必须明确:

  • Kubernetes Namespace 面向集群资源管理
  • Containerd Namespace 面向运行时内部资源隔离

因此两者虽然名字相同,但属于不同层面的概念。

原始笔记中给出的常见命令非常实用:

ctr ns c test
ctr ns ls
ctr ns label test a=b
ctr ns rm test

这说明 Namespace 除了隔离用途,还能配合标签做更细粒度的管理。

十一、把这篇内容真正用在运维里

如果把 Day006 这部分内容浓缩成最实用的经验,其实就是下面几条:

  • 内网或 HTTP 仓库要提前配好 insecure registry
  • 所有 Kubernetes 节点都要统一处理运行时配置
  • defaultk8s.io 命名空间不能混着理解
  • 想给 Kubernetes 直接用的镜像,优先检查 k8s.io 命名空间
  • Pod 拉取失败时,不要只盯仓库,要一起看镜像拉取策略

这部分能力看似基础,但它恰恰是 Containerd 运维和 Kubernetes 节点排障里最常见、最实用的能力之一。