最近在搭建一个小型 Kubernetes 集群,拓扑是 1 个管理节点 + 2 个工作节点,打算用 Calico 做 CNI 网络插件。过程中遇到了不少坑,现在整理下来,给大家参考。


一、遇到的问题

第一次尝试部署 Calico 的时候,Pod 根本跑不起来。kubectl describe pod 看日志发现两类报错:

  1. 镜像拉取失败

    Failed to pull image "docker.io/calico/kube-controllers:v3.27.3": connect: connection refused

    • 当时以为是 Docker Hub 网络问题,可 curl 测试发现节点能访问 registry-1.docker.io,但 containerd 就拉不下来。
    • 后面才发现节点没有 Docker CLI,而且 containerd 的网络和外网访问有点问题。
  2. CNI 权限问题

    plugin type="calico" failed (add): connection is unauthorized: Unauthorized

    • 也就是 Calico 没法访问 Kubernetes API,ServiceAccount 或 RBAC 配置不对。

总之,Pod 一直 ImagePullBackOff,根本启动不起来。


二、解决方案

1️⃣ 使用 containerd 拉镜像

我发现节点没有 Docker CLI,只能用 containerd 的命令:

ctr -n k8s.io images pull docker.io/calico/kube-controllers:v3.27.3
ctr -n k8s.io images pull docker.io/calico/node:v3.27.3
# 给镜像打标签
ctr -n k8s.io images tag docker.io/calico/kube-controllers:v3.27.3 docker.io/calico/kube-controllers:v3.27.3
ctr -n k8s.io images tag docker.io/calico/node:v3.27.3 docker.io/calico/node:v3.27.3

注意:每个节点都要执行一次,因为 containerd 的镜像存储是本地的,节点 A 拉了镜像,节点 B 不会共享。


2️⃣ 重新启动 Calico Pod

镜像拉好之后,我把原来的 Pod 删除,让 Kubernetes 自动用本地镜像重建:

kubectl delete pod -n kube-system -l k8s-app=calico-kube-controllers
kubectl delete pod -n kube-system -l k8s-app=calico-node

然后看 Pod 状态慢慢变成 Running,不再报 ImagePullBackOff


3️⃣ 验证网络是否可用

我在一个节点上创建测试 Pod,然后 ping 另一个节点的 Pod IP:

kubectl run test-pod --image=busybox --restart=Never -- sleep 3600
kubectl exec -it test-pod -- ping <另一个节点上的 Pod IP>

可以正常 ping 通,说明 Calico 已经给 Pod 分配网络,跨节点通信正常。


三、总结经验

  1. 内网集群一定要提前拉好镜像
    • Docker Hub / 阿里云镜像仓库有时会认证或网络限制,用 containerd ctr images pull 预拉镜像最稳妥。
  2. 每个节点都要拉
    • Pod 会在任意节点调度,本地没镜像会报 ImagePullBackOff
  3. CNI 权限要正确
    • ServiceAccount 和 ClusterRoleBinding 要保证 Calico 有权限访问 Kubernetes API。
  4. 验证网络
    • 删除 Pod 重建后,一定要用测试 Pod ping 跨节点 Pod IP,确认网络通。

💡 总结一句话:

内网 Kubernetes 集群部署 Calico,先拉镜像、再检查权限、最后重建 Pod,这样小集群也能跑得稳稳的。


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