在运行kubeadm init
和 join
命令部署好master
和node
节点后,kubectl get nodes
看到节点都是NotReady
状态,这是因为没有安装CNI
网络插件。
c
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文件安装,国内一般都下载不了,需要翻墙
c
kubectl apply -f "https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/calico.yaml"
2) 先下载下来calico.yaml
,然后执行kubectl apply -f calico.yaml
, 本文采用的这种方式
cpp
两种下载方式,有时网络不好下载也会失败:
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
, 具体下载版本可以根据需要自行修改。
cpp
#!/bin/bash
ctr -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.4
ctr -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.4
ctr -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
, 所以保证后面的版本号一直即可。
cpp
[root@k8s-master kylin]# cat calico.yaml | grep v3.26.4
image: docker.io/calico/cni:v3.26.4
image: docker.io/calico/cni:v3.26.4
image: docker.io/calico/node:v3.26.4
image: docker.io/calico/node:v3.26.4
image: docker.io/calico/kube-controllers:v3.26.4
应用修改后的 YAML
文件:
c
kubectl apply -f calico.yaml
4. 检查
执行 kubectl get pods -n kube-system
cpp
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
cpp
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
cpp
Init:ImagePullBackOff
- 使用
ctr images pull
拉取镜像到本地,创建calico-node pod
失败
查看pod
日志, kubectl describe pod -n kube-system calico-node-xxxx
报拉取镜像失败。
cpp
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 排错使用到的命令
cpp
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 // 强制重建 Pod
kubectl get pods -n kube-system -l k8s-app=calico-node //查看组件状态
7 移除当前节点并添加节点
将node
节点移除后,服务器重置,然后根据上篇node
节点部署与安装重新,将这个节点重新添加到集群中,出现了问题:
calico-node
状态是 Running
,但是READY
是0
cpp
kubectl get pods -n kube-system
NAME 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
发现有:
cpp
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) 通信
cpp
telnet ip 179
- 安装 calicoctl(需与 Calico 版本匹配)
cpp
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 对等体状态
cpp
calicoctl node status
正常输出应显示 Established
状态:
cpp
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 配置
cpp
calicoctl get bgpconfigurations default -o yaml
查看节点级别的 BGP 对等体配置
cpp
calicoctl get node <node-name> -o yaml
关键配置项:
cpp
spec.bgp.asNumber: 集群的 AS 号(默认 64512)。
spec.bgp.peers: 显式指定的 BGP 对等体(如果使用全互联模式可能无需配置)。
4. 验证节点 IP 地址
确保 Calico 使用的节点 IP 地址正确(尤其是多网卡环境):
cpp
查看节点的实际 IP 地址(通常是主网卡 IP)
ip addr show
查看 Calico 节点资源中记录的 IP
calicoctl get node <node-name> -o yaml | grep 'address:'
如果节点 IP 不匹配,需要修正:
cpp
修改 Calico 节点的 IP 地址
calicoctl patch node <node-name> --patch '{"spec":{"bgp":{"ipv4Address":"<correct-ip>/24"}}}'
5. 检查路由表
在问题节点和目标节点(10.42.74.176)上检查路由表,确认 BGP 路由是否注入:
cpp
ip route show | grep bird
正常应看到对方节点网段的路由条目:
10.244.1.0/24 via 10.42.74.176 dev eth0 proto bird
最后都不是:重启node节点解决