容器云网络故障深度排查:POD访问SVC超时全解析

1. 故障背景

  单节点Kubernetes集群升级操作系统内核版本、NVIDIA驱动与CUDA后重启服务器,引发容器云管理界面访问异常。核心环境如下:

  • ​​组件版本​​:
    • Ubuntu 5.19.0-40-generic
    • Kubernetes 1.21.5, Docker 27.5.1
    • 网络插件:Flannel(Pod网段 10.233.64.0/18、Svc网段10.233.0.0/18)
    • 域名解析:CoreDNS + NodeLocalDNS
    • 代理模式:Kube-Proxy ipvs模式
  • ​​关键现象​​:
    Pod可互访​​Pod IP​​,宿主机可访问​​Service IP​​与​​Pod IP​​,但Pod内部访问​​Service IP超时​​(如 10.233.36.146:6379)。

2. 问题排查

阶段一:基础状态检查​

(1)防火墙确认:ufw status 显示inactive(排除防火墙拦截)

(2)核心组件状态:

kubectl get pods -n=kube-system  # 所有组件Running
kubectl get pods -n=容器云核心组件-system  # 发现apiserver报错

(3)日志线索定位:

kubectl logs -f -n=容器云核心组件-system apiserver-68654cdc5-gg88b

关键报错:

Error: failed to connect to redis service, please check redis status, error: dial tcp 10.233.36.146:6379: i/o timeout
2025/07/29 17:22:08 failed to connect to redis service, please check redis status, error: dial tcp 10.233.36.146:6379: i/o timeout

结论:DNS解析正常(域名→Service IP),但Service流量不通。

(4)排查redis服务运行情况:

kubectl get pods -n=容器云公共组件-system |grrp redis

Redis容器运行状态正常,容器日志也正常,将Redis Svc改成NodePort模式,通过本地Redis客户端工具也能正常连接Redis服务,说明Redis服务是正常的。

阶段二:网络分层验证

  • 客户端: bubybox容器或者宿主机
  • 服务端: 集群里正常运行的Nginx服务
测试类型​​​​操作命令​​​​结果​​​​推断​​
​​Pod→Pod IP​​/* by 01022.hk - online tools website : 01022.hk/zh/textflip.html */ kubectl exec -it busybox -- telnet <PodIP> 80✅ 成功Flannel底层网络正常
 
​​Pod→Service IP​​/* by 01022.hk - online tools website : 01022.hk/zh/textflip.html */ kubectl exec -it busybox -- telnet <SvcIP> 80❌ 超时Service层异常
​​宿主机→Service​​telnet <SvcIP> 80✅ 成功kube-proxy规则对宿主机有效

关键矛盾点​​:

  • IPVS规则存在(ipvsadm -Ln | grep <SvcIP> 显示正常DNAT)
  • 但Pod流量无法穿透Service

注意: 如果使用的是iptables规则使用iptables-save | grep <service-name>命令排查Kube-Proxy组件是否生成了SvcIP转PodIP规则。

阶段三:抓包与内核层深挖​

(1)​​抓包分析(Pod侧)​​

同时打开2个shell,都进入busybox容器内部,其中一个shell执行tcpdump命令进行抓包,另一个shell执行telnet nginx_svcIp(10.233.42.160) 80命令。

tcpdump -i any 'host 10.233.42.160 and tcp port 80' -w svc_capture.pcap

抓包结束后使用kubectl cp或者docker cp命令将抓的包拷贝到宿主机上再使用sftp工具下载到本地用wireshark分析,发现源地址到不了目标svcIP。

image

结论:

持续发送SYN包 → ​​零响应​​(无RST/SYN-ACK),排除目标拒绝,指向​​中间层拦截​​。

​​源地址​​:Pod IP 10.233.64.250(发送方)

​​目标地址​​:Service IP 10.233.42.160

​​行为​​:

  1. 发送端发起TCP SYN请求(序号1)
  2. 连续​​6次重传SYN包​​(序号2-7),时间间隔指数级增长(1s → 3s → 7s → 15s → 31s → 64s)

​​关键缺失​​:​​零响应​​:无SYN-ACK(目标端确认)、无RST(目标拒绝)

 (2)​​抓包分析(服务器侧)​​

同时打开2个shell,一个直接在服务器上执行tcpdump命令进行抓包(直接抓nginx_podIP),另一个进入busybox容器内部执行telnet nginx_svcIp(10.233.42.160) 80命令。

