Skip to content

Kubernetes 全链路深入解析:Pod → Service → DNS → iptables → 内核

目标读者:Kubernetes 高级运维、SRE、网络工程师、DevOps
前置知识:Kubernetes 基础、Linux 网络、iptables、DNS 基础
教材版本:v1.0


目录

  1. 全链路总览
  2. Pod 网络创建过程
  3. CNI 与数据链路层
  4. Service 与 Endpoints 机制
  5. kube-proxy 与 iptables/ipvs
  6. DNS 解析全链路
  7. 内核数据包流转:从 Pod 到 Pod
  8. 外部访问全链路
  9. NodeLocal DNSCache 全链路
  10. Calico + iptables 全链路
  11. 故障排查方法论
  12. 性能热点与优化
  13. 附录:全链路命令速查

第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 命令后:

  1. 为 Pod 创建 veth pair
  2. 一端放入 Pod 网络命名空间(eth0)
  3. 另一端连接到宿主机网络(bridge/tunl0/cali*)
  4. 分配 IP 地址
  5. 配置路由

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数据链路特点
FlannelVXLAN / UDP / host-gw简单,适合中小规模
CalicoBGP / IPIP / VXLAN高性能,支持网络策略
CiliumeBPF / VXLAN可观测性强,性能优秀
WeaveVXLAN易用,去中心化
CanalFlannel + 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-1

4.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:8080

4.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:8080

5.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:5

6.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.45

6.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 NOTRACK

6.4 ndots 放大效应

Pod 查询短域名 web-service 时:

  1. web-service.default.svc.cluster.local
  2. web-service.svc.cluster.local
  3. web-service.cluster.local
  4. web-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)

数据包路径:

  1. Pod A 协议栈构造数据包,目的 IP 10.244.1.11
  2. 通过 eth0 发送到 veth pair 对端
  3. 进入宿主机 bridge(cni0)
  4. bridge 根据 MAC 表转发到 Pod B 的 veth
  5. 进入 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)

数据包路径:

  1. Pod A 发出目的 IP 10.244.2.10 的数据包
  2. 宿主机路由表匹配到 flannel.1
  3. VXLAN 封装:外层 IP 为 Node-1 IP,目的 IP 为 Node-2 IP
  4. 物理网络转发到 Node-2
  5. Node-2 flannel.1 解封装
  6. 转发到 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 B

7.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)


Pod

8.2 LoadBalancer 访问

外部客户端

    │ 访问 <EXTERNAL-IP>:80

云厂商 LB / MetalLB VIP

    │ 转发到某个节点的 NodePort

<NodeIP>:<NodePort>


kube-proxy 规则


Pod

8.3 Ingress 访问

外部客户端

    │ HTTPS api.example.com

LoadBalancer / NodePort


Ingress Controller (NGINX/Traefik)

    │ 根据 host/path 路由

Service (ClusterIP)


Pod

8.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 / VXLAN

10.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-POSTROUTING

10.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 关键优化建议

  1. 大规模集群启用 NodeLocal DNSCache
  2. kube-proxy 使用 ipvs 模式
  3. Calico 使用 BGP 模式(网络支持时)
  4. 合理设置 Pod 资源限制和请求
  5. 配置 CoreDNS HPA
  6. 监控 DNS 延迟和缓存命中率
  7. 使用 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 80

13.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 -Ln

13.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 status

13.6 内核 / conntrack

bash
conntrack -L | head
conntrack -C
cat /proc/sys/net/netfilter/nf_conntrack_max
iptables -t raw -L -n -v

13.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、内核协议栈、物理网络的复杂系统。掌握全链路的关键是:

  1. 理解每个组件的职责边界
  2. 熟悉数据包在内核中的流转路径
  3. 掌握分层排查法
  4. 善用 iptables、ipvsadm、conntrack、tcpdump 等工具

希望本教材能帮助你在生产环境中快速定位和解决 Kubernetes 网络问题。


教材生成时间:2026-07-18