常见问题¶
一、信息查看¶
节点信息
K-KUBE-LAB-01 10.101.11.240
K-KUBE-LAB-02 10.101.11.114
K-KUBE-LAB-03 10.101.11.154
K-KUBE-LAB-201 10.101.11.238
K-KUBE-LAB-202 10.101.11.93
K-KUBE-LAB-203 10.101.11.53
kubernetes 所有组件中只会有 ETCD 存在 leader 选举
cd /etc/kubernetes
rsync -av manifests/ manifests-20230310/
rsync -av manifests-20230310/ manifests/
# The items in the lists are endpoint, ID, version, db size, is leader, is learner, raft term, raft index, raft applied index, errors.
etcdctl member list -w table \
--endpoints=https://10.101.11.114:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl endpoint status -w table \
--cluster \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl endpoint status -w table \
--cluster \
--endpoints=https://10.101.11.114:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# 切换leader
etcdctl move-leader ed1afb9abd383490 \
--endpoints=https://10.101.11.240:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl member remove 99bb4ff3ed8558ca \
--endpoints=https://10.101.11.114:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl member add k-kube-lab-201 \
--endpoints=https://10.101.11.114:2379 \
--peer-urls=https://10.101.11.238:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
二、MOCK场景¶
kubernetes cluster 在运行过程中会有很多异常情况,此处用于模拟异常并尝试恢复。
当control-plane不可用时,集群中业务的pod不受影响,流量正常接入。
2.1 终止部分control-plane节点¶
可行
| control-plane节点数 | 允许异常节点 |
|---|---|
| 3 | 1 |
| 4 | 1 |
| 5 | 2 |
| 6 | 2 |
| 7 | 3 |
| 8 | 3 |
| 9 | 5 |
模拟故障
# 共3台control-plane
#1,停第1台静态容器
cd /etc/kubernetes
mv manifests manifests-20230310
# 现象:集群正常,etcd leader 飘移
# 原因:etcd leader 成功飘移(etcd leader 刚好在停掉的节点上)
#2,停第2台静态容器
cd /etc/kubernetes
mv manifests manifests-20230310
# 现象:集群崩溃,etcd leader 消失
# 原因:etcd learner/leader 角色未发生变化,etcd luster节点数量小于2 etcd 集群不存在leader无法正常工作
恢复故障
#1,恢复第2台静态容器
cd /etc/kubernetes
rsync -av manifests-20230310/ manifests/
# 现象:集群正常,etcd leader 出现
# 原因:etcd leader 未发生飘移 ,etcd luster节点数量为2
#2,恢复第1台静态容器
cd /etc/kubernetes
rsync -av manifests-20230310/ manifests/
# 现象:集群正常
2.2 终止全部 control-plane 节点¶
不可行
# 参考场景一,当恢复到第2台 control-plane 时集群恢复可用。
2.3 挪用其他节点证书恢复¶
不可行
模拟故障
# 在其中一个节点上操作
#1,停掉control-plane
cd /etc/kubernetes
mv manifests manifests-20230310
# 现象:集群正常,摘掉1个control-plane
#2,备份证书
mv pki pki-20230310
恢复故障
#1,从其他节点恢复证书
scp /etc/kubernetes/pki
#2,恢复control-plane
cd /etc/kubernetes
rsync -av manifests-20230310/ manifests/
# 现象:集群正常,摘掉control-plane未恢复
# 原因:拷贝过来的证书签名中 X509v3 Subject Alternative Name 未包含当前节点信息
2.4 当集群不可用时 join 新节点¶
不可行
恢复故障
kubeadm init phase upload-certs --upload-certs
# I0310 17:40:27.320512 1479993 version.go:256] remote version is much newer: v1.26.2; falling back to: stable-1.25
# [upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
# error execution phase upload-certs: error uploading certs: error creating token: timed out waiting for the condition
# To see the stack trace of this error execute with --v=5 or higher
# 现象:无法join
# 原因:无法往etcd插入节点数据
2.5 编辑etcd数据¶
不可行
恢复故障
etcdctl member remove b9512d2bb2a3c6f5 \
--endpoints=https://10.101.11.154:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl member add k-kube-lab-201 \
--endpoints=https://10.101.11.154:2379 \
--peer-urls=https://10.101.11.238:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl endpoint status \
--endpoints=https://10.101.11.154:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
etcdctl endpoint status -w table \
--cluster \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# 原因:当集群不可用时etcd数据只支持查看
2.6 删除 control-plane节点后再join¶
可行
恢复故障
# etcd member 节点信息还存在需要先手动移除
etcdctl member remove 1bd3101f2cbe0fab \
--endpoints=https://10.101.11.154:2379 \
--cacert=/etc/kubernetes/pki/etcd/ca.crt \
--cert=/etc/kubernetes/pki/etcd/server.crt \
--key=/etc/kubernetes/pki/etcd/server.key
# 原因:若不
2.7 etcd数据不一致¶
+---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| ENDPOINT | ID | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
+---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
| https://10.101.11.240:2379 | 5fa87e503b09d83d | 3.5.1 | 112 MB | true | false | 3 | 309461550 | 309461550 | |
| https://10.101.11.114:2379 | 797dc1cea3a53a6b | 3.5.1 | 119 MB | false | false | 3 | 309461550 | 309461550 | |
| https://10.101.11.154:2379 | 8ac0782f040c745a | 3.5.1 | 123 MB | false | false | 3 | 309461550 | 309461550 | |
+---------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
三、番外篇¶
3.1 成员数量(cluser size)¶
这里主要涉及到两点。首先是一个etcd cluster的节点数量最好是奇数,两个原因:
- 对应的偶数个节点(奇数+1)能容忍的失败节点数量还是一样的。例如3个节点时,能容忍一个节点down,4个节点时同样只能容忍一个节点down。但是节点增多,导致失败的概率会增大;
- 在发生网络分区,将cluster隔离成两个小团体时,总有一个团体能满足quorum(法定票数),从而能继续提供服务。但是对于偶数个节点,则有可能两个隔离的分区都无法提供服务。
另外一点就是关于cluster节点数量的上限问题。虽然上限没有限制,但是一个etcd cluster最好不要超过7个节点。一方面,节点数量增加的确可以增加容错率,例如7个节点可以容忍3个down,9个则可以容忍4个down。但是另一方面,节点数量增加,同样也会导致quorum增大,例如7个节点的quorum是4,9个节点的quorum则是5;因为etcd是强一致性K/V DB,每一个写请求必须至少quorum个节点都写成功才能返回成功,所以节点数量增加会降低写请求的性能。
3.2 替换节点的正确姿势¶
当cluster中某个节点down了,一般需要把这个节点从cluster中移除,并增加一个新的节点到cluster中去。
这里一定要注意,要先删除老节点,然后再增加新节点。先删除后增加,先删除后增加,重要的事情说三遍!这个顺序不能反了,如果先增加新节点,然后再删除老节点,有可能导致cluster无法工作,并且永远也无法自动恢复,就必须人工干预了。
这里举一个例子来说明。假设cluster有三个节点,其中一个节点突然发生故障。这时cluster中还有两个节点健康,依然满足quorum,所以cluster还可以正常提供服务。这时如果先增加一个新节点到cluster中,因为那个down的节点还没有从cluster中移除,所以cluster的节点数量就变成了4。如果一切顺利,新节点正常启动,倒也还好。但是如果发生了意外(比如配置错误),导致新增加的节点启动失败,这时cluster的quorum已经从2变成了3,可是cluster中依然只有两个节点能工作,不符合quorum要求,从而导致cluster无法对外提供服务,而且永远无法自动恢复。这个时候,当你再想从cluster中删除任何节点,都不会成功了,因为删除节点也需要向cluster中发送一个写请求,这时cluster已经因为quorum不达标而无法提供服务了,所以删除节点的操作不会成功。这就尴尬了!
3.3 同时部署多个CNI¶
不能同时作为主要 CNI 插件使用。
原因
1️⃣ 都会向 /etc/cni/net.d/ 写入配置
Calico 和 Cilium 都会生成 CNI 配置文件,例如:
/etc/cni/net.d/10-calico.conflist
/etc/cni/net.d/10-cilium.conflist
Kubelet 启动 Pod 时会读取第一个匹配的 .conf/.conflist 文件。 当存在两个配置时,Pod 的网络命名空间可能被:
- 随机选中的一个插件配置;
- 或者直接报错(比如找不到网桥、重复分配 IP)。
2️⃣ 都会管理同一个网段(Pod CIDR)
- Calico 通常管理
192.168.0.0/16或10.244.0.0/16 - Cilium 也会接管一个相似的 CIDR(通常自动探测或由
--cluster-pool-cidr指定)
结果是:
- IP 分配冲突;
- 两个 IPAM(地址管理)同时申请相同地址;
- Pod 网络路由异常(flannel/calico/cilium 路由表混乱)。
3️⃣ 都会创建内核网桥与 veth 对
Calico host-gw / vxlan 与 Cilium eBPF / geneve 机制会同时插入路由:
ip route show table main
结果是:
- Pod 出流量路由到错误设备;
- eBPF program 与 iptables 规则互相覆盖;
cilium-agent和calico-felix同时修改内核路由策略。
解决
calico --> cilium
1️⃣ 检查当前 CNI 配置
kubectl get pods -n kube-system -l k8s-app=calico-node
kubectl get ds -n kube-system
ls /etc/cni/net.d/
你应该能看到:
/etc/cni/net.d/10-calico.conflist
并且 kubelet 启动参数里有:
--network-plugin=cni
--cni-conf-dir=/etc/cni/net.d
2️⃣ 备份 Calico 配置
kubectl get all -n kube-system -l k8s-app=calico-node -o yaml > calico-backup.yaml
kubectl get cm,ds,crd,svc,deploy,secret -n kube-system | grep calico
备份是为了可以在出问题时回滚。
3️⃣ 停止新 Pod 调度(可选)
如果是生产环境,建议在迁移期间暂停新调度:
kubectl cordon <node-name>
kubectl drain <node-name> --ignore-daemonsets
卸载 Calico
1️⃣ 删除 Calico 控制组件
kubectl delete -f https://docs.projectcalico.org/manifests/calico.yaml
或者如果你是自定义部署的:
kubectl delete ds,deploy,cm,svc,crd -n kube-system -l k8s-app=calico-node
2️⃣ 删除残留的 CRD(如果有)
kubectl delete crd bgppeers.crd.projectcalico.org bgpconfigurations.crd.projectcalico.org \
ippools.crd.projectcalico.org felixconfigurations.crd.projectcalico.org \
clusterinformations.crd.projectcalico.org blockaffinities.crd.projectcalico.org \
hostendpoints.crd.projectcalico.org ipamblocks.crd.projectcalico.org ipamhandles.crd.projectcalico.org \
networkpolicies.crd.projectcalico.org globalnetworkpolicies.crd.projectcalico.org
3️⃣ 删除 CNI 文件(非常关键)
在每个节点上执行:
sudo rm -f /etc/cni/net.d/10-calico.conflist
sudo rm -f /etc/cni/net.d/calico-kubeconfig
并确保目录下**只保留 loopback 配置**:
ls /etc/cni/net.d/
应该只剩:
00-loopback.conf
4️⃣ 清理网络接口与路由
Calico 会创建 cali* 接口与 iptables 规则。
执行以下命令:
# 删除所有 cali 接口
sudo ip link | grep cali | awk '{print $2}' | sed 's/://' | xargs -I{} sudo ip link delete {}
# 清理 iptables 残留
sudo iptables-save | grep -i cali
sudo iptables -F
sudo iptables -t nat -F
sudo iptables -X
sudo iptables -t nat -X
sudo iptables-save
可选:清理路由表中残留 Calico CIDR
sudo ip route show | grep cali
sudo ip route del <calico-cidr>