tcpdump -i any 'host 10.233.64.43 and tcp port 80' -w svc_capture.pcap

抓包结束后使用kubectl cp或者docker cp命令将抓的包拷贝到宿主机上再使用sftp工具下载到本地用wireshark分析,根据包信息可以看到pod访问svcIp时也进行了DNAT将svcIP转成podIp了(说明kube-proxy正常),但是源Pod访问不通目标Pod。

image

(3)内核参数致命错误

这时候怀疑是Conntrack问题,使用sysctl -p命令检查内核参数配置,发现参数加载报错。

8b96bf6997b136e913d074479c246fe4

这三个关键内核参数配置没有加载成功,主要是net.bridge.bridge-nf-call-iptables = 1。

net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1  

net.bridge.bridge-nf-call-iptables = 1参数失效后果。

`net.bridge.bridge-nf-call-iptables=0`  
↓  
网桥流量**绕过iptables规则**  
↓  
kube-proxy的IPVS DNAT规则**失效**

net.bridge.bridge-nf-call-iptables = 1​​

  1. ​​作用​​:控制通过 Linux 网桥的 ​​IPv4 流量是否经过 iptables 规则链​​(如 FORWARD、INPUT)。
  2. ​​启用后(=1)​​:
    • 桥接流量(如 Pod 间通信、Service IP 访问)会被提交到 iptables 规则处理。
    • 这是 Kubernetes 的​​必需配置​​,确保 kube-proxy 的 Service 负载均衡规则(DNAT)能生效。image
  3. ​​禁用后(=0)​​:
    • 桥接流量绕过 iptables,导致 Service IP 的 DNAT 规则失效,​​Pod 访问 Service IP 必然失败​​。image

注意:

  1. ​​IPVS 的独立处理​​:

    • IPVS 工作在内核 L4 层,其 DNAT 规则(ipvsadm -Ln 看到的记录)不依赖 iptables。
    • 即使 bridge-nf-call-iptables=0,IPVS 仍能通过内核的 nf_conntrack 完成 DNAT 转换。
  2. ​​失效的真正表现​​:

    • DNAT ​​转换成功​​,但流量 ​​无法正确路由回 Pod​​。
    • 原因:网桥流量绕过 iptables 后,​​缺失关键的路由/过滤规则​​(如 KUBE-MARK-MASQ 标记、KUBE-FORWARD 链的放行规则)。

​​net.bridge.bridge-nf-call-ip6tables = 1​​

  1. ​​作用​​:控制桥接的 ​​IPv6 流量是否经过 ip6tables 规则链​​。
  2. 在 IPv6 环境中需启用,否则 IPv6 Service 无法正常工作。

​​net.bridge.bridge-nf-call-arptables = 1

  1. 作用​​:控制桥接的 ​​ARP 流量是否经过 arptables 规则链​​。
  2. 启用后可防止 ARP 欺骗,但对 Service IP 通信影响较小。

3. 解决方案:修复内核隔离​

步骤一:动态加载模块​

加载内核模块:

modprobe br_netfilter # 临时加载
modprobe nf_conntrack # 临时加载
echo "br_netfilter" >> /etc/modules-load.d/k8s.conf # 永久加载
echo "nf_conntrack" >> /etc/modules-load.d/k8s.conf # 永久加载

步骤二:永久固化配置​内核参数配置(实际这些参数之前都有,只不过上面那三行加载失败了)

cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-arptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf #执行sysctl -p命令不报错

立即生效:Pod访问Service IP恢复。

安装k8s集群建议内核参数配置:

net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.icmp_ignore_bogus_error_responses = 1
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
kernel.dmesg_restrict = 1
kernel.sysrq = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-arptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_local_reserved_ports = 30000-32767
vm.max_map_count = 262144
vm.swappiness = 1
fs.inotify.max_user_instances = 524288

modprobe br_netfilter:​​

  • ​​作用​​:动态加载 br_netfilter 内核模块。
  • ​​功能​​:该模块使​​网桥流量经过 Netfilter 框架(iptables/ip6tables)​​,是 Kubernetes 等容器网络的基础。启用后,网桥(如 Docker 的 docker0 或 CNI 网桥)的流量会被 iptables 规则处理,确保 Service DNAT、NodePort 等生效。
  • ​​场景​​:解决同节点 Pod 互访 Service IP 失败问题(因绕过 iptables 导致 DNAT 失效)。

