1. 问题现象与背景描述
那天下午,我正在测试一个Kubernetes集群的新功能。由于需要回退到之前的测试环境状态,我毫不犹豫地使用了VMware的快照恢复功能。恢复过程很顺利,虚拟机也正常重启了。但当我尝试访问集群时,却发现所有节点间的网络通信都中断了——kubectl命令超时,Pod间无法互相访问,甚至节点之间也失去了联系。
这种情况在VMware环境中并不罕见。根据我的经验,快照恢复后网络异常通常与以下几个因素有关:
- 虚拟机网卡MAC地址变化
- 网络接口配置丢失
- 防火墙规则被重置
- Kubernetes网络插件状态不一致
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 初步排查与问题定位
2.1 检查基础网络连通性
首先,我需要确认最基础的网络连接是否正常:
bash复制# 检查IP地址是否正常分配
ip addr show
# 测试网关连通性
ping <网关IP>
# 测试同网段其他节点
ping <其他节点IP>
在我的案例中,基础网络连接是正常的——IP地址正确分配,可以ping通网关和其他节点。这说明问题不在底层网络,而是出在Kubernetes网络层面。
2.2 检查Kubernetes组件状态
接下来,我检查了Kubernetes核心组件的运行状态:
bash复制# 查看节点状态
kubectl get nodes
# 查看kubelet日志
journalctl -u kubelet -n 100 --no-pager
# 检查网络插件状态
kubectl get pods -n kube-system | grep network
发现所有节点都处于"NotReady"状态,kubelet日志中不断报错"network plugin is not ready"。这明确指向了网络插件的问题。
3. 深入分析网络插件问题
3.1 Calico网络插件分析
我的集群使用的是Calico作为CNI插件。快照恢复后,Calico的以下组件可能出现问题:
- Felix:负责节点上的网络规则配置
- BIRD:负责节点间的路由分发
- calico-node:主进程,管理整个网络生命周期
检查Calico组件的日志:
bash复制kubectl logs -n kube-system <calico-node-pod-name> -c calico-node
日志中出现了大量"Failed to connect to etcd"的错误。这很奇怪,因为我们的集群使用的是kubeadm默认的配置,Calico应该通过Kubernetes API与集群通信,而不是直接连接etcd。
3.2 快照恢复对网络插件的影响
经过仔细排查,发现快照恢复导致了以下问题:
- IPAM状态不一致:Calico在快照恢复前分配的IP地址信息与当前实际网络状态不匹配
- 节点标识变化:快照恢复可能导致节点标识(如主机名、UUID等)发生变化
- 网络接口重置:Calico创建的虚拟网络接口(如tunl0)可能被重置
4. 解决方案与修复步骤
4.1 清理并重置Calico状态
首先需要完全清理现有的Calico状态:
bash复制# 删除Calico的IPAM数据
kubectl delete --all pods -n kube-system
kubectl delete --all deployments -n kube-system
kubectl delete --all daemonsets -n kube-system
# 清理节点上的Calico数据
sudo rm -rf /var/lib/calico/
sudo rm -rf /etc/cni/net.d/10-calico.conflist
4.2 重新部署Calico
然后重新部署Calico网络插件:
bash复制# 下载最新的Calico manifest文件
curl https://docs.projectcalico.org/manifests/calico.yaml -O
# 部署Calico
kubectl apply -f calico.yaml
4.3 验证网络恢复
等待所有Calico pod启动完成后,验证网络状态:
bash复制# 检查节点状态
kubectl get nodes
# 创建测试pod验证网络连通性
kubectl run test-pod --image=busybox -- sleep 3600
kubectl exec test-pod -- ping <其他节点IP>
5. 预防措施与最佳实践
为了避免类似问题再次发生,我总结了以下经验:
-
快照前的准备工作:
- 在创建快照前,先优雅地关闭Kubernetes集群
- 记录当前的网络配置和状态
- 备份重要的网络配置文件
-
快照恢复后的检查清单:
- 验证MAC地址是否变化
- 检查网络接口配置
- 确认主机名和节点标识一致
- 检查时间同步状态
-
长期解决方案:
- 考虑使用持久化存储保存CNI插件状态
- 实现自动化恢复脚本
- 定期备份网络配置
6. 技术原理深度解析
6.1 VMware快照机制对网络的影响
VMware快照恢复会影响到虚拟机的以下网络相关属性:
-
虚拟网卡MAC地址:
- 如果虚拟机配置为"自动生成MAC地址",恢复快照可能导致MAC变化
- 解决方案:在VMX文件中设置
ethernet0.addressType = "static"
-
网络接口状态:
- 快照恢复会重置网络接口的驱动状态
- 可能导致网络接口重命名或配置丢失
-
ARP缓存与邻居表:
- 快照恢复会清空ARP缓存
- 可能导致短暂的网络中断
6.2 Kubernetes网络插件的工作原理
以Calico为例,其核心组件在快照恢复后面临的挑战:
-
IPAM(IP地址管理):
- Calico使用
calico-ipam管理Pod IP分配 - 快照恢复可能导致IPAM状态与实际分配不一致
- Calico使用
-
BGP路由分发:
- BIRD进程维护的路由表在恢复后可能过时
- 需要重新建立BGP对等会话
-
Felix配置:
- Felix维护的iptables规则可能丢失
- 需要重新同步网络策略
7. 其他可能的相关问题与解决方案
7.1 使用其他CNI插件的情况
-
Flannel:
- 常见问题:子网租约文件不一致
- 解决方案:清理
/var/lib/cni/flannel目录
-
Weave Net:
- 常见问题:对等连接中断
- 解决方案:重启weave pod并检查对等状态
-
Cilium:
- 常见问题:eBPF映射丢失
- 解决方案:重启cilium-agent并重建eBPF映射
7.2 节点完全无法通信的情况
如果节点间完全无法通信,可以尝试以下步骤:
- 检查VMware虚拟交换机的配置
- 验证VLAN设置是否正确
- 检查物理网络设备的连接状态
- 确认没有网络隔离策略被意外启用
8. 自动化恢复脚本示例
为了简化未来的恢复过程,我创建了一个自动化脚本:
bash复制#!/bin/bash
# 停止kubelet服务
sudo systemctl stop kubelet
# 清理CNI配置
sudo rm -rf /etc/cni/net.d/*
sudo rm -rf /var/lib/cni/
# 清理Calico数据
sudo rm -rf /var/lib/calico/
sudo rm -rf /var/run/calico/
# 重启网络服务
sudo systemctl restart network
# 重启kubelet
sudo systemctl start kubelet
# 等待组件恢复
sleep 60
# 重新部署Calico
kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml
这个脚本可以保存为/usr/local/bin/reset-k8s-network.sh,并赋予执行权限。
9. 监控与告警建议
为了防止类似问题影响生产环境,建议设置以下监控项:
-
节点网络状态:
- 监控节点间的网络延迟
- 设置Pod间连通性检查
-
Calico特定指标:
felix_resync_state:检查配置同步状态bgp_session_state:监控BGP会话状态
-
告警规则示例:
yaml复制- alert: CalicoNodeDown expr: absent(up{job="calico-node"} == 1) for: 5m labels: severity: critical annotations: summary: "Calico node down (instance {{ $labels.instance }})" description: "Calico node {{ $labels.pod }} has been down for more than 5 minutes"
10. 总结与个人经验分享
经过这次故障排查,我深刻认识到在虚拟化环境中管理Kubernetes集群的几个关键点:
-
快照不是万能的:虽然快照提供了便捷的回退方式,但对有状态服务(如Kubernetes)可能带来复杂问题
-
文档记录很重要:在创建快照前,记录当前的网络配置和集群状态可以大大简化恢复过程
-
理解底层原理:只有深入理解CNI插件的工作原理,才能快速定位和解决网络问题
在实际操作中,我发现定期执行以下操作可以显著减少网络问题:
- 每月进行一次网络故障演练
- 维护一个标准化的恢复检查清单
- 在非生产环境中测试快照恢复流程
最后,对于关键业务集群,建议考虑使用更可靠的备份方案(如Velero)替代简单的VM快照,这样可以保证应用状态的完整性。
