)
K8s 1.28 从 Docker 切换到 Containerd 后如何正确配置 Harbor 私有仓库附完整 ctr 命令清单当 Kubernetes 1.24 版本宣布弃用 Docker 作为默认容器运行时的那一刻起整个容器生态就迎来了重大变革。对于长期依赖 Docker 工具链的运维团队来说转向 Containerd 不仅意味着工作习惯的改变更涉及到一系列底层配置的调整。特别是在私有镜像仓库 Harbor 的使用上许多团队都遇到了ErrImagePull这类看似简单却令人头疼的问题。本文将带你深入理解 Containerd 的架构设计手把手解决 Harbor 集成难题。不同于 Docker 时代的一键配置Containerd 需要更精确的配置和更底层的操作命令。我们会从实际案例出发提供可直接复用的配置模板和命令清单帮助你顺利完成这次关键的技术迁移。1. 理解 Containerd 与 Docker 的核心差异在 Docker 主导容器生态的这些年里大多数开发者已经习惯了docker pull、docker push这样的简洁命令。但很少有人意识到这些便利的 CLI 命令背后Docker 实际上是在调用 Containerd 的功能。当 K8s 决定直接使用 Containerd 时相当于去掉了 Docker 这个中间商这带来了性能提升但也失去了 Docker 提供的许多便利功能。架构对比特性DockerContainerd镜像管理内置完整镜像处理逻辑仅基础镜像操作CLI 工具功能丰富的 docker 命令基础的 ctr/nerdctl 命令私有仓库认证自动处理 ~/.docker/config.json需手动配置 config.toml默认命名空间单一镜像存储多命名空间隔离HTTP 仓库支持自动处理需显式启用 plain-http最关键的差异在于命名空间概念。Containerd 默认使用default命名空间存储镜像而 Kubernetes 则使用专门的k8s.io命名空间。这就是为什么你用ctr image ls能看到镜像但 K8s 却报ErrImagePull的根本原因。2. Containerd 配置深度解析要让 Containerd 正确对接 Harbor 私有仓库关键在于/etc/containerd/config.toml文件的配置。这个文件定义了 Containerd 的所有运行时行为包括镜像拉取策略、存储驱动、命名空间管理等核心功能。2.1 基础配置生成与优化首先获取默认配置模板sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml关键配置项修改建议国内镜像加速[plugins.io.containerd.grpc.v1.cri.registry.mirrors] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io] endpoint [https://registry-1.docker.io] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.gcr.io] endpoint [https://mirror.gcr.io]Systemd 集成[plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options] SystemdCgroup true2.2 Harbor 私有仓库专项配置对于 HTTP 协议的 Harbor 仓库生产环境强烈建议使用 HTTPS需要特别配置[plugins.io.containerd.grpc.v1.cri.registry.configs] [plugins.io.containerd.grpc.v1.cri.registry.configs.harbor.example.com.tls] insecure_skip_verify true [plugins.io.containerd.grpc.v1.cri.registry.configs.harbor.example.com.auth] username admin password Harbor12345 [plugins.io.containerd.grpc.v1.cri.registry.configs.192.168.2.142:8800.tls] insecure_skip_verify true [plugins.io.containerd.grpc.v1.cri.registry.configs.192.168.2.142:8800.auth] username admin password Harbor12345注意配置修改后需要重启服务生效sudo systemctl daemon-reload sudo systemctl restart containerd3. 实战操作镜像全生命周期管理Containerd 提供了ctr和nerdctl两个命令行工具。ctr是官方提供的底层工具功能基础但稳定nerdctl则兼容了 Docker CLI 的使用习惯更适合从 Docker 迁移的用户。3.1 镜像拉取与查看从 Docker Hub 拉取镜像ctr image pull docker.io/library/nginx:alpine从 Harbor 拉取镜像HTTP 协议ctr image pull --plain-http harbor.example.com/project/nginx:v1查看镜像# 查看默认命名空间 ctr image ls # 查看 Kubernetes 使用的命名空间 ctr -n k8s.io image ls3.2 镜像标记与推送为镜像打标签ctr -n k8s.io image tag docker.io/library/nginx:alpine harbor.example.com/project/nginx:v1推送镜像到 Harborctr -n k8s.io image push --plain-http harbor.example.com/project/nginx:v13.3 镜像导入导出导出镜像ctr -n k8s.io image export nginx.tar harbor.example.com/project/nginx:v1导入镜像ctr -n k8s.io image import nginx.tar4. Kubernetes 集成实战在 K8s 1.28 中工作负载无法拉取镜像通常由三个原因导致Containerd 未正确配置 Harbor 访问镜像存在于错误命名空间工作负载缺少必要的 imagePullSecrets解决方案创建镜像拉取密钥kubectl create secret docker-registry harbor-creds \ --docker-serverharbor.example.com \ --docker-usernameadmin \ --docker-passwordHarbor12345 \ --namespacedefault在 Deployment 中引用密钥apiVersion: apps/v1 kind: Deployment metadata: name: nginx spec: template: spec: containers: - name: nginx image: harbor.example.com/project/nginx:v1 imagePullSecrets: - name: harbor-creds紧急情况下的节点级镜像预加载# 在所有节点执行 ctr -n k8s.io image pull --plain-http harbor.example.com/project/nginx:v15. 高级技巧与故障排查跨命名空间镜像复制# 将镜像从 default 复制到 k8s.io 命名空间 ctr image export - | ctr -n k8s.io image import -常见错误及解决方案错误failed to resolve reference harbor.example.com/project/nginx:v1原因Containerd 无法验证 HTTPS 证书解决添加--plain-http参数或正确配置 TLS错误image exists in default namespace but not k8s.io解决显式指定-n k8s.io或在 Kubernetes 配置中设置imagePullPolicy: Never性能优化建议为 Containerd 配置合适的存储驱动如 overlayfs定期执行镜像垃圾回收ctr images prune考虑使用nerdctl作为日常管理工具它支持更丰富的功能如nerdctl compose up -d nerdctl build -t myapp .从 Docker 到 Containerd 的转变表面上看只是工具链的更换实质上却代表着容器技术向着更专业、更模块化的方向发展。虽然初期会面临一些适应成本但一旦掌握了 Containerd 的工作机制你会发现它比 Docker 更加灵活和高效。特别是在大规模生产环境中Containerd 的稳定性和性能优势会更加明显。