
K8s 1.28 安装 Flannel 卡在 ImagePullBackOff别慌手把手教你用 ctr 命令手动拉取镜像搞定当你满怀期待地在 Kubernetes 1.28 集群上部署 Flannel 网络插件时突然发现 Pod 状态卡在ImagePullBackOff那种感觉就像开车时突然遇到路障。别担心这不是世界末日而是一个可以通过 containerd 的ctr命令轻松解决的常见问题。1. 理解问题根源为什么会出现 ImagePullBackOff在开始解决问题之前我们需要先理解这个错误的本质。ImagePullBackOff是 Kubernetes 报告的一种 Pod 状态表示 kubelet 无法从指定的镜像仓库拉取容器镜像。这通常由以下几种情况导致网络连接问题无法访问 Docker Hub 或其他镜像仓库认证问题需要认证的私有仓库但未配置正确的凭据镜像不存在指定的镜像标签或版本不存在资源限制节点磁盘空间不足或内存限制在 Flannel 安装场景中最常见的原因是网络连接问题特别是当你的集群位于内网环境或对国外镜像仓库如 docker.io的访问受限时。# 查看 Pod 详细状态 kubectl describe pod -n kube-system kube-flannel-ds-xxxxx在输出中你可能会看到类似这样的错误信息Failed to pull image docker.io/flannel/flannel:v0.22.3: rpc error: code Unknown desc failed to pull and unpack image docker.io/flannel/flannel:v0.22.3: failed to resolve reference docker.io/flannel/flannel:v0.22.3: failed to do request: Head https://registry-1.docker.io/v2/flannel/flannel/manifests/v0.22.3: dial tcp: lookup registry-1.docker.io on 10.96.0.10:53: read udp 10.244.0.3:43214-10.96.0.10:53: i/o timeout2. 为什么选择 ctr 命令而非传统解决方案面对镜像拉取问题常见的解决方案包括配置镜像加速器或代理修改 Docker/containerd 配置使用国内镜像源手动下载镜像并导入然而这些方法各有局限方法优点缺点镜像加速器长期有效需要修改集群配置可能影响其他服务国内镜像源下载速度快镜像可能不完整或版本滞后手动导入直接解决问题传统方法操作复杂ctr命令是 containerd 自带的客户端工具相比传统方法有独特优势无需修改集群配置直接在节点上操作不影响其他服务精确控制镜像命名空间通过-n k8s.io参数确保镜像能被 kubelet 识别即时生效拉取后 Kubernetes 能立即使用无需额外步骤3. 实战使用 ctr 命令手动拉取 Flannel 镜像3.1 准备工作首先确认你的环境Kubernetes 1.28 集群使用 containerd 作为容器运行时默认配置拥有节点上的 sudo 权限# 检查容器运行时 kubectl get node -o wide3.2 确定需要的镜像版本查看 Flannel 的部署清单文件找到需要的镜像# 下载最新版 Flannel 部署文件 curl -LO https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml # 查看需要的镜像 grep image kube-flannel.yml通常会输出两个镜像image: docker.io/flannel/flannel-cni-plugin:v1.2.0 image: docker.io/flannel/flannel:v0.22.33.3 使用 ctr 命令拉取镜像关键步骤来了使用ctr命令拉取镜像特别注意-n k8s.io参数# 拉取 flannel-cni-plugin 镜像 sudo ctr -n k8s.io images pull docker.io/flannel/flannel-cni-plugin:v1.2.0 # 拉取 flannel 主镜像 sudo ctr -n k8s.io images pull docker.io/flannel/flannel:v0.22.3注意-n k8s.io参数至关重要它指定了镜像的命名空间确保 kubelet 能够识别这些镜像。如果省略这个参数镜像会被拉到默认命名空间Kubernetes 将无法使用。3.4 验证镜像拉取成功检查镜像是否已正确拉取sudo ctr -n k8s.io images list | grep flannel应该能看到类似输出docker.io/flannel/flannel-cni-plugin:v1.2.0 docker.io/flannel/flannel:v0.22.34. 高级技巧与疑难解答4.1 使用镜像加速器如果直接拉取仍然太慢可以尝试使用镜像加速器# 使用阿里云镜像加速 sudo ctr -n k8s.io images pull registry.aliyuncs.com/google_containers/flannel:v0.22.3然后重新打标签sudo ctr -n k8s.io images tag registry.aliyuncs.com/google_containers/flannel:v0.22.3 docker.io/flannel/flannel:v0.22.34.2 多架构镜像支持如果你的集群混合了不同架构的节点如 amd64 和 arm64需要拉取多架构镜像sudo ctr -n k8s.io images pull --platform linux/amd64,linux/arm64 docker.io/flannel/flannel:v0.22.34.3 常见错误处理错误1权限不足ctr: permission denied解决方案确保使用 sudo 执行命令错误2镜像拉取后 Pod 仍无法启动可能原因镜像被拉取到了错误的命名空间解决方案确认使用了-n k8s.io参数并检查镜像列表sudo ctr -n k8s.io images list | grep flannel5. 为什么这个方法有效深入理解 containerd 和 kubelet 的交互理解背后的原理能帮助你在类似场景中举一反三。Kubernetes 通过 kubelet 管理节点上的容器而 kubelet 通过 CRIContainer Runtime Interface与容器运行时如 containerd通信。当使用ctr -n k8s.io命令时我们直接将镜像放入了 kubelet 管理的命名空间因此kubelet 能立即发现这些镜像不需要额外的镜像缓存同步过程避免了权限和命名空间隔离导致的问题相比之下使用docker pull或ctr不加-n k8s.io时镜像会被放在默认命名空间kubelet 无法直接访问需要额外的导入导出操作。6. 其他替代方案对比虽然ctr命令是最直接的解决方案但了解其他方法也有价值方法一配置 containerd 镜像加速器编辑/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, https://mirror.gcr.io]然后重启 containerdsudo systemctl restart containerd方法二使用国内镜像源修改 Flannel 的部署文件将docker.io/flannel/flannel:v0.22.3替换为国内镜像源地址。方法三手动导入导出镜像在有网络的环境中拉取镜像导出为 tar 文件再导入到目标集群# 在有网络的机器上 docker pull flannel/flannel:v0.22.3 docker save flannel/flannel:v0.22.3 flannel.tar # 在目标集群上 sudo ctr -n k8s.io images import flannel.tar7. 预防措施与最佳实践为了避免未来遇到类似问题可以考虑以下预防措施预先拉取镜像在集群初始化前拉取所有需要的镜像搭建本地镜像仓库在内网部署 Harbor 或其他 registry使用镜像缓存配置 containerd 的镜像缓存策略监控镜像拉取状态设置告警及时发现镜像拉取失败对于生产环境我通常会预先在部署脚本中加入镜像拉取步骤# 预拉取关键镜像 PRELOAD_IMAGES( flannel/flannel:v0.22.3 flannel/flannel-cni-plugin:v1.2.0 k8s.gcr.io/pause:3.6 ) for image in ${PRELOAD_IMAGES[]}; do sudo ctr -n k8s.io images pull docker.io/${image} || \ sudo ctr -n k8s.io images pull registry.aliyuncs.com/google_containers/${image##*/} done在实际工作中遇到ImagePullBackOff这类问题时最重要的是保持冷静逐步排查。ctr命令虽然强大但只是众多工具中的一种。理解容器运行时的工作原理才能在各种网络环境下游刃有余地部署 Kubernetes 集群。