Kubernetes网络故障分层诊断:从DNS到CNI的实战排查指南
1. 为什么 Kubernetes 网络组件“看不见”却最常出问题?
在 K8s 集群里,你可能花三天时间调通一个 Pod 的 CPU 限制,结果它一跑起来就卡在 Pending 状态;也可能刚部署完一个 Service,前端死活连不上后端,curl -v http://svc-name:8080返回Connection refused,而kubectl get pods显示所有 Pod 都是 Running。这时候翻日志、查事件、看资源配额,全都没报错——问题就藏在那层“看不见”的网络里。
这不是玄学,而是 Kubernetes 网络模型的天然设计决定的:它把网络抽象成“每个 Pod 拥有独立 IP、可被集群内任意节点直接访问”的逻辑平面,但这个平面背后,是由 CNI 插件、kube-proxy、iptables/ipvs、CoreDNS、Service CIDR、Pod CIDR、节点路由表、主机防火墙、甚至云厂商 VPC 路由规则等至少 7 层组件协同撑起来的。它们不暴露在kubectl get列表里,不写进 Deployment YAML,也不出现在 Prometheus 的默认指标中。你删掉一个 CoreDNS Pod,集群会自动拉起新实例;但如果你误删了calico-node的 DaemonSet,整个集群的 Pod 间通信会在 90 秒内集体失联——而kubectl get nodes依然显示 Ready。
我第一次在生产环境遇到这个问题,是在一次 Ubuntu 22.04 升级后。系统内核从 5.15 升到 6.2,iptables-nft默认替代了iptables-legacy,而当时用的 Calico v3.22 还没完全适配 nftables 后端。现象是:新调度的 Pod 可以互相 ping 通,但老 Pod 就连不上新 Pod,tcpdump抓包发现 SYN 包发出去了,SYN-ACK 却根本没回来。排查链路花了整整 6 小时:先确认 Service 和 Endpoints 正常 → 再验证 kube-proxy 日志无异常 → 接着检查节点路由表发现10.233.64.0/18(Calico 的 Pod CIDR)路由指向了tunl0设备 → 最后在ip rule show里发现一条被内核升级自动注入的from all lookup local规则,把本该走 Calico FIB 的流量劫持到了本地协议栈。这个细节,任何“Kubernetes 菜鸟教程”都不会提,因为它的触发条件太具体:Ubuntu 22.04 + 内核 6.2+ + Calico v3.22 + iptables-nft 切换。但它真实存在,且每天都在不同团队重演。
所以,“Инспектирование сетевых компонентов Kubernetes”(Kubernetes 网络组件检查)不是一项可选技能,而是 K8s 工程师的生存底线。它不等于“看一眼kubectl get svc”,而是要像网络工程师一样,分层穿透:从 DNS 解析层(CoreDNS)、服务发现层(kube-proxy + iptables/ipvs)、容器网络层(CNI 插件的 dataplane)、节点网络层(路由表 + 防火墙)、再到底层传输层(MTU、TCP MSS、网卡 offload)。每层都有其专属的检查工具、关键指标和典型故障模式。接下来,我会带你一层一层拆解,用实操命令、输出解读和真实踩坑案例,把这套检查体系变成你肌肉记忆的一部分。
2. DNS 层诊断:当nslookup nginx-svc.default.svc.cluster.local返回server can't find...时,你该查什么?
DNS 是 Kubernetes 网络的“门面”,90% 的连接失败,第一步就卡在这里。但很多人只记得kubectl get pods -n kube-system | grep coredns,看到两个 Pod Running 就以为万事大吉。实际上,CoreDNS 的健康状态、配置正确性、上游解析能力、以及客户端 Pod 的/etc/resolv.conf配置,四者缺一不可。
2.1 确认 CoreDNS Pod 状态与资源占用
首先,别只看Running。执行:
kubectl get pods -n kube-system -l k8s-app=kube-dns -o wide重点看三列:
READY列:必须是1/1,如果显示0/1,说明容器启动失败,立刻kubectl logs -n kube-system <coredns-pod-name>;RESTARTS列:非零值意味着容器反复崩溃,常见于内存不足(OOMKilled)或配置语法错误;NODE列:确保两个 Pod 分布在不同节点上,避免单点故障。
接着查资源使用:
kubectl top pods -n kube-system -l k8s-app=kube-dns如果 CPU 持续 >800m 或内存 >300Mi,说明解析压力过大。此时要检查是否启用了autopath插件(它会为每个查询生成多个上游请求),或是否存在恶意域名爆破(如*.random123456.com的泛解析请求)。我们曾在一个测试集群发现,一个开发误将curl http://api.example.com写成curl http://api.example.com.(末尾多了一个点),导致 CoreDNS 对api.example.com.进行递归查询,而该域名不存在,触发了长达 5 秒的超时等待,拖垮了整个 DNS QPS。
2.2 验证 CoreDNS 配置与插件链
CoreDNS 的 ConfigMap 名为coredns,位于kube-system命名空间。执行:
kubectl get configmap coredns -n kube-system -o yaml核心检查点有三个:
forward插件的上游 DNS:forward . 8.8.8.8是常见配置,但企业内网应指向内部 DNS 服务器(如10.10.10.10)。如果上游 DNS 不可用,CoreDNS 会缓存 NXDOMAIN 响应 30 秒,导致新服务上线后无法解析。kubernetes插件的pods insecure参数:默认为insecure,允许通过pod-name.namespace.pod.cluster.local解析 Pod IP。如果改为verified,则要求 Pod 必须有对应 Endpoint,否则返回 NXDOMAIN。这个参数常被误改,导致调试时nslookup失败。cache插件的 TTL 设置:cache 30表示缓存 30 秒。如果服务频繁扩缩容,TTL 过长会导致客户端拿到过期的 Endpoint IP。
提示:修改 ConfigMap 后,CoreDNS Pod 不会自动重启。必须手动滚动更新:
kubectl rollout restart deployment coredns -n kube-system。这是新手最容易忽略的步骤,改完配置却看不到效果,就是因为 Pod 还在用旧配置运行。
2.3 从客户端 Pod 内部验证 DNS 解析链路
这才是最关键的一步。不能只在控制节点上nslookup,必须进入目标 Pod:
kubectl exec -it <your-pod-name> -- sh # 进入后执行: cat /etc/resolv.conf标准输出应类似:
nameserver 10.96.0.10 search default.svc.cluster.local svc.cluster.local cluster.local options ndots:5nameserver必须是 ClusterIP10.96.0.10(CoreDNS 的 Service IP),而不是127.0.0.1或宿主机 IP;search域必须包含.svc.cluster.local,否则curl nginx-svc会尝试解析nginx-svc.default.svc.cluster.local,而非nginx-svc.default.svc.cluster.local.(注意末尾点);ndots:5表示:如果域名中点号数量少于 5,就依次追加search域进行查询。这就是为什么curl nginx-svc能成功,而curl nginx-svc.default会失败(它被追加为nginx-svc.default.default.svc.cluster.local)。
然后执行真实解析测试:
# 测试集群内服务解析 nslookup nginx-svc.default.svc.cluster.local # 测试外部域名解析(验证 upstream) nslookup google.com # 测试反向解析(验证 PTR 记录) nslookup 10.233.64.10如果第一项失败但第二项成功,问题一定在kubernetes插件配置或 Service/Endpoints 对象本身;如果第二项也失败,则上游 DNS 或 CoreDNS 网络连通性有问题。
2.4 实战排错:CoreDNS 日志里的“silent fail”
有一次,用户报告说curl nginx-svc超时,但nslookup nginx-svc却能返回正确 IP。这说明 DNS 解析成功,但网络层不通。我们进入 CoreDNS Pod 查日志:
kubectl logs -n kube-system coredns-5d4dd4b4db-abcde | tail -20发现大量类似日志:
[INFO] 10.233.64.5:42123 - 12345 "A IN nginx-svc.default.svc.cluster.local. udp 54 false 512" NOERROR qr,aa,rd 106 0.000123456sNOERROR表示解析成功,qr,aa,rd表示是响应、权威、递归。一切正常?再看更早的日志:
[ERROR] plugin/errors: 2 nginx-svc.default.svc.cluster.local. A: read udp 10.233.64.10:53535->10.10.10.10:53: i/o timeout原来,CoreDNS 在尝试向上游 DNS 查询nginx-svc.default.svc.cluster.local时超时了,但因为它配置了fallthrough,就转而查询kubernetes插件,最终从本地 Service 对象拿到了 IP。所以nslookup成功了,但这个过程耗时 2.3 秒(日志里0.002345678s),远超客户端curl的默认 30 秒超时。解决方案是:在forward插件后添加policy random,并增加max_fails 1,让 CoreDNS 在上游失败时立即 fallback,而不是等待超时。
这个案例说明:DNS 层的“成功”不等于“低延迟”,而高延迟在网络调用链中会被指数级放大。检查 DNS,永远要带着time nslookup和tcpdump -i any port 53一起上。
3. Service 与 kube-proxy 层:为什么kubectl get endpoints显示有 IP,但curl还是 Connection refused?
Service 是 Kubernetes 的服务发现抽象,但它的背后,是 kube-proxy 这个“流量翻译官”在默默工作。它监听 API Server 的 Service 和 Endpoints 变化,然后在每个节点上生成对应的 iptables 或 ipvs 规则,把ClusterIP:Port的流量转发到真实的 Pod IP 上。这一层的问题,特点是“表象正常,实则失效”。
3.1 理解 kube-proxy 的两种工作模式:iptables vs ipvs
kube-proxy 有两种主流模式,选择直接影响性能和可观测性:
| 特性 | iptables 模式 | ipvs 模式 |
|---|---|---|
| 规则生成方式 | 为每个 Service/Endpoint 生成独立的-A KUBE-SERVICES链 | 创建虚拟服务10.96.0.10:443,绑定真实服务器10.233.64.10:443 |
| 连接跟踪开销 | 高(每个连接都需遍历规则链) | 低(内核级哈希查找) |
| 会话保持(SessionAffinity) | 仅支持 ClientIP,且依赖 conntrack | 支持多种算法(rr, lc, dh, sh) |
| 故障排查难度 | 极高(规则链嵌套深,iptables-save输出可达万行) | 中等(ipvsadm -Ln输出清晰) |
在 Ubuntu 22.04 安装 Kubernetes 集群时,如果你用的是 KubeKey 或 kubeadm,默认启用的是 ipvs 模式,因为它对大规模集群更友好。但很多老旧文档仍以 iptables 为例,导致新手在ipvsadm命令找不到时,误以为 kube-proxy 没启动。
3.2 验证 kube-proxy 的状态与模式
先确认 Pod 状态:
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o wide确保所有节点上都有一个 kube-proxy Pod,且READY为1/1。然后查其日志:
kubectl logs -n kube-system kube-proxy-xyzab | head -10关键线索在启动日志里:
- 如果看到
Using ipvs Proxier.,说明是 ipvs 模式; - 如果看到
Using iptables Proxier.,则是 iptables 模式; - 如果看到
F0712 10:23:45.123456 1 server.go:471] failed to load kernel module ip_vs,说明内核未加载 ip_vs 模块,需手动执行modprobe ip_vs && modprobe ip_vs_rr && modprobe ip_vs_wrr && modprobe ip_vs_sh。
3.3 检查 Service 与 Endpoints 的一致性
这是最基础也最容易被忽视的检查。执行:
kubectl get service nginx-svc kubectl get endpoints nginx-svc理想输出:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE nginx-svc ClusterIP 10.96.0.100 <none> 80/TCP 2d NAME ENDPOINTS AGE nginx-svc 10.233.64.10:80,10.233.64.11:80 2d关键点:
ENDPOINTS列必须有 IP:Port,且 IP 必须是 Pod 的真实 IP(可通过kubectl get pods -o wide核对);- 如果
ENDPOINTS为空,说明 Selector 不匹配(Service 的selector标签与 Pod 的labels不一致),或 Pod 处于 NotReady 状态(kubectl get pods中STATUS列不是Running); - 如果
ENDPOINTS有 IP,但curl仍失败,问题一定在 kube-proxy 的规则生成或节点网络上。
3.4 直接检查节点上的转发规则(ipvs 模式)
登录到运行目标 Pod 的节点(比如10.233.64.10所在节点),执行:
# 查看所有虚拟服务 ipvsadm -Ln # 查看特定 ClusterIP 的规则 ipvsadm -Ln | grep 10.96.0.100标准输出应类似:
TCP 10.96.0.100:80 rr -> 10.233.64.10:80 Masq 1 0 0 -> 10.233.64.11:80 Masq 1 0 0rr表示轮询算法;Masq表示使用 NAT 模式(即修改源 IP 为节点 IP);- 两行
->表示两个真实后端,且权重(Weight列)均为 1。
如果这里没有->行,说明 kube-proxy 没有为该 Service 生成规则,原因通常是:Service 的clusterIP字段为None(Headless Service),或 kube-proxy 配置了--proxy-mode=userspace(已废弃)。
3.5 实战排错:iptables 模式下的“隐形丢包”
在一次 Kubernetes 企业项目实战中,客户集群使用 iptables 模式。现象是:从节点 Acurl 10.96.0.100:80成功,但从节点 B 失败。ipvsadm查不到规则(因为是 iptables 模式),于是我们导出规则:
iptables-save > /tmp/iptables.rules在/tmp/iptables.rules中搜索10.96.0.100,找到:
-A KUBE-SERVICES -d 10.96.0.100/32 -p tcp -m comment --comment "default/nginx-svc: cluster IP" -m tcp --dport 80 -j KUBE-SVC-XXXXXX再找KUBE-SVC-XXXXXX链:
-A KUBE-SVC-XXXXXX -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-YYYYYY -A KUBE-SVC-XXXXXX -j KUBE-SEP-ZZZZZZ看起来没问题。但继续看KUBE-SEP-YYYYYY:
-A KUBE-SEP-YYYYYY -s 10.233.64.10/32 -j KUBE-MARK-MASQ -A KUBE-SEP-YYYYYY -p tcp -m tcp -j DNAT --to-destination 10.233.64.10:80问题来了:-s 10.233.64.10/32这条规则,要求源 IP 必须是10.233.64.10才能匹配。而从节点 B 发起的curl,源 IP 是节点 B 的 IP(如192.168.1.100),根本不会进入这条链!真正的规则应该是-m addrtype --src-type LOCAL,表示匹配来自本机的流量。这个错误源于一个自定义的kube-proxy配置补丁,它错误地将--masquerade-all=true与--cluster-cidr=10.233.0.0/16组合使用,导致规则生成逻辑错乱。修复方法是:删除错误的补丁,重启 kube-proxy,并用iptables -t nat -L KUBE-SERVICES -n --line-numbers逐行验证。
这个案例揭示了一个核心原则:Service 层的检查,必须在发起请求的源节点上进行,而不是在控制平面节点上。因为 kube-proxy 的规则是 per-node 的。
4. CNI 插件层:当ping 10.233.64.10通,但curl http://10.233.64.10:80不通时,你在跟谁打架?
CNI(Container Network Interface)插件是 Kubernetes 网络的“地基”,它负责给每个 Pod 分配 IP、设置网络命名空间、配置 veth pair、管理 ARP 表、以及实现跨节点通信。主流插件有 Calico、Cilium、Flannel、Weave。它们的调试方式差异巨大,但底层原理相通:所有流量都必须经过 CNI 插件创建的虚拟网络设备(如caliXXXXX,cni0,lxcXXXXX)。
4.1 识别当前 CNI 插件与版本
首先,确定你用的是哪个插件。查看/etc/cni/net.d/目录:
ls -l /etc/cni/net.d/- 如果看到
10-calico.conflist,则是 Calico; - 如果看到
05-cilium.conf,则是 Cilium; - 如果看到
10-flannel.conflist,则是 Flannel; - 如果看到
10-weave.conf,则是 Weave。
然后查插件进程:
# Calico ps aux | grep calico-node # Cilium ps aux | grep cilium-agent # Flannel ps aux | grep flanneld版本信息至关重要。例如,Calico v3.25 修复了内核 6.2 下的tunl0设备 MTU 错误,而 v3.22 会因此导致大包分片丢失。执行:
# Calico calicoctl version # Cilium cilium version # Flannel flanneld --version4.2 检查 Pod 网络命名空间与 veth 设备
进入一个有问题的 Pod:
kubectl exec -it nginx-pod -- sh执行ip a,你会看到:
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 3: eth0@if4: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1440 qdisc noqueue state UP link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff inet 10.233.64.10/32 scope global eth0 valid_lft forever preferred_lft forever关键信息:
eth0@if4表示这是一个 veth 设备,@if4指向宿主机命名空间中的对端(索引 4);mtu 1440是 Calico 的典型值(比标准 1500 小,为 VXLAN 头留空间);10.233.64.10/32是 Pod IP,掩码/32表示这是一个主机路由,所有流量都需通过网关(即 veth 对端)。
现在退出 Pod,登录到该 Pod 所在的宿主机,执行:
# 查看所有网络命名空间 ls /var/run/netns/ # 找到对应 Pod 的 netns(通常以 pod-<uuid> 命名) ip netns exec <pod-netns-name> ip a # 或者,直接查 veth 对端 ip link | grep -A2 "if4:"你会看到宿主机上有一个名为caliXXXXX的设备,其 MAC 地址与 Pod 内eth0的link/ether一致。这就是 veth pair 的宿主机端。
4.3 验证跨节点通信:ARP 与路由表
Pod 能 ping 通同节点其他 Pod,但 ping 不通跨节点 Pod,问题大概率出在 CNI 的跨节点隧道或路由上。
首先,在源 Pod 所在节点,查路由表:
ip route get 10.233.65.20假设目标 Pod IP 是10.233.65.20(属于另一个节点的 Pod CIDR),正确输出应为:
10.233.65.20 via 192.168.1.200 dev eth0 src 192.168.1.100 uid 0via 192.168.1.200表示下一跳是目标节点的物理 IP;dev eth0表示走eth0网卡;src 192.168.1.100是本节点物理 IP。
如果输出是10.233.65.20 dev caliXXXXX scope link,说明路由认为目标 IP 在本地,但实际不在,这是典型的Pod CIDR重叠或 CNI 配置错误。
然后查 ARP 表:
ip neigh show | grep 192.168.1.200应该看到类似:
192.168.1.200 dev eth0 lladdr aa:bb:cc:dd:ee:ff REACHABLE如果状态是FAILED或INCOMPLETE,说明无法通过 ARP 获取目标节点的 MAC 地址,原因可能是:
- 目标节点防火墙(
ufw或iptables)阻止了 ARP 请求; - 云厂商安全组未放行 ICMP 和 ARP;
calico-node或cilium-agent未运行,导致 BGP 或 VXLAN 隧道未建立。
4.4 实战排错:Calico 的tunl0设备与 MTU 不匹配
在 Ubuntu 22.04 安装 Kubernetes 集群时,我们使用 Calico v3.22。现象是:小包(ping -s 100)跨节点通,大包(ping -s 1400)不通,curl直接超时。tcpdump在源节点抓包发现:
- SYN 包发出,大小 1500 字节;
- SYN-ACK 包返回,大小 1500 字节;
- 但目标 Pod 的
tcpdump只收到 SYN,没收到 SYN-ACK。
这说明中间某个环节进行了分片,而接收方无法重组。查tunl0设备:
ip link show tunl0输出:
5: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0mtu 1440是正确的。但再查物理网卡eth0:
ip link show eth0输出:
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:11:22:33:44:55 brd ff:ff:ff:ff:ff:ffmtu 1500。问题就在这里:VXLAN 封装需要额外 50 字节头(UDP + VXLAN + Ethernet),所以tunl0的 MTU 必须比eth0小至少 50。1440 = 1500 - 60,看似合理。但内核 6.2 的ipip模块计算有偏差,实际需要1420。解决方案是:手动调整tunl0MTU:
ip link set tunl0 mtu 1420并永久生效:在 Calico 的InstallationCRD 中添加:
spec: calicoNetwork: mtu: 1420这个细节,任何“Kubernetes 面试”题库都不会考,但它决定了你的集群能否承载视频流或大文件上传。
5. 节点网络层:当curl http://10.233.64.10:80在宿主机上成功,但在 Pod 内失败时,防火墙在搞鬼
最后一层,也是最容易被忽略的一层:宿主机自身的网络栈。Linux 内核的netfilter(iptables/nftables)、conntrack、sysctl网络参数、以及云厂商的安全组,共同构成了 Pod 流量的“守门人”。这一层的问题,特点是“Pod 内部一切正常,但流量就是出不去”。
5.1 检查 conntrack 表溢出
conntrack是内核维护的连接跟踪表,记录所有 NAT 连接的状态。当表满时,新连接会被丢弃,表现为curl随机超时。检查:
# 查看当前连接数 conntrack -L | wc -l # 查看最大容量 sysctl net.netfilter.nf_conntrack_max # 查看当前使用率 conntrack -S在高并发场景下,nf_conntrack_max默认值(通常 65536)很容易被耗尽。解决方案是:
# 临时增大 sysctl -w net.netfilter.nf_conntrack_max=131072 # 永久生效,写入 /etc/sysctl.conf echo "net.netfilter.nf_conntrack_max=131072" >> /etc/sysctl.conf sysctl -p注意:增大
nf_conntrack_max会消耗更多内存(每个连接约 300 字节),需按节点内存比例设置。
5.2 验证 iptables/nftables 规则链
Ubuntu 22.04 默认使用nftables后端,但很多 Kubernetes 文档仍教iptables命令。执行:
# 查看当前使用的后端 update-alternatives --display iptables # 如果是 nftables,用以下命令查规则 nft list ruleset | grep -A10 "kubernetes"重点检查FORWARD链,它控制节点间流量:
nft list chain inet filter FORWARD你应该看到类似规则:
chain FORWARD { type filter hook forward priority filter; policy accept; meta l4proto tcp tcp dport 6443 ct state established,related accept meta l4proto tcp tcp dport 80 ct state established,related accept ... }如果policy是drop,且没有明确的accept规则放行 Pod 流量,那么所有跨节点通信都会被拦截。修复方法是:在nftables配置中添加:
# 允许来自 Pod CIDR 的流量 ip saddr 10.233.0.0/16 counter accept # 允许转发到 Pod CIDR 的流量 ip daddr 10.233.0.0/16 counter accept5.3 检查 sysctl 网络参数
几个关键参数必须开启,否则 CNI 插件无法工作:
# 必须为 1,允许 IP 转发 sysctl net.ipv4.ip_forward # 必须为 1,允许非本地 IP 的数据包进入 sysctl net.bridge.bridge-nf-call-iptables # 必须为 1,允许桥接流量被 iptables 处理 sysctl net.bridge.bridge-nf-call-ip6tables在 Ubuntu 22.04 上,bridge-nf-call-iptables默认为0,这会导致 Calico 的caliXXX设备流量绕过 iptables,从而无法被 kube-proxy 规则捕获。永久修复:
echo "net.bridge.bridge-nf-call-iptables=1" >> /etc/sysctl.conf echo "net.bridge.bridge-nf-call-ip6tables=1" >> /etc/sysctl.conf sysctl -p5.4 云厂商安全组与 VPC 路由
如果你的集群部署在 AWS、阿里云或腾讯云上,安全组(Security Group)是第一道防线。必须确保:
- 所有节点的安全组,入站规则放行
TCP:6443(API Server)、TCP:10250(kubelet)、UDP:8472(VXLAN)、TCP/UDP:30000-32767(NodePort); - VPC 路由表中,
Pod CIDR(如10.233.0.0/16)必须指向集群的主节点或 Transit Gateway。
一个经典错误是:在创建节点时,忘记将Pod CIDR添加到安全组的入站规则中,导致calico-node的 BGP 会话无法建立,ip route看不到跨节点路由。
6. 一套完整的检查清单与自动化脚本
把以上所有检查点,浓缩成一份可执行的清单,并附上一个一键诊断脚本,这是 Kubernetes 工程师的终极武器。
6.1 手动检查清单(按优先级排序)
| 步骤 | 检查项 | 命令 | 预期结果 | 失败含义 |
|---|---|---|---|---|
| 1 | CoreDNS Pod 状态 | kubectl get pods -n kube-system -l k8s-app=kube-dns | READY=1/1,RESTARTS=0 | CoreDNS 宕机或配置错误 |
| 2 | DNS 解析测试 | kubectl exec <pod> -- nslookup nginx-svc.default.svc.cluster.local | 返回10.96.0.100 | DNS 层故障 |
| 3 | Service & Endpoints | kubectl get svc nginx-svc && kubectl get endpoints nginx-svc | ENDPOINTS列有 IP | Service 选择器不匹配或 Pod NotReady |
| 4 | kube-proxy 模式 | `kubectl logs -n kube-system kube-proxy-xxx | head -5` | Using ipvs Proxier.或Using iptables Proxier. |
| 5 | 节点转发规则 | ipvsadm -Ln | grep 10.96.0.100(ipvs) 或iptables -t nat -L KUBE-SERVICES -n | grep 10.96.0.100(iptables) | 有对应规则 | kube-proxy |
