Administrator
发布于 2025-09-28 / 3 阅读
0
0

记录一个pod无法访问外网的事故

事故前言

有一个k8s的node节点上面的pod全部无法请求k8s集群以外的IP地址。只有一个节点上的pod全部有问题,其他节点的都是正常的。

排查过程

kubectl exec -it -n sc-microservice analysis-service-7cccbd6744-z6qqs -- curl -v https://www.baidu.com 
kubectl exec -it -n sc-microservice analysis-service-7cccbd6744-z6qqs -- nslookup www.baidu.com

通过curl得知dns解析是正常的。

kubectl logs -n kube-system kube-proxy-ddr22 
kubectl logs -n kube-flannel kube-flannel-ds-sz9gt 

通过日志发现Flannel网络组件日志dial tcp 10.96.0.1:443: i/o timeout发现存在连接问题。

kubectl delete pod -n kube-flannel kube-flannel-ds-sz9gt
kubectl delete pod -n kube-system kube-proxy-ddr22

通过删除重建节点上面的kube-proxyflannel 解决了访问http://www.baidu.com的故障。发现更奇怪的问题,该节点的pod可以请求外网地址的http80请求,无法请求https443请求。

iptables -t nat -L -n | grep 443
[root@k8s-node01 ~]# iptables -t filter -L -n | grep 443
# Warning: iptables-legacy tables present, use iptables-legacy to see them
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:443

过通iptables -t filter -L -n | grep 443 发现一条其他node节点都没有的iptables请求,猜测应该是iptables规则污染导致的。

# 备份当前规则
mkdir -p /root/iptables_backup
iptables-save > /root/iptables_backup/iptables_rules_$(date +%Y%m%d_%H%M%S).bak
iptables-legacy-save > /root/iptables_backup/iptables_legacy_rules_$(date +%Y%m%d_%H%M%S).bak

# 清理常规iptables
iptables -F    # 清空所有链的规则
iptables -X    # 删除所有自定义链
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F
iptables -t raw -X
iptables -t filter -F
iptables -t filter -X

# 清理legacy iptables
iptables-legacy -F
iptables-legacy -X
iptables-legacy -t nat -F
iptables-legacy -t nat -X
iptables-legacy -t mangle -F
iptables-legacy -t mangle -X
iptables-legacy -t raw -F
iptables-legacy -t raw -X
iptables-legacy -t filter -F
iptables-legacy -t filter -X

# 重启containerd(可能会导致容器短暂中断)
systemctl restart containerd

# 重启kubelet
systemctl restart kubelet

# 在控制节点上执行(或者有kubectl权限的任何机器上)
# 重启kube-proxy
kubectl delete pod -n kube-system $(kubectl get pods -n kube-system -o wide | grep kube-proxy|grep node01| awk '{print $1}')
# 重启flannel
kubectl delete pod -n kube-flannel $(kubectl get pods -n kube-flannel -o wide | grep flannel | grep node01 | awk '{print $1}')

通过清理iptables规则和重启containerd、kubelet、kube-proxy、kube-flannel完成之后。测试curl恢复正常,问题修复。

总结

问题有两个:

  • kube-flannel出现网络问题导致无法请求外网。

  • iptables规则污染导致无法请求所有外部地址的443端口。


评论