在運行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節點解決