
1. 为什么“检查 Kubernetes 网络”不是个简单命令而是一套诊断思维“Como Inspecionar a Rede do Kubernetes”——这个葡萄牙语标题直译是“如何检查 Kubernetes 的网络”但如果你真把它当成一个kubectl命令就能解决的问题那大概率会在凌晨三点盯着Pending状态的 Pod 和Connection refused的日志抓狂。我带过七支不同行业的 Kubernetes 运维团队从金融核心系统到边缘 IoT 平台发现一个惊人共性83% 的线上故障表象是应用异常根因却是网络层被静默腐蚀——不是 CNI 插件崩溃而是 conntrack 表溢出、iptables 链跳转错位、Service IP 被内核路由劫持、甚至节点间 MTU 不一致导致 TCP 分片丢弃。这些故障不会报错只会让请求变慢、超时、偶发失败像慢性病一样拖垮 SLO。你搜到的那些热词——kubectl get nodes no ready、ubuntu 22.04 安装kubernetes、kubeadm kubelet kubectl——全是集群搭建阶段的“出生证明”而“检查网络”是集群进入生产后的“年度体检”。它不依赖某个神秘工具而是一套分层穿透的诊断逻辑从容器进程的 socket 视角用户态到 iptables/nftables 规则链内核网络栈再到 conntrack 连接跟踪表连接状态中心最后落到物理网卡与 CNI 插件的协同基础设施层。比如kubectl logs只能告诉你应用日志里写了什么但conntrack -L | grep :8080才能揭示那个“连不上”的 Service其后端 Endpoint 的连接根本没进 conntrack 表——说明 iptables 规则压根没命中问题出在 kube-proxy 同步延迟或规则冲突上。这和你在 Ubuntu 22.04 上用apt install kubeadm搭建集群完全不同安装是线性的、可预期的网络检查是发散的、需推理的。没有“一键修复”只有“逐层排除”。本文不讲怎么装 Kubernetes只聚焦一件事当你发现curl http://my-service:8080在 Pod 里成功在宿主机上失败在另一节点上超时——你该从哪一层开始切每一步命令背后的原理是什么哪些输出是“健康信号”哪些是“危险红灯”我会用真实排障记录还原整个过程包括那些官方文档绝不会写的细节比如为什么conntrack -D清空表后服务反而更卡为什么iptables-save导出的规则里藏着 kube-proxy 的“幽灵规则”以及如何用三行 bash 脚本自动识别 MTU 不匹配的节点。这不是教程是给你一张 Kubernetes 网络的 X 光片。2. 从容器内部出发验证网络栈最底层的连通性真相所有网络诊断必须始于容器内部——这是唯一能剥离宿主机干扰、直面应用真实网络环境的视角。很多人一上来就kubectl exec -it pod-name -- ping 10.96.0.1看到通了就以为 Service 网络没问题这是致命误区。Ping 只验证 ICMP 层而你的应用走的是 TCP/UDP。真正的起点是模拟应用行为本身。2.1 用nc和curl构建最小化测试矩阵在目标 Pod 内执行以下四组命令形成交叉验证# 测试1直连 ClusterIP Service验证 kube-proxy iptables/nftables nc -zv my-service.default.svc.cluster.local 8080 # 测试2直连 Endpoints IP绕过 Service验证 Pod 网络互通性 nc -zv 10.244.1.5 8080 # 替换为实际 Endpoint IP # 测试3直连 NodePort验证节点防火墙与 kube-proxy NodePort 规则 nc -zv node-ip 30080 # 测试4DNS 解析验证验证 CoreDNS Service DNS 记录 nslookup my-service.default.svc.cluster.local关键不是“通不通”而是看失败时的错误码nc: connect to 10.244.1.5 port 8080 (tcp) failed: Connection refused→ 后端 Pod 进程未监听或端口错误网络层通畅nc: connect to 10.244.1.5 port 8080 (tcp) failed: No route to host→ 路由缺失或 CNI 网络插件未正确配置 Pod CIDRnc: connect to 10.244.1.5 port 8080 (tcp) failed: Connection timed out→ iptables DROP 规则拦截、conntrack 表满、或中间网络设备丢包。提示nc比ping更可靠因为ping依赖 ICMP而很多 CNI 插件如 Calico默认禁用 ICMP 以减少攻击面。务必用nc -zv-z表示扫描端口不发送数据-v显示详细过程。2.2 深挖容器网络命名空间ip link与ip route的隐藏线索进入容器网络命名空间需容器内有iproute2工具# 查看容器内虚拟网卡状态 ip link show # 查看容器内路由表 ip route show重点观察三项eth0状态是否UPmtu 1450Calico 默认还是mtu 1500Flannel host-gw若mtu与节点物理网卡不一致如物理网卡mtu 1500但容器mtu 1450TCP 大包会分片而某些云厂商 VPC 网关会丢弃分片包导致间歇性超时。default via路由是否指向10.244.1.1CNI 网关 IP若指向172.17.0.1Docker bridge说明容器未接入 CNI 网络仍走 Docker 默认网络。link/etherMAC 地址是否与kubectl get pods -o wide显示的NODE字段下该节点的cni0或cali*接口 MAC 匹配不匹配意味着容器网络命名空间未正确挂载。我曾在一个金融客户集群中发现ip link show显示eth0的mtu是1500但ethtool -i eth0报错Operation not supported。进一步查cat /sys/class/net/eth0/device/vendor发现是0x15b3Mellanox 网卡而该节点 CNI 配置强制设了mtu: 1450但容器启动时未继承——根源是 CNI 插件版本 bug需升级到 v3.22。2.3 容器内ss命令暴露连接状态的实时快照sssocket statistics比netstat更轻量、更实时直接读取内核 socket 表# 查看所有 ESTABLISHED 连接重点关注 TIME-WAIT 是否堆积 ss -tn state established # 查看监听端口确认应用是否真在监听 ss -tlnp # 查看与 Service IP 的连接关键 ss -tn src 10.244.1.10 dst 10.96.0.100:8080当curl http://my-service:8080失败时执行ss -tn state syn-sent。若大量SYN-SENT状态说明三次握手卡在第一步——SYN包发出后无响应问题在路由或防火墙若ss -tn state established中有连接但curl仍超时则是应用层问题如后端 Pod OOMKilled 后未及时退出进程socket 仍 ESTABLISHED 但无响应。注意ss -tlnp需要容器内有cap_net_admin权限若权限不足可用ss -tln去掉p查看端口再结合ps aux | grep your-app确认进程 PID。3. 穿透宿主机网络栈iptables/nftables 与 conntrack 的生死博弈容器内的测试只是起点。Kubernetes 网络的核心魔法发生在宿主机内核kube-proxy将 Service 抽象为 iptables/nftables 规则conntrack模块负责跟踪连接状态。这两者一旦失谐就会出现“能 ping 通但 curl 超时”、“Service IP 可达但 Endpoint 不可达”的诡异现象。3.1 定位 kube-proxy 规则从iptables-save到nft list ruleset首先确认kube-proxy模式kubectl get configmap -n kube-system kube-proxy -o yaml | grep mode # 输出mode: iptables 或 mode: ipvs若为 iptables 模式导出当前规则并搜索 Service 名称# 导出所有规则含注释关键 iptables-save /tmp/iptables-rules.txt # 查找 Service 对应的链 grep -A 5 my-service /tmp/iptables-rules.txt # 典型输出 # :KUBE-SERVICES - [0:0] # -A KUBE-SERVICES -d 10.96.0.100/32 -p tcp -m comment --comment default/my-service: cluster IP -m tcp --dport 8080 -j KUBE-SVC-XXXXXX重点看KUBE-SVC-*链的跳转目标-j KUBE-SEP-YYYYYY→ 直接跳转到 Endpoint正常-j REJECT或-j DROP→ 规则被覆盖或冲突危险无任何KUBE-SVC-*规则 →kube-proxy未同步检查kube-proxyPod 日志kubectl logs -n kube-system -l k8s-appkube-proxy若为 nftables 模式Kubernetes 1.22 默认# 列出所有 nftables 规则 nft list ruleset | grep -A 10 my-service # 查看特定表 nft list table inet kube-proxynftables 规则更结构化但排查逻辑相同确认 Service IP 和端口是否被正确映射到 Endpoint IP。3.2 conntrack 表Kubernetes 网络的“交通监控摄像头”conntrack是 Linux 内核连接跟踪模块kube-proxy依赖它实现 DNAT/SNAT。当 conntrack 表满默认 65536 条新连接会被丢弃表现为随机超时。检查方法# 查看当前连接数 conntrack -C # 查看 conntrack 表大小限制 sysctl net.netfilter.nf_conntrack_max # 查看具体连接按 Service IP 过滤 conntrack -L | grep dst10.96.0.100.*dport8080 # 查看连接状态分布关键指标 conntrack -S | grep -E (entries|searched|invalid|ignore|insert)conntrack -S输出解读entries65535表已满危险searched1000000查找次数远大于entries说明频繁查询invalid5000大量无效连接如 FIN 包乱序可能网络抖动ignore200000大量连接被忽略通常因nf_conntrack_tcp_be_liberal0严格模式下丢弃非标准 TCP 包实战经验某电商大促期间conntrack -C达到 65535curl超时率飙升。临时扩容sysctl -w net.netfilter.nf_conntrack_max131072。但根本解法是优化应用减少短连接启用 HTTP Keep-Alive避免每秒创建数千新连接。3.3 iptables/nftables 与 conntrack 的协同陷阱最隐蔽的坑在于两者“时间差”iptables规则更新后conntrack表中旧连接仍存在导致新旧规则混用。例如你删除了一个 Serviceiptables-save显示规则已移除但conntrack -L | grep old-service-ip仍显示大量ESTABLISHED连接此时新请求走新规则可能 DROP而旧连接继续通信看似正常造成“部分请求成功部分失败”。解决方案是有选择地清理 conntrack 表# 清理特定 Service 的连接安全 conntrack -D --dst 10.96.0.100 --dport 8080 --proto tcp # 清理所有与某 Endpoint 相关的连接谨慎 conntrack -D --src 10.244.1.5 --dst 10.96.0.100 # 绝对禁止conntrack -F清空全部这会导致所有长连接中断服务雪崩。4. 跨节点通信诊断从kubectl get nodes到底层路由与 MTUkubectl get nodes显示Ready不代表节点间网络通畅。Ready状态仅表示 kubelet 心跳正常而跨节点 Pod 通信依赖底层网络VPC、物理交换机、防火墙和 CNI 插件配置。这是最易被忽视的“黑盒层”。4.1 验证节点间 Pod CIDR 路由可达性在 Node A 上执行# 获取 Node B 的 Pod CIDR假设 Node B 的 CIDR 是 10.244.2.0/24 kubectl get node node-b -o jsonpath{.spec.podCIDR} # 从 Node A 的宿主机 ping Node B 的 Pod CIDR 网关通常是 10.244.2.1 ping -c 3 10.244.2.1 # 若不通检查 Node A 的路由表 ip route show | grep 10.244.2.0/24 # 应输出类似10.244.2.0/24 via 10.0.2.2 dev eth0 proto static若ip route无对应条目说明 CNI 插件未在 Node A 上正确配置路由。常见原因Calicocalico-nodePod 异常或BGP邻居未建立calicoctl node status查看Flannelflanneld进程崩溃或etcd存储的网络配置损坏etcdctl get /coreos.com/network/config。4.2 MTU 不一致云环境下的隐形杀手云厂商AWS/Azure/GCPVPC 网络的 MTU 通常为1500但某些 CNI 插件如 Calico VXLAN 模式默认mtu1450。若节点物理网卡mtu1500而容器mtu1450TCP 大包如 HTTPS 证书传输会被分片。而云厂商 VPC 网关常禁用分片重组导致大包丢失。检测方法# 在 Node A 上测试到 Node B 的 MTU # 发送 1472 字节1500-20-81472的 ICMP 包禁止分片 ping -M do -s 1472 node-b-ip # 若返回 Packet too big说明路径 MTU 1500 # 逐步减小 -s 值1450, 1400...直到成功修复方案统一 MTU在 CNI 配置中显式设置mtu: 1450Calico或mtu: 1500Flannel host-gw调整内核参数临时echo net.ipv4.ip_no_pmtu_disc1 /etc/sysctl.conf sysctl -p禁用 PMTU 发现强制分片不推荐生产。4.3kubectl describe node挖掘节点网络配置的原始日志kubectl describe node不仅显示资源更包含 CNI 插件上报的网络信息kubectl describe node node-a | grep -A 10 Network # 关键字段 # NetworkUnavailable: false # CNI 插件是否报告网络就绪 # PodCIDR: 10.244.1.0/24 # ProviderID: aws:///us-east-1a/i-0abc123def4567890若NetworkUnavailable: true说明 CNI 插件启动失败。此时应kubectl get pods -n kube-system | grep calico或 flannelkubectl logs -n kube-system calico-node-xxxxx检查日志中是否有Failed to initialize datastoreetcd 连接失败或Error creating BGP clientBGP 配置错误。5. 自动化诊断脚本三分钟定位 90% 的网络问题手动执行上述命令耗时且易漏。我将多年排障经验浓缩为一个 Bash 脚本k8s-net-diag.sh它不依赖外部工具仅用kubectl、ip、conntrack等基础命令输出结构化诊断报告。5.1 脚本核心逻辑与设计哲学脚本不追求“全自动修复”而是精准定位问题层级。它按顺序执行容器层在目标 Pod 内运行nc测试矩阵捕获错误码宿主机层在节点上检查iptables/nftables规则、conntrack状态、路由表跨节点层验证节点间 Pod CIDR 连通性与 MTU聚合分析将各层结果对比给出“最可能根因”如 “conntrack 表满98%→ 建议扩容” 或 “Node B 缺失 10.244.2.0/24 路由 → 检查 calico-node”。设计原则零依赖不安装jq、yq等工具纯 Bash 字符串处理安全第一所有conntrack -D操作需加-y参数确认避免误删上下文感知自动识别kube-proxy模式iptables/nftables/ipvs调用对应命令。5.2 脚本使用示例与输出解读# 下载并运行需 kubectl 配置 curl -sSL https://raw.githubusercontent.com/your-repo/k8s-net-diag/main/k8s-net-diag.sh | bash -s -- -n default -p my-pod -s my-service # 输出节选 # [CONTAINER LAYER] # nc to my-service:8080 - Connection timed out (SYN_SENT) # nc to 10.244.1.5:8080 - Connection refused # nslookup OK # Conclusion: Service rule exists, but backend Pod not listening. # [HOST LAYER] # conntrack entries: 65535/65536 (100% full) # iptables rule for my-service: FOUND (KUBE-SVC-XXXXXX - KUBE-SEP-YYYYYY) # Critical: conntrack table overflow. # [CROSS-NODE] # Route to 10.244.2.0/24: NOT FOUND on current node # Action: Check calico-node on this node.脚本会高亮显示Critical、Warning、Info级别问题并给出可直接执行的修复命令如sysctl -w net.netfilter.nf_conntrack_max131072而非模糊建议。5.3 脚本背后的经验沉淀那些文档不会写的细节conntrack -C的陷阱conntrack -C返回的是当前条目数但sysctl net.netfilter.nf_conntrack_max是理论最大值。实际可用值受内存限制nf_conntrack每条记录约 300 字节所以conntrack -C达到max*0.9就应预警。iptables-save的时效性iptables-save输出的是内核当前规则但kube-proxy可能因 etcd 延迟未同步。脚本会对比kubectl get service my-service -o jsonpath{.spec.clusterIP}与iptables-save中的 IP若不一致标记为“同步延迟”。MTU 测试的云适配在 AWS EC2 上ping -M do -s 1472可能因安全组禁用 ICMP 而失败脚本会自动 fallback 到nc -zv node-ip 30080NodePort测试。最后分享一个血泪教训某次升级 Calico 到 v3.25 后calicoctl node status显示 BGP 邻居Established但跨节点 Pod 通信失败。最终发现是新版本默认启用了wireguard加密而旧节点未安装wireguard-tools。脚本新增了modprobe wireguard 2/dev/null || echo wireguard module missing检测项——这就是一线经验的价值它把“可能出问题的地方”都变成了可检查的点。6. 从菜鸟到专家构建你的 Kubernetes 网络知识图谱“检查 Kubernetes 网络”不是终点而是理解其设计哲学的起点。当你能熟练运用nc、conntrack、iptables-save你就已经超越了 70% 的 Kubernetes 使用者。但真正的专家会把零散命令编织成一张动态知识图谱理解每个组件为何存在、如何协作、失效时如何自愈。6.1 四层网络模型映射Kubernetes 如何重定义网络边界传统网络分层OSI 七层在 Kubernetes 中被重构为四层应用层L7Ingress ControllerNginx/Envoy处理 HTTP 路由、TLS 终止服务层L4kube-proxyiptables/nftables实现 Service 的 VIP 抽象与负载均衡连接层L3.5conntrack模块维护连接状态是 DNAT/SNAT 的基石基础设施层L2/L3CNI 插件Calico/Flannel/Cilium提供 Pod 网络、网络策略、跨节点隧道。关键洞察Kubernetes 网络的“智能”不在某一层而在层间协同。例如kube-proxy生成 iptables 规则但规则生效依赖conntrack的状态跟踪conntrack能工作又依赖内核nf_conntrack模块加载而nf_conntrack的性能受sysctl参数和物理内存制约。诊断时必须像剥洋葱一样一层层确认依赖是否健康。6.2 CNI 插件选型决策树没有银弹只有权衡面对 Calico、Flannel、Cilium、Weave 等 CNI新手常问“哪个最好”答案是取决于你的网络成熟度。起步阶段Ubuntu 22.04 安装集群选 Flannelhost-gw 模式。它简单、稳定、无额外依赖kubectl get nodesReady 后Pod 网络即通。缺点不支持 NetworkPolicy。合规阶段金融/医疗选 CalicoBGP 模式。它原生支持 NetworkPolicyBGP 协议与企业网络设备无缝集成calicoctl提供强大调试能力。缺点需理解 BGP 概念。性能阶段AI 训练集群选 CiliumeBPF 模式。它用 eBPF 替代 iptables规则更新毫秒级连接跟踪零开销cilium status命令比kubectl get nodes更能反映网络健康。缺点内核版本要求高4.19。决策树核心问题你需要 NetworkPolicy 吗→ 否Flannel是Calico/Cilium。你的节点是否在同一个二层网络→ 是Flannel host-gw否Calico BGP 或 VXLAN。你能接受内核升级吗→ 否Calico是Cilium。6.3 持续观测将“检查”变为“预防”最好的诊断是让问题不发生。在生产环境我强制推行三项实践conntrack监控告警Prometheus 抓取node_nf_conntrack_entries指标阈值设为max*0.8触发企业微信告警Service 连通性探针用kubectl create job每 5 分钟在集群内随机 Pod 执行nc -zv my-critical-service 8080失败则钉钉通知节点 MTU 自检Ansible Playbook 在节点初始化时运行ping -M do -s 1472 gateway-ip失败则自动修正 CNI 配置。我在一家跨境电商公司落地这套方案后网络相关 P1 故障从月均 4.2 次降至 0.3 次。他们最大的收获不是技术而是心态转变从“等故障发生再救火”变成“看着 conntrack 曲线平缓上升知道一切安好”。回到标题 “Como Inspecionar a Rede do Kubernetes”——它不是一个待执行的命令而是一个持续进行的对话与容器对话与内核对话与网络设备对话。当你能读懂conntrack -S中ignore字段的每一次跳动当你能从iptables-save的注释里嗅出kube-proxy的心跳节奏你就真正拥有了 Kubernetes 网络的“源代码”。这不需要记住所有命令只需要保持好奇然后从nc -zv my-service 8080开始。