柯儿的天空头像
关注
【Kubernetes从入门到精通】第51篇:K8s网络故障排查指南——Pod不通了别慌,按这条“黄金路径“走封面图

【Kubernetes从入门到精通】第51篇:K8s网络故障排查指南——Pod不通了别慌,按这条“黄金路径“走

上一篇【第50篇】多集群网络互联——Submariner和Cilium Cluster Mesh
下一篇【第52篇】K8s安全体系全景——Authentication/Authorization/Admission三道防线


摘要

前面五篇把K8s网络从模型到插件、从DNS到策略都讲透了。但理论和实战之间隔着一道墙:真出问题的时候,你对着一个"超时"的错误,根本不知道从哪下手

网络问题最磨人的地方在于——它横跨多个层级。一个HTTP请求从Pod出去,要过Pod网络、Service转发、kube-proxy、CNI插件、Node路由、物理网络……任何一层出问题,表现都是"连不上",但根因天差地别。

这篇文章给你一条**“黄金排查路径”**:Pod→Service→Node→外部。按顺序一层层剥,配合ip/nsenter/tcpdump/kubectl exec这几把利器,90%的网络问题都能在一顿饭功夫内定位。


一、黄金排查路径

1.1 总览

【网络排查黄金路径——"从内到外,逐层剥洋葱"】

  请求: Pod A → (Pod网络) → Service → (Node网络) → 外部/对端Pod
                  │              │            │
                  ▼              ▼            ▼
  Layer1:  Pod本机能通吗?   (localhost / 自身IP)
  Layer2:  Service能通吗?  (ClusterIP / Endpoints)
  Layer3:  Node层面OK吗?   (CNI / 路由 / 防火墙)
  Layer4:  外部/跨Node能通吗?(物理网络 / 安全组)

  口诀:先确认"自己没问题",再确认"中间人没问题",
        最后确认"外面没问题"。

要点:排查网络最忌讳"东戳一下西戳一下"。记住这个顺序——先Pod内部,再Service,再Node,最后外部。每次只验证一层,确认这层OK了再往下一层走。这样你永远不会在"Pod本身都起不来"的时候去调CNI。


二、Layer 1:Pod自身网络

2.1 Pod能上网吗?进程真在监听吗?

# 1. 进Pod看看进程在不在监听
kubectl exec -it my-pod -- netstat -tlnp 2>/dev/null || \
kubectl exec -it my-pod -- ss -tlnp
# 如果看不到 0.0.0.0:8080 在 LISTEN → 应用没起来或监听了127.0.0.1

# 2. 在Pod里自己curl自己
kubectl exec -it my-pod -- curl -s localhost:8080/health
# 自己都curl不通 → 应用层问题,不是网络问题!先去看应用日志

# 3. 看Pod IP 和 路由
kubectl exec -it my-pod -- ip addr show
kubectl exec -it my-pod -- ip route show

2.2 常见坑:应用只监听127.0.0.1

【经典坑:应用监听 localhost,集群里谁都连不上】

  错误配置:
    server.listen(127.0.0.1, 8080)   ← 只接受本机回环
    → 其他Pod访问这个Pod的Pod IP:8080 → 拒绝!

  正确配置:
    server.listen(0.0.0.0, 8080)     ← 接受所有网卡
    → 其他Pod才能通过Pod IP访问

三、Layer 2:Service和Endpoints

3.1 Endpoint为空 = Service白搭

这是Service不通的最高频原因:Service背后没有Endpoint(没有健康的Pod)

# 1. 看Service的Endpoint有没有
kubectl get endpoints my-service
# NAME          ENDPOINTS                     AGE
# my-service    10.244.1.5:8080,10.244.1.6   ← 有,正常
# 如果 ENDPOINTS 是 <none> → Service没匹配到Pod!

# 2. 为什么没匹配到?看Selector对不对
kubectl describe service my-service
# Selector: app=backend
kubectl get pods -l app=backend
# 如果Pod的Label不是app=backend → 永远匹配不上

# 3. 看EndpointSlice (新版本)
kubectl get endpointslices -l kubernetes.io/service-name=my-service
【Service不通的排查链】

  kubectl get svc → ClusterIP 有了?
        │ 有
        ▼
  kubectl get endpoints → 有后端Pod IP?
        │ 没有
        ▼
  检查 Service.selector 和 Pod.labels 是否一致
        │ 一致但还没有
        ▼
  检查 Pod 是否 Ready (readinessProbe通过?)
        │ Pod 不 Ready → kube-controller-manager不会把它加入Endpoints
        ▼
  检查 kube-proxy 是否正常运行 + 模式正确

