在运行kubeadm init 和 join 命令部署好master和node节点后,kubectl get nodes 看到节点都是NotReady状态,这是因为没有安装CNI网络插件。
kubectl get nodes
NAME                    STATUS     ROLES           AGE     VERSION   
k8s-master   NotReady    control-plane   5d22h   v1.28.2
k8s-node1    NotReady    <none>          5d22h   v1.28.2 
1. 安装
通过命令kubectl apply -f 安装:
1) 直接通过官方yaml文件安装,国内一般都下载不了,需要翻墙
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml"
 
2) 先下载下来calico.yaml,然后执行kubectl apply -f calico.yaml, 本文采用的这种方式
两种下载方式,有时网络不好下载也会失败:curl -O https://raw.githubusercontent.com/projectcalico/calico/v3.26.4/manifests/calico.yaml
wget https://github.com/projectcalico/calico/blob/v3.26.4/manifests/calico.yaml 
2. 下载镜像到本地
因为calico.yaml中的image 默认使用的是官方源,国内下载不下来,需要先把镜像拉取到本地,从本地镜像启动pod。
下载地址:calico国内镜像下载地址
本文这里把cni, node,kube-controllers 写成了脚本 calico_image_pull.sh, 具体下载版本可以根据需要自行修改。
#!/bin/bashctr -n k8s.io images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/cni:v3.26.4-linuxarm64
ctr -n k8s.io images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/cni:v3.26.4-linuxarm64  docker.io/calico/cni:v3.26.4ctr -n k8s.io images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/node:v3.26.4-linuxarm64
ctr -n k8s.io images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/node:v3.26.4-linuxarm64  docker.io/calico/node:v3.26.4ctr -n k8s.io images pull swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/kube-controllers:v3.26.4-linuxarm64
ctr -n k8s.io images tag  swr.cn-north-4.myhuaweicloud.com/ddn-k8s/docker.io/calico/kube-controllers:v3.26.4-linuxarm64  docker.io/calico/kube-controllers:v3.26.4
 
3. 修改calico.yaml
由于上面 给镜像tag 就是打的docker.io/calico/xxx, 所以保证后面的版本号一直即可。
[root@k8s-master kylin]# cat calico.yaml | grep v3.26.4image: docker.io/calico/cni:v3.26.4image: docker.io/calico/cni:v3.26.4image: docker.io/calico/node:v3.26.4image: docker.io/calico/node:v3.26.4image: docker.io/calico/kube-controllers:v3.26.4
 
应用修改后的 YAML 文件:
kubectl apply -f calico.yaml
 
4. 检查
执行 kubectl get pods -n kube-system
NAME                                       READY   STATUS    RESTARTS      AGE
calico-kube-controllers-646957dd46-ktmkl   1/1     Running   0             36m
calico-node-jxznc                          1/1     Running   0             36m
calico-node-ztbsk                          1/1     Running   0             36m
coredns-5c55fb4899-h4v4z                   1/1     Running   0             5d22h
coredns-5c55fb4899-hpfr8                   1/1     Running   0             5d22h
etcd-k8s-master                            1/1     Running   2 (56m ago)   5d22h
kube-apiserver-k8s-master                  1/1     Running   2 (56m ago)   5d22h
kube-controller-manager-k8s-master         1/1     Running   2 (56m ago)   5d22h
kube-proxy-kx9nv                           1/1     Running   0             5d22h
kube-proxy-s5rcq                           1/1     Running   1 (56m ago)   5d22h
kube-scheduler-k8s-master                  1/1     Running   2 (56m ago)   5d22
 
执行 kubectl get nodes
NAME         STATUS   ROLES           AGE     VERSION
k8s-master   Ready    control-plane   5d23h   v1.28.2
k8s-node1    Ready    <none>          5d23h   v1.28.2
 
至此部署成功。
5. 踩坑
- 每个节点都需要拉取
calico镜像到本地,不然执行kubectl get pods -n kube-system存在ImagePullBackOff状态的pod 
Init:ImagePullBackOff 
 
- 使用 
ctr images pull拉取镜像到本地,创建calico-node pod失败 
查看pod日志, kubectl describe pod -n kube-system calico-node-xxxx 报拉取镜像失败。
Failed to pull image "docker.io/calico/cni:v3.26.4": rpc error: code = DeadlineExceeded desc = failed to pull and unpack image "docker.io/calico/cni:v3.26.4": failed to resolve reference "docker.io/calico/cni:v3.26.4": failed to do request: Head "https://registry-1.docker.io/v2/calico/cni/manifests/v3.26.4"
 
