Appearance
CNI 与 Pod 网络
CNI 负责把 Pod 接入集群网络。Kubernetes 只定义网络模型的要求:每个 Pod 有独立 IP、Pod 之间可以互通、Service 提供稳定入口。至于 IP 从哪分、跨节点怎么转发、策略怎么拦截、隧道怎么封装——全部交给 CNI 插件处理。
这块容易混淆,因为它同时涉及 Linux 网络、Kubernetes 资源对象和具体 CNI 实现。排查时把链路拆开:Pod 自己有没有 IP → 同节点 Pod 通不通 → 跨节点 Pod 通不通 → Service 通不通 → DNS 解析正不正常。逐一验证,不要混在一起。
K8s 网络模型的基本要求
| 要求 | 说明 |
|---|---|
| 每个 Pod 有独立 IP | Pod 内容器共享同一个 network namespace |
| Pod 之间可互通 | 同节点和跨节点 Pod 都能直接访问 Pod IP |
| Node 能访问 Pod | 节点能访问本机和跨节点 Pod |
| Service 提供稳定入口 | Pod IP 变化后,Service 名称和 ClusterIP 不变 |
Pod IP 是集群内地址,外部访问不走 Pod IP,而是走 LoadBalancer、Gateway、Ingress、NodePort 或云负载均衡。
同一 Pod 内容器共享网络命名空间,localhost 就能互访。不同 Pod 即使在同一台节点上,也不在同一网络命名空间——访问必须走 Pod IP 或 Service。
Pod 到 Pod 的链路
同节点 Pod 通信:
跨节点多了一段节点间转发:
这里的"路由或隧道"由 CNI 决定。Flannel 常见 VXLAN,Calico 可以用 IPIP、VXLAN 或 BGP,Cilium 用 eBPF 数据面。
排查时分清三件事:
| 验证对象 | 看什么 |
|---|---|
| Pod IP | Pod 是否拿到 IP,跨节点 Pod IP 是否互通 |
| Service | ClusterIP 到 EndpointSlice 是否正常 |
| DNS | 服务名是否能解析到正确 ClusterIP |
Pod IP 不通和 Service 不通不是一回事。Pod IP 不通偏向 CNI、路由、隧道、防火墙;Pod IP 通但 Service 不通,问题在 kube-proxy、EndpointSlice、Service selector 或端口。
常见 CNI
| 插件 | 特点 | 场景 |
|---|---|---|
| Flannel | 简单,主要解决跨节点通信 | 实验、小集群 |
| Calico | BGP/VXLAN/IPIP、NetworkPolicy 成熟 | 传统机房和通用生产集群 |
| Cilium | eBPF 数据面、Hubble 可观测性、策略和 Gateway 能力强 | 新集群,需要强网络观测和安全能力 |
传统机房里 Calico 很常见——它对 BGP、IPIP、VXLAN 这些模式都支持得比较成熟。新集群如果网络团队能一起维护,Cilium 值得评估,它把排查方式带到 eBPF、Hubble 和策略可视化体系里。
Pod CIDR 和 Service CIDR
K8s 集群有两个网段必须提前规划:
| 网段 | 作用 | 示例 |
|---|---|---|
| Pod CIDR | 给 Pod 分配 IP | 10.244.0.0/16 |
| Service CIDR | 给 ClusterIP 分配 IP | 10.96.0.0/12 |
这两个网段需要避开公司内网、VPN、Docker 默认网段、云 VPC 网段。网段冲突时现象经常不是"全部断",而是部分地址路由异常——集群里访问公司某个网段走了 Pod 路由,或者 VPN 连上后某些 Service 解析出来 IP 能通但端口不通。
Calico 的三种模式
| 模式 | 说明 | 关注点 |
|---|---|---|
| IPIP | Pod 流量封装进 IPIP 包跨节点传输 | 底层网络不感知 Pod 路由,注意 MTU |
| VXLAN | VXLAN 隧道封装跨节点流量 | 云和跨三层网络常见,注意 UDP 4789 |
| BGP | 节点之间或和交换机通过 BGP 分发 Pod 路由 | 性能好,但依赖网络设备配合 |
隧道模式的好处是底层网络不用知道 Pod 网段——宿主机之间先包一层再发。代价是多一层封装,MTU 配不好时大包异常。BGP 模式把 Pod 网段直接告诉网络设备,更直接,但需要交换机或路由器配合。
MTU、防火墙和 conntrack
CNI 网络问题里,MTU 很容易被忽略。VXLAN、IPIP 封装会增加额外头部,原本 1500 的包封装后可能超过底层 MTU。表现通常是小包通、大包不通,或者 TCP 握手成功但传大响应时卡住。
防火墙除了 TCP 端口,还要看协议类型:
| 类型 | 关注 |
|---|---|
| VXLAN | UDP 4789 |
| IPIP | IP 协议号 4 |
| BGP | TCP 179 |
| kube-apiserver | TCP 6443 |
| NodePort | TCP/UDP 30000-32767 |
conntrack 表满时,Service 访问出现间歇失败:
bash
sysctl net.netfilter.nf_conntrack_max
conntrack -S
dmesg | grep -i conntrack接口突然超时、Service 访问随机失败、节点日志出现 nf_conntrack: table full 时,问题不在 Deployment YAML 上,要看节点连接跟踪和短连接数量。
跨节点不通排查
bash
kubectl get pods -A -o wide
kubectl get nodes -o wide
kubectl run net-test --rm -it --image=busybox:1.36 --restart=Never -- sh
# Pod 内
ping <other-pod-ip>
nc -vz <service-name> <port>
nslookup <service-name>.<namespace>.svc.cluster.local节点上看:
bash
ip route
iptables-save | grep -E 'CALI|CILIUM|FLANNEL|KUBE' | head -50| 现象 | 判断方向 |
|---|---|
| 新 Pod 没 IP | CNI 插件异常、IP 池耗尽、kubelet 调 CNI 失败 |
| 同节点通,跨节点不通 | 隧道、防火墙、路由、BGP、MTU |
| Pod IP 通,Service 不通 | kube-proxy、EndpointSlice、selector、端口名 |
| Service 通,域名不通 | CoreDNS、搜索域、NetworkPolicy |
| 小包通,大包卡 | MTU、封装、中间设备 |
| 间歇性失败 | conntrack、节点压力、CNI Agent 重启 |
Cilium 集群可以用 Hubble 直接看流量路径和丢包点;Calico 集群更常看 IPPool、BGP、felix 日志和节点路由。CNI 不同,排查入口也会变——只靠 kubectl describe pod 看不到底层网络问题。