要点:Service不通,八成是Endpoint为空。而Endpoint为空,八成是Selector和Pod Label对不上,或者Pod的readinessProbe没过(不Ready的Pod不会被加入Endpoint)。先kubectl get endpoints一发,真相往往就出来了。


四、Layer 3:Node和CNI

4.1 CNI插件是否健康

# 1. 看CNI插件Pod状态
kubectl get pods -n kube-system -o wide | grep -E "calico|flannel|cilium"
# 不是Running?看日志

# 2. 看节点上的CNI配置和二进制
ls /etc/cni/net.d/        # 配置文件
ls /opt/cni/bin/          # 二进制

# 3. 看节点路由表 (跨Node通信靠它)
ip route show | grep <pod-cidr>
# 没有对端Pod网段的路由 → CNI插件没写路由

# 4. 看vxlan/bgp接口
ip link show | grep -E "vxlan|flannel|cali|cilium"

4.2 用tcpdump抓包定位

# 在Node上抓Pod的包 (进Pod的网络命名空间抓)
# 方法1: 用nsenter进Pod的netns
PID=$(docker inspect -f '{{.State.Pid}}' <container-id>)
nsenter -t $PID -n tcpdump -i eth0 -nn port 8080

# 方法2: 直接在主机的veth上抓
ip link show | grep veth
tcpdump -i vethxxxx -nn host 10.244.1.5

# 看包到没到对端Node
tcpdump -i any -nn host 10.244.2.5   # 在对端Node抓
# 如果发出去了但没回来 → 对端CNI/防火墙问题
# 如果根本没发出去 → 本端路由/iptables问题

五、Layer 4:DNS与跨Node

5.1 DNS解析失败

# 1. 直接在Pod里解析
kubectl exec -it my-pod -- nslookup kubernetes.default
# 失败?检查CoreDNS
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns | grep -i error

# 2. 看Pod的resolv.conf
kubectl exec -it my-pod -- cat /etc/resolv.conf
# nameserver 必须是CoreDNS的ClusterIP

# 3. 经典坑: ndots:5 导致外部域名慢
#   解决: 调整dnsConfig或ndots值

5.2 跨Node不通

【跨Node不通的排查清单】

  1. 安全组/防火墙挡了?
     → 同Node能通、跨Node不通,多半是云厂商安全组没放行
     → 放行: VXLAN(8472/UDP) / BGP(179/TCP) / 节点IP段

  2. CNI封装模式对吗?
     → Flannel默认vxlan,确认8472端口通
     → Calico BGP模式,确认节点间IP层可达

  3. 路由表有没有对端网段?
     → ip route show | grep <对端Pod CIDR>

六、排查工具箱速查

【K8s网络排查"瑞士军刀"】

  kubectl exec -it <pod> -- <cmd>   进Pod执行命令
  kubectl get endpoints <svc>       看Service后端
  kubectl describe svc <svc>        看Service详情/事件
  kubectl get pods -n kube-system   看网络插件状态
  ip route show                      看Node路由表
  ip link show                      看网络接口
  tcpdump -i <if> -nn <过滤>         抓包(最硬核)
  nsenter -t <pid> -n <cmd>          进Pod netns
  curl -s <ip>:<port>               测连通性

要点:网络排查没有捷径,但有顺序。抓住"黄金路径"——先Pod、再Service、再Node、最后外部——每一步用对工具,你就能从"一脸懵"变成"一眼定位"。tcpdump虽然硬核,但当你怀疑包被丢了、被改了,它就是最后的真相之眼。


本篇小结

网络不通不可怕,可怕的是没章法地乱试。记住黄金路径:Pod自身(进程监听了0.0.0.0吗?)→ Service(Endpoint有后端吗?Selector对吗?)→ Node/CNI(插件活着吗?路由写了吗?)→ 外部/DNS(安全组放了吗?CoreDNS活吗?)。

九成问题集中在前两层——Endpoint为空和DNS故障。tcpdump+nsenter是你的终极武器,但当它们出场时,说明问题已经比较深了。网络模块到此通关,下一篇我们进入安全体系——K8s的"三道防线"。


上一篇【第50篇】多集群网络互联——Submariner和Cilium Cluster Mesh
下一篇【第52篇】K8s安全体系全景——Authentication/Authorization/Admission三道防线


转载自 CSDN-专业IT技术社区

原文链接:https://blog.csdn.net/xyghehehehe/article/details/163812018

文章来源crawl

评论

赞0

评论列表

微信小程序
QQ小程序

关于作者

点赞数:0
关注数:0
粉丝:0
文章:0
关注标签:0
加入于:--