主题
Kubernetes 全链路深入解析:Pod → Service → DNS → iptables → 内核
目标读者:Kubernetes 高级运维、SRE、网络工程师、DevOps
前置知识:Kubernetes 基础、Linux 网络、iptables、DNS 基础
教材版本:v1.0
目录
- 全链路总览
- Pod 网络创建过程
- CNI 与数据链路层
- Service 与 Endpoints 机制
- kube-proxy 与 iptables/ipvs
- DNS 解析全链路
- 内核数据包流转:从 Pod 到 Pod
- 外部访问全链路
- NodeLocal DNSCache 全链路
- Calico + iptables 全链路
- 故障排查方法论
- 性能热点与优化
- 附录:全链路命令速查
第1章 全链路总览
1.1 什么是 Kubernetes 网络全链路
Kubernetes 网络全链路是指:从应用发起一个请求开始,经过 Pod、Service、DNS、kube-proxy、iptables/ipvs、CNI、网卡、内核协议栈,最终到达目标 Pod 或外部网络的完整路径。
1.2 全链路核心组件
┌─────────────────────────────────────────────────────────────────┐
│ Kubernetes Cluster │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────────┐ │
│ │ Pod │───>│ Service │───>│ DNS │───>│ kube-proxy │ │
│ │ App │ │ ClusterIP│ │ CoreDNS │ │ iptables/ipvs│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ └──────┬──────┘ │
│ │ │ │ │ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Linux Kernel Netfilter / IPVS │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ CNI Plugin (Calico/Flannel/Cilium) │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Physical NIC / vSwitch / Overlay │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘1.3 一次完整请求的全链路
以 Pod A 访问 http://web-service.default.svc.cluster.local:80 为例:
Pod A 应用
│
│ 1. DNS 查询域名
▼
CoreDNS / NodeLocal DNSCache
│
│ 2. 返回 ClusterIP 10.96.123.45
▼
Pod A 内核
│
│ 3. 发起 TCP 连接到 10.96.123.45:80
▼
kube-proxy iptables/ipvs 规则
│
│ 4. DNAT/负载均衡到 Pod B:8080
▼
CNI 网络
│
│ 5. 跨节点或同节点转发
▼
Pod B 容器
│
│ 6. 处理请求并返回
▼
原路返回第2章 Pod 网络创建过程
2.1 Pod 创建流程
用户创建 Pod
│
▼
API Server 接收请求
│
▼
Scheduler 选择节点
│
▼
kubelet 在节点上创建 Pod
│
├─ 创建 pause 容器(网络命名空间)
├─ 调用 CNI 插件配置网络
└─ 启动业务容器2.2 CNI 调用过程
kubelet 根据 --cni-bin-dir 和 --cni-conf-dir 调用 CNI 插件:
bash
# CNI 配置目录
/etc/cni/net.d/
# CNI 插件目录
/opt/cni/bin/CNI 插件收到 ADD 命令后:
- 为 Pod 创建 veth pair
- 一端放入 Pod 网络命名空间(eth0)
- 另一端连接到宿主机网络(bridge/tunl0/cali*)
- 分配 IP 地址
- 配置路由
2.3 veth pair 与网络命名空间
Pod Network Namespace
┌─────────────────────────┐
│ eth0: 10.244.1.10/24 │
│ ↑ │
│ │ veth pair │
│ ↓ │
│ veth xxxxxx │
└───────┬─────────────────┘
│
▼
Host Network Namespace
┌─────────────────────────┐
│ veth yyyyyy │
│ ↑ │
│ │ │
│ docker0 / cni0 │
│ 或 cali* 接口 │
└─────────────────────────┘2.4 查看 Pod 网络配置
bash
# 查看 Pod 所在节点和 IP
kubectl get pod <pod> -o wide
# 进入 Pod 网络命名空间(在节点上执行)
nsenter -t <pause-pid> -n ip addr
nsenter -t <pause-pid> -n ip route
nsenter -t <pause-pid> -n cat /etc/resolv.conf
# 查看宿主机上的 veth 接口
ip link show
ethtool -S eth0 # 在 Pod 内执行,查看对端接口第3章 CNI 与数据链路层
3.1 常见 CNI 插件对比
| CNI | 数据链路 | 特点 |
|---|---|---|
| Flannel | VXLAN / UDP / host-gw | 简单,适合中小规模 |
| Calico | BGP / IPIP / VXLAN | 高性能,支持网络策略 |
| Cilium | eBPF / VXLAN | 可观测性强,性能优秀 |
| Weave | VXLAN | 易用,去中心化 |
| Canal | Flannel + Calico | 组合方案 |
3.2 Flannel VXLAN 模式
Pod A (10.244.1.10) Pod B (10.244.2.10)
│ │
▼ ▼
cni0 (10.244.1.1) cni0 (10.244.2.1)
│ │
▼ ▼
flannel.1 (VTEP) ────── VXLAN ──────> flannel.1 (VTEP)
│ │
▼ ▼
eth0 (Node-1) 物理网络 eth0 (Node-2)3.3 Calico BGP 模式
Pod A (10.244.1.10) Pod B (10.244.2.10)
│ │
▼ ▼
cali* 接口 cali* 接口
│ │
▼ ▼
Node-1 路由表 Node-2 路由表
│ │
▼ ▼
BGP peer (交换机/路由器) BGP peer (交换机/路由器)每个节点的 Pod 子网通过 BGP 宣告到网络中。
3.4 路由查看
bash
# 查看节点路由
ip route show
# Calico 查看 BGP 状态
calicoctl node status
# 查看 ARP 表
ip neigh show第4章 Service 与 Endpoints 机制
4.1 Service 创建过程
用户创建 Service
│
▼
API Server
│
├─ 分配 ClusterIP
├─ Endpoint Controller 创建 Endpoints/EndpointSlice
└─ kube-proxy Watch 到变化,生成规则4.2 Endpoints 与 EndpointSlice
yaml
# Endpoints(旧)
apiVersion: v1
kind: Endpoints
metadata:
name: web-service
subsets:
- addresses:
- ip: 10.244.1.10
- ip: 10.244.1.11
ports:
- port: 8080
# EndpointSlice(新)
apiVersion: discovery.k8s.io/v1
kind: EndpointSlice
metadata:
name: web-service-abc12
labels:
kubernetes.io/service-name: web-service
addressType: IPv4
ports:
- name: http
protocol: TCP
port: 8080
endpoints:
- addresses:
- 10.244.1.10
conditions:
ready: true
nodeName: node-14.3 Service 到 Endpoint 的映射
Service
name: web-service
ClusterIP: 10.96.123.45
port: 80
│
│ selector: app=web
▼
EndpointSlice
app-web-abc12
endpoints:
- 10.244.1.10:8080
- 10.244.1.11:80804.4 关键认知
- ClusterIP 不是真实 IP:只是 iptables/ipvs 规则中的匹配条件
- Service port 不监听:Pod 上没有进程监听 ClusterIP:port
- targetPort 才是真实端口:EndpointSlice 中记录的是 targetPort
第5章 kube-proxy 与 iptables/ipvs
5.1 kube-proxy 职责
kube-proxy 运行在每个节点,Watch Service 和 EndpointSlice,生成本地转发规则:
kube-proxy
│
├─ Watch Service
├─ Watch EndpointSlice
├─ 生成 iptables 规则 或 ipvs 规则
└─ 数据包在内核态转发5.2 iptables 模式规则链
PREROUTING / OUTPUT
│
▼
KUBE-SERVICES
│
├─ KUBE-SVC-XXX (匹配 ClusterIP:port)
│ │
│ ├─ KUBE-SEP-AAA (DNAT 到 Pod-1:targetPort)
│ └─ KUBE-SEP-BBB (DNAT 到 Pod-2:targetPort)
│
└─ KUBE-NODEPORTS (匹配 NodePort)5.3 ipvs 模式数据结构
Virtual Server (VS)
TCP 10.96.123.45:80 rr
├── Real Server 1: 10.244.1.10:8080
└── Real Server 2: 10.244.1.11:8080
Virtual Server (VS)
TCP 192.168.1.10:30080 rr
├── Real Server 1: 10.244.1.10:8080
└── Real Server 2: 10.244.1.11:80805.4 关键命令
bash
# 查看 kube-proxy 模式
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode
# 查看 iptables 规则
iptables -t nat -L KUBE-SERVICES -n -v
iptables -t nat -L KUBE-NODEPORTS -n -v
iptables -t nat -L KUBE-SVC-XXX -n -v
# 查看 ipvs 规则
ipvsadm -Ln
ipvsadm -Lnc
# 查看 conntrack
conntrack -L | grep 10.96.123.45第6章 DNS 解析全链路
6.1 Pod resolv.conf
bash
cat /etc/resolv.conf
# nameserver 10.96.0.10
# search default.svc.cluster.local svc.cluster.local cluster.local
# options ndots:56.2 DNS 查询流程
Pod A
│
│ 查询 web-service.default.svc.cluster.local
▼
NodeLocal DNSCache (如启用)
│
│ 缓存命中:直接返回
│ 缓存未命中:转发到 CoreDNS
▼
kube-dns Service (10.96.0.10)
│
│ kube-proxy 负载均衡
▼
CoreDNS Pod
│
│ kubernetes 插件查询 API Server
▼
返回 ClusterIP 10.96.123.456.3 NodeLocal DNSCache 劫持
bash
# PREROUTING DNAT
iptables -t nat -A PREROUTING -d 10.96.0.10/32 -p udp --dport 53 -j DNAT --to-destination 169.254.20.10:53
iptables -t nat -A PREROUTING -d 10.96.0.10/32 -p tcp --dport 53 -j DNAT --to-destination 169.254.20.10:53
# NOTRACK
iptables -t raw -A PREROUTING -d 10.96.0.10/32 -p udp --dport 53 -j NOTRACK6.4 ndots 放大效应
Pod 查询短域名 web-service 时:
web-service.default.svc.cluster.localweb-service.svc.cluster.localweb-service.cluster.localweb-service
每次查询失败才会尝试下一个,导致 DNS 请求放大。
第7章 内核数据包流转:从 Pod 到 Pod
7.1 同节点 Pod 通信
Pod A (10.244.1.10)
│
▼
veth pair
│
▼
cni0 / docker0 (bridge)
│
▼
veth pair
│
▼
Pod B (10.244.1.11)数据包路径:
- Pod A 协议栈构造数据包,目的 IP 10.244.1.11
- 通过 eth0 发送到 veth pair 对端
- 进入宿主机 bridge(cni0)
- bridge 根据 MAC 表转发到 Pod B 的 veth
- 进入 Pod B 网络命名空间
7.2 跨节点 Pod 通信(Flannel VXLAN)
Pod A (10.244.1.10) Pod B (10.244.2.10)
│ │
▼ ▼
cni0 (Node-1) cni0 (Node-2)
│ │
▼ ▼
flannel.1 (VTEP) ────── VXLAN ──────> flannel.1 (VTEP)
│ │
▼ ▼
eth0 (Node-1) 物理网络 eth0 (Node-2)数据包路径:
- Pod A 发出目的 IP 10.244.2.10 的数据包
- 宿主机路由表匹配到 flannel.1
- VXLAN 封装:外层 IP 为 Node-1 IP,目的 IP 为 Node-2 IP
- 物理网络转发到 Node-2
- Node-2 flannel.1 解封装
- 转发到 Pod B
7.3 通过 Service 访问 Pod
Pod A
│
│ 目的:10.96.123.45:80
▼
Pod A 所在节点
│
▼
PREROUTING / OUTPUT
│
▼
KUBE-SERVICES
│
▼
KUBE-SVC-XXX
│
▼
KUBE-SEP-XXX (DNAT 到 Pod-B:8080)
│
▼
路由决策
│
▼
CNI 网络转发到 Pod B7.4 conntrack 在返回路径中的作用
请求包:
源:10.244.1.10:random
目的:10.96.123.45:80
DNAT 后:
源:10.244.1.10:random
目的:10.244.2.10:8080
Pod B 回复:
源:10.244.2.10:8080
目的:10.244.1.10:random
返回包经过 conntrack 反向 DNAT:
源:10.96.123.45:80
目的:10.244.1.10:random第8章 外部访问全链路
8.1 NodePort 访问
外部客户端
│
│ 访问 <NodeIP>:30080
▼
Node-1 eth0:30080
│
▼
PREROUTING
│
▼
KUBE-NODEPORTS
│
▼
KUBE-SVC-XXX
│
▼
KUBE-SEP-XXX (DNAT 到 Pod:8080)
│
▼
Pod8.2 LoadBalancer 访问
外部客户端
│
│ 访问 <EXTERNAL-IP>:80
▼
云厂商 LB / MetalLB VIP
│
│ 转发到某个节点的 NodePort
▼
<NodeIP>:<NodePort>
│
▼
kube-proxy 规则
│
▼
Pod8.3 Ingress 访问
外部客户端
│
│ HTTPS api.example.com
▼
LoadBalancer / NodePort
│
▼
Ingress Controller (NGINX/Traefik)
│
│ 根据 host/path 路由
▼
Service (ClusterIP)
│
▼
Pod8.4 externalTrafficPolicy 的影响
| 模式 | 路径 | 源 IP |
|---|---|---|
| Cluster | 可能跨节点转发 | 被 SNAT |
| Local | 只到本节点 Pod | 保留 |
第9章 NodeLocal DNSCache 全链路
9.1 未启用 NodeLocal DNSCache
Pod A
│
│ DNS 查询
▼
kube-dns Service (10.96.0.10)
│
│ 可能跨节点
▼
CoreDNS Pod
│
│ 查询 API Server
▼
返回结果问题:跨节点流量、conntrack 压力、CoreDNS 瓶颈。
9.2 启用 NodeLocal DNSCache
Pod A
│
│ DNS 查询目标 10.96.0.10
▼
iptables DNAT 到 169.254.20.10
│
▼
NodeLocal DNSCache (本节点)
│
├─ 缓存命中:直接返回
└─ 缓存未命中:转发到 CoreDNS优势:流量不出节点、降低 CoreDNS 压力、减少 conntrack。
第10章 Calico + iptables 全链路
10.1 Calico 数据路径
Pod A
│
▼
cali* veth 接口
│
▼
Calico iptables 规则 (cali-FORWARD)
│
├─ NetworkPolicy 检查
│ │
│ ▼
│ cali-pi-<policy>
│
▼
路由决策
│
├─ 同节点:直接转发
└─ 跨节点:BGP / IPIP / VXLAN10.2 Calico 与 kube-proxy 规则共存
外部流量进入
│
▼
PREROUTING
│
├─ NodeLocal DNSCache DNAT(如启用)
├─ kube-proxy KUBE-SERVICES DNAT
└─ Calico cali-PREROUTING
│
▼
FORWARD
│
├─ kube-proxy 相关规则
└─ Calico cali-FORWARD / NetworkPolicy
│
▼
POSTROUTING
│
├─ kube-proxy 相关规则
└─ Calico cali-POSTROUTING10.3 NetworkPolicy 影响流量示例
如果 NetworkPolicy 只允许 app=frontend 访问 app=backend:
bash
iptables -L cali-tw-<backend-endpoint> -n -v
# 可看到允许 frontend 源 IP 的规则
# 其他源 IP 会被 DROP第11章 故障排查方法论
11.1 分层排查法
第 7 层:应用层
└─ Pod 是否运行?应用是否监听端口?
第 4 层:传输层
└─ Service/Endpoints 是否正确?telnet 是否通?
第 3 层:网络层
└─ 路由是否正确?CNI 是否正常?
第 2 层:数据链路层
└─ veth pair 是否存在?bridge 是否正常?
第 1 层:物理层
└─ 节点网络、网卡、交换机、安全组11.2 全链路排查清单
bash
# 1. Pod 状态
kubectl get pod <pod> -o wide
# 2. Service 和 Endpoints
kubectl get svc <svc> -o wide
kubectl get endpoints <svc>
kubectl get endpointslices -l kubernetes.io/service-name=<svc>
# 3. DNS 解析
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup <svc>.<namespace>
# 4. 从 Pod 内访问 Service
kubectl exec -it <pod> -- wget -O- http://<svc>:<port>
# 5. 查看 kube-proxy 规则
iptables -t nat -L KUBE-SERVICES -n -v | grep <svc>
ipvsadm -Ln | grep <cluster-ip>
# 6. 查看路由
ip route show
# 7. 查看 CNI 状态
kubectl get pods -n kube-system -l k8s-app=calico-node
# 8. 查看接口
ip link show
# 9. 抓包
tcpdump -i any -nn host <pod-ip> or host <cluster-ip> or port <node-port>
# 10. 查看 conntrack
conntrack -L | grep <cluster-ip>11.3 常见故障树
Pod 无法访问 Service
│
├─ Service 不存在 → 创建 Service
│
├─ Endpoints 为空 → 检查 selector 和 Pod readiness
│
├─ DNS 解析失败 → 检查 CoreDNS / NodeLocal DNSCache
│
├─ kube-proxy 规则缺失 → 重启 kube-proxy
│
├─ NetworkPolicy 拦截 → 检查 cali-pi-* 规则
│
├─ CNI 不通 → 检查路由、VXLAN/BGP
│
└─ conntrack 满 → 清理或增大 nf_conntrack_max第12章 性能热点与优化
12.1 常见性能瓶颈
| 瓶颈 | 原因 | 优化 |
|---|---|---|
| CoreDNS 高负载 | 大量 DNS 查询 | NodeLocal DNSCache |
| conntrack 满 | 大量短连接 | 增大上限、NOTRACK |
| iptables 规则过多 | 大量 Service/Pod | 使用 ipvs 模式 |
| 跨节点流量高 | Pod 调度不均 | Topology Spread Constraints |
| CNI 封装开销 | VXLAN/IPIP | 使用 BGP 或 eBPF |
| DNS ndots 放大 | 短域名查询多 | 调整 ndots 或使用 FQDN |
12.2 关键优化建议
- 大规模集群启用 NodeLocal DNSCache
- kube-proxy 使用 ipvs 模式
- Calico 使用 BGP 模式(网络支持时)
- 合理设置 Pod 资源限制和请求
- 配置 CoreDNS HPA
- 监控 DNS 延迟和缓存命中率
- 使用 eBPF 数据平面(Cilium 或 Calico eBPF)
第13章 附录:全链路命令速查
13.1 Pod 网络
bash
# Pod IP 和节点
kubectl get pod -o wide
# 进入 Pod 网络命名空间
nsenter -t <pause-pid> -n ip addr
nsenter -t <pause-pid> -n ip route
nsenter -t <pause-pid> -n cat /etc/resolv.conf
# Pod 内抓包
kubectl exec -it <pod> -- tcpdump -i any -nn port 8013.2 Service
bash
kubectl get svc -o wide
kubectl get endpoints <svc>
kubectl get endpointslices -l kubernetes.io/service-name=<svc>
kubectl describe svc <svc>13.3 DNS
bash
kubectl get pods -n kube-system -l k8s-app=kube-dns
kubectl logs -n kube-system -l k8s-app=kube-dns
kubectl get configmap coredns -n kube-system -o yaml
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup <svc>.<namespace>13.4 kube-proxy
bash
kubectl get configmap kube-proxy -n kube-system -o yaml | grep mode
iptables -t nat -L KUBE-SERVICES -n -v
iptables -t nat -L KUBE-NODEPORTS -n -v
ipvsadm -Ln13.5 CNI / 路由
bash
ip route show
ip link show
ip neigh show
kubectl get pods -n kube-system -l k8s-app=calico-node
calicoctl node status13.6 内核 / conntrack
bash
conntrack -L | head
conntrack -C
cat /proc/sys/net/netfilter/nf_conntrack_max
iptables -t raw -L -n -v13.7 抓包
bash
# 抓 Pod 间流量
tcpdump -i any -nn host <pod-ip>
# 抓 Service 流量
tcpdump -i any -nn host <cluster-ip>
# 抓 NodePort 流量
tcpdump -i any -nn port <node-port>
# 抓 DNS 流量
tcpdump -i any -nn port 53结语
Kubernetes 网络全链路是一个涉及应用层、DNS、Service、iptables/ipvs、CNI、内核协议栈、物理网络的复杂系统。掌握全链路的关键是:
- 理解每个组件的职责边界
- 熟悉数据包在内核中的流转路径
- 掌握分层排查法
- 善用 iptables、ipvsadm、conntrack、tcpdump 等工具
希望本教材能帮助你在生产环境中快速定位和解决 Kubernetes 网络问题。
教材生成时间:2026-07-18