​​modprobe ip_conntrack:​​

  • ​​作用​​:加载 ip_conntrack 模块(新内核中名为 nf_conntrack)。
  • ​​功能​​:实现​​连接跟踪(Connection Tracking)​​,记录网络连接状态(如 TCP/UDP 会话),是 NAT 和有状态防火墙的核心依赖。例如,Kubernetes Service 的 SNAT/DNAT 依赖此模块。
  • ​​注意​​:新版本内核中该模块已更名为 nf_conntrack,但 modprobe ip_conntrack 会自动加载新模块。

​​sysctl -p:​​

  • ​​作用​​:重新加载 /etc/sysctl.conf 或 /etc/sysctl.d/*.conf 中的内核参数配置。
  • ​​功能​​:使修改的 net.bridge.bridge-nf-call-iptables、net.ipv4.ip_forward 等参数​​立即生效​​。

步骤三:残余问题

向量数据库仍异常 → 定位到​​冗余iptables规则拦截​​:

img_v3_02om_2e2158f7-df53-41bf-99bd-a7f60cc2ddbg 

iptables -t filter -L KUBE-EXTERNAL-SERVICES --line-numbers
iptables -t filter -D KUBE-EXTERNAL-SERVICES <行号>  # 删除冲突规则

最终状态​​:所有服务连通性恢复。

4. 总结

故障根因​​​​防御措施​​
内核升级后模块未加载将 br_netfilternf_conntrack 加入 /etc/modules-load.d/k8s.conf
桥接流量隔离部署前验证 sysctl net.bridge.bridge-nf-call-iptables=1
​​核心启示​​:升级后需全链路测试网络,重点检查 ​​内核参数 → 网桥 → kube-proxy​​链条。 
<think> 首先,用户的问题是:“我想查找K8s网络故障排查思路 请问Kubernetes网络故障排查思路”。这是在询问Kubernetes网络故障排查的思路。 根据系统级指令: - 所有行内数学表达式必须使用$...$格式。但在这个上下文中,可能没有数学表达式,所以我可以忽略。 - 独立公式必须使用$$...$$格式并单独成段。同样,可能不需要。 - LaTeX语法正确:确保任何数学表达正确。 - 使用中文回答:整个回答必须是中文。 - 生成相关问题:在回答后添加相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。必须引用提供的引用内容。 用户提供了几个引用: - 引用[1]:关于PodPod之间网络故障排查思路。 - 引用[2]:关于Kubernetes常见故障及解决方案。 - 引用[3]:关于Kubernetes网络故障排查。 - 引用[4]:关于Kubernetes故障排查实战。 我需要基于这些引用构建回答,确保回答真实可靠,并引用相关部分。 用户上一次问题或历史:指令说“请尽可能多的参考用户上一次的问题和你的回答”,但在这个消息中,用户的问题是新提出的,所以我应该聚焦于当前问题。 回答结构:应该清晰、逐步帮助用户解决问题。结构可以是: 1. 引言:概述Kubernetes网络故障排查的重要性。 2. 详细步骤:基于引用,提供排查思路。 3. 结论或总结。 4. 生成相关问题。 关键点从引用中提取: - 从引用[1]:排查Pod网络通信故障的通用思路:检查Calico状态,Kube-proxy状态,容器日志,Docker服务状态。 - 从引用[2]:节点状态为NotReady的原因:Kubelet异常、网络故障、资源压力。解决方案:检查Kubelet服务、网络连接、节点资源。 - 从引用[3]:涉及DNS检查,如nslookup命令。 - 从引用[4]:网络错误确认三件事:Pods工作是否正常?直接连接到Pod IP?应用端口配置正确? 整合这些: - 总体思路:从底层到高层,从组件状态到具体连接。 - 步骤: 1. 检查网络组件(如Calico)状态和日志。 2. 检查Kube-proxy状态。 3. 检查节点状态和Kubelet服务。 4. 检查Pods状态和日志。 5. 测试网络连接(如直接连接到Pod IP)。 6. 检查DNS设置。 7. 检查端口配置和防火墙。 确保回答结构清晰: - 使用标题或小节。 - 步骤化。 在引用处:自然地添加引用标识。例如,在描述某个点时,说“... [^1]”。 生成相关问题:在末尾添加相关问题,以§§相关问题§§开头。 最终回答结构: 1. Kubernetes网络故障排查概述。 2. 详细排查步骤(基于引用)。 3. 总结。 4. 相关问题。 使用中文。 </think>### Kubernetes网络故障排查思路 在Kubernetes(K8s)集群中,网络故障是常见问题,可能导致Pod间通信失败、服务不可用或节点不可达。排查时,建议采用分层方法,从底层网络组件到上层应用逐步验证。以下是基于最佳实践的通用排查思路,结合了常见故障场景和解决步骤。每一步都参考了相关文档,确保可靠性和实用性。 #### 1. **检查网络插件状态** Kubernetes依赖网络插件(如Calico、Flannel)实现Pod间通信。首先确认插件运行状态: - 查看Calico或其他插件的Pod状态:`kubectl get pods -n kube-system | grep calico`(或对应插件名)。 - 检查日志:例如 `kubectl logs <calico-pod-name> -n kube-system`,日志中可能显示网络配置错误或连接问题[^1]。 - 如果插件状态异常,重启或重新部署插件可能解决。 #### 2. **验证Kube-proxy和节点状态** Kube-proxy负责服务负载均衡,异常会影响网络通信: - 检查Kube-proxy Pod:`kubectl get pods -n kube-system | grep kube-proxy`,确保所有Pod为Running状态。 - 查看节点状态:`kubectl get nodes`,如果节点显示NotReady,需排查原因: - 验证Kubelet服务:在问题节点执行 `systemctl status kubelet`,确保服务运行正常[^2]。 - 检查网络连接:确认节点到Master的通信(如使用 `ping` 或 `telnet` 测试Master IP和端口)。 - 资源压力:运行 `kubectl describe node <node-name>` 检查CPU/内存使用情况,资源耗尽可能导致网络中断[^2]。 #### 3. **排查Pod和容器级别问题** Pod是网络通信的基本单元,故障可能源于Pod自身: - 检查Pod状态:`kubectl get pods -o wide`,观察Pod的IP、重启次数和状态。异常重启可能表示网络冲突或资源不足。 - 直接测试Pod网络: - 获取Pod IP:`kubectl get pod <pod-name> -o jsonpath='{.status.podIP}'`。 - 在另一个Pod中执行连接测试:例如 `kubectl exec -it <source-pod> -- ping <target-pod-IP>`,验证Pod间连通性[^4]。 - 查看容器日志:`kubectl logs <pod-name>`,日志中可能包含网络错误信息(如连接超时或DNS失败)。 - 确认Docker或容器运行时状态:在节点上运行 `systemctl status docker`,确保运行时服务正常运行[^1]。 #### 4. **测试DNS和服务发现** DNS故障是常见网络问题,影响服务解析: - 验证CoreDNS或kube-dns状态:`kubectl get pods -n kube-system | grep coredns`。 - 执行DNS查询测试:在Pod内运行 `nslookup kubernetes.default.svc.cluster.local`,检查是否能解析集群内部服务[^3]。 - 如果解析失败,检查CoreDNS配置和日志。 #### 5. **检查端口配置和网络策略** 应用端口错误或网络策略阻塞可能导致通信失败: - 确认Pod端口:查看Pod的YAML定义,确保 `containerPort` 与应用实际端口匹配(如应用在8080端口,YAML中应为 `containerPort: 8080`)[^4]。 - 测试服务连通性:`kubectl get svc` 获取服务IP,然后 `telnet <service-ip> <port>` 测试访问。 - 检查网络策略:`kubectl get networkpolicy`,确保策略未错误地限制流量。 #### 6. **高级网络诊断** 如果以上步骤未解决问题,进行深入分析: - 网络抓包:在节点或Pod内使用 `tcpdump`(如 `tcpdump -i any port 53` 抓DNS流量)。 - 防火墙和路由检查:确认节点防火墙未阻止流量(如iptables或firewalld),并检查路由表 `route -n`。 - 集群事件日志:`kubectl get events --sort-by=.metadata.creationTimestamp`,查找网络相关警告。 #### 总结 Kubernetes网络故障排查应从底层组件(如网络插件和Kube-proxy)开始,逐步到Pod和DNS层,最后验证应用配置。大多数问题源于组件异常、资源不足或配置错误。快速修复包括重启服务、优化资源或调整网络策略。如果问题持续,参考官方文档或社区工具(如 `kubectl describe` 和 `kubectl debug`)进行诊断[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值