这个是因为kubectl 命令默认的命令空间是k8s.io, 而ctr images pull 默认的空间是default, 所以使用crictl images 看不到拉取的镜像,从而kubectl apply -f calico.yaml 在命令空间k8s.io中找不到相应镜像就到远程去拉,而远程又连不上,所以失败。
所以上面的脚本中指定了命令空间 ctr -n k8s.io xxxxx, 或者直接使用crictl images pull xxxx。
另外 , ctr是Containerd自带的命令行工具,而crictl是Kubernetes社区提供的工具,主要用于调试和管理容器运行时接口(CRI)相关的容器和镜像。
ctr 默认操作的是 Containerd 的 default 命名空间
 crictl 操作的是 Kubernetes CRI 专用的 k8s.io 命名空间
6 排错使用到的命令
kubectl logs -n kube-system calico-node-xxxxx -c calico-node //如果 Pod 处于 CrashLoopBackOff,查看 pod 日志
kubectl describe pod -n kube-system calico-node-xxxx     // 查看 Pod 详细信息kubectl delete pod -n kube-system calico-node-xxxxx  // 强制重建 Podkubectl get pods -n kube-system -l k8s-app=calico-node //查看组件状态
 
7 移除当前节点并添加节点
将node节点移除后,服务器重置,然后根据上篇node节点部署与安装重新,将这个节点重新添加到集群中,出现了问题:
 calico-node 状态是 Running,但是READY 是0
kubectl get pods -n kube-systemNAME                                       READY   STATUS    RESTARTS      AGE
calico-kube-controllers-646957dd46-qdlfd   1/1     Running   0             9h
calico-node-kk6bw                          0/1     Running   0             9h
calico-node-qmn2c                          0/1     Running   0             9h
coredns-5c55fb4899-h4v4z                   1/1     Running   0             6d13h
coredns-5c55fb4899-hpfr8                   1/1     Running   0             6d13h
etcd-k8s-master                            1/1     Running   2 (15h ago)   6d13h
kube-apiserver-k8s-master                  1/1     Running   2 (15h ago)   6d13h
kube-controller-manager-k8s-master         1/1     Running   2 (15h ago)   6d13h
kube-proxy-5ffzx                           1/1     Running   0             10h
kube-proxy-s5rcq                           1/1     Running   1 (15h ago)   6d13h
kube-scheduler-k8s-master                  1/1     Running   2 (15h ago)   6d13h
 
执行kubectl describe pod -n kube-system calico-node-qmn2c
发现有:
Warning  Unhealthy  6s  kubelet  Readiness probe failed: 2025-04-09 15:03:09.435 [INFO][401] confd/health.go 180: Number of node(s) with BGP peering established = 0
calico/node is not ready: BIRD is not ready: BGP not established with 10.42.74.176
 
排错:
- 检查BGP端口(179)的连通性,确保节点之间可以通过 BGP 端口(TCP 179) 通信
 
telnet ip 179
 
- 安装 calicoctl(需与 Calico 版本匹配)
 
curl -L https://github.com/projectcalico/calico/releases/download/v3.26.4/calicoctl-linux-arm64 -o calicoctl
chmod +x calicoctl
sudo mv calicoctl /usr/local/bin/
 
查看 BGP 对等体状态
calicoctl node status
 
正常输出应显示 Established 状态:
IPv4 BGP status
+---------------+-----------+-------+----------+-------------+
| PEER ADDRESS  | PEER TYPE | STATE |  SINCE   |    INFO     |
+---------------+-----------+-------+----------+-------------+
| 10.42.74.176    | node-to-node | up    | 09:00:00 | Established |
+---------------+-----------+-------+----------+-------------+
 
如果状态为 Idle 或 Active,表示 BGP 会话未建立。
3. 检查 Calico 配置
 确认 Calico 的 BGP 配置是否正确:
查看默认的 BGP 配置
calicoctl get bgpconfigurations default -o yaml
 
查看节点级别的 BGP 对等体配置
calicoctl get node <node-name> -o yaml
 
关键配置项:
spec.bgp.asNumber: 集群的 AS 号(默认 64512)。spec.bgp.peers: 显式指定的 BGP 对等体(如果使用全互联模式可能无需配置)。
 
4. 验证节点 IP 地址
 确保 Calico 使用的节点 IP 地址正确(尤其是多网卡环境):
查看节点的实际 IP 地址(通常是主网卡 IP)
ip addr show查看 Calico 节点资源中记录的 IP
calicoctl get node <node-name> -o yaml | grep 'address:'
 
如果节点 IP 不匹配,需要修正:
修改 Calico 节点的 IP 地址
calicoctl patch node <node-name> --patch '{"spec":{"bgp":{"ipv4Address":"<correct-ip>/24"}}}'
 
5. 检查路由表
 在问题节点和目标节点(10.42.74.176)上检查路由表,确认 BGP 路由是否注入:
ip route show | grep bird
正常应看到对方节点网段的路由条目:
10.244.1.0/24 via 10.42.74.176 dev eth0 proto bird
 
最后都不是:重启node节点解决