kube-proxy 与 Kubernetes 网络模型深度解析
1. Kubernetes 网络模型
Kubernetes 网络模型有三个基本要求:
- Pod 间通信:所有 Pod 可以直接通信,无需 NAT
- Node-Pod 通信:节点可以直接与 Pod 通信,无需 NAT
- Pod 看到的 IP 与外部看到的 IP 相同(无 NAT)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ┌─────────────────────────────────────────────────────────┐ │ Node 1 (10.0.0.1) │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Pod A │ │ Pod B │ │ │ │ IP: 10.244.1.2 │ │ IP: 10.244.1.3 │ │ │ └──────────────────┘ └──────────────────┘ │ │ │ │ │ │ └──────────┬───────────┘ │ │ cni0/cbr0(虚拟网桥) │ └───────────────────────┼─────────────────────────────────┘ │ 跨节点路由(Overlay/BGP) ┌───────────────────────┼─────────────────────────────────┐ │ Node 2 (10.0.0.2) │ │ │ ┌──────────────────┐ ┌──────────────────┐ │ │ │ Pod C │ │ Pod D │ │ │ │ IP: 10.244.2.2 │ │ IP: 10.244.2.3 │ │ │ └──────────────────┘ └──────────────────┘ │ └─────────────────────────────────────────────────────────┘
|
2. kube-proxy 的职责
kube-proxy 运行在每个节点上,负责维护网络规则,实现 Service 的负载均衡:
1 2 3 4 5 6 7 8
| Service(虚拟 IP: 10.96.0.1:80) │ │ kube-proxy 维护的规则 ▼ 负载均衡到后端 Pod ├── Pod A (10.244.1.2:8080) ├── Pod B (10.244.1.3:8080) └── Pod C (10.244.2.2:8080)
|
3. iptables 模式(默认)
3.1 工作原理
kube-proxy 监听 Service 和 Endpoints 变化,动态维护 iptables 规则:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| 数据包到达 │ ▼ PREROUTING → KUBE-SERVICES │ ├── 匹配 Service ClusterIP:Port │ │ │ ▼ │ KUBE-SVC-XXXX(Service 链) │ │ │ ├── 33 │ ├── 50 │ └── 100 │ └── DNAT:将 ClusterIP 替换为 Pod IP
|
3.2 查看 iptables 规则
1 2 3 4 5 6 7 8
| iptables -t nat -L KUBE-SERVICES -n --line-numbers
iptables -t nat -L KUBE-SVC-XXXXXXXXXXXX -n
iptables -t nat -L KUBE-SEP-XXXXXXXXXXXX -n
|
3.3 iptables 的局限性
- 规则数量随 Service 数量线性增长(1000 个 Service → 数万条规则)
- 每次更新需要全量刷新规则(O(n) 复杂度)
- 大规模集群性能下降明显
4. IPVS 模式(推荐生产使用)
4.1 IPVS vs iptables
| 特性 |
iptables |
IPVS |
| 数据结构 |
链表 |
哈希表 |
| 规则查找 |
O(n) |
O(1) |
| 更新方式 |
全量刷新 |
增量更新 |
| 负载均衡算法 |
随机 |
rr/lc/dh/sh/sed/nq |
| 大规模性能 |
差 |
好 |
4.2 启用 IPVS
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: v1 kind: ConfigMap metadata: name: kube-proxy namespace: kube-system data: config.conf: | mode: "ipvs" ipvs: scheduler: "rr" # 轮询(rr/lc/dh/sh/sed/nq) strictARP: true
|
4.3 IPVS 负载均衡算法
1 2 3 4 5 6
| rr - Round Robin(轮询) lc - Least Connection(最少连接) dh - Destination Hashing(目标哈希) sh - Source Hashing(源哈希,会话保持) sed - Shortest Expected Delay nq - Never Queue
|
5. Service 类型详解
5.1 ClusterIP(默认)
1 2 3 4 5 6 7 8 9 10 11
| apiVersion: v1 kind: Service metadata: name: my-service spec: type: ClusterIP selector: app: my-app ports: - port: 80 targetPort: 8080
|
- 分配一个集群内部虚拟 IP
- 只能在集群内部访问
- 适合内部微服务通信
5.2 NodePort
1 2 3 4 5 6
| spec: type: NodePort ports: - port: 80 targetPort: 8080 nodePort: 30080
|
1 2 3 4
| 外部请求 → 任意节点 IP:30080 │ ▼ kube-proxy DNAT → Pod IP:8080
|
5.3 LoadBalancer
1 2 3 4 5
| spec: type: LoadBalancer ports: - port: 80 targetPort: 8080
|
1 2 3 4 5 6 7
| 外部请求 → 云厂商 LB(自动创建) │ ▼ NodePort │ ▼ Pod
|
5.4 ExternalName
1 2 3 4
| spec: type: ExternalName externalName: my-database.example.com
|
5.5 Headless Service
1 2 3 4
| spec: clusterIP: None selector: app: mysql
|
DNS 直接返回 Pod IP 列表,适合 StatefulSet 和服务发现。
6. Endpoints 与 EndpointSlice
6.1 传统 Endpoints
1 2 3
| kubectl get endpoints my-service
|
6.2 EndpointSlice(1.21+ 默认)
EndpointSlice 解决了大规模 Endpoints 的性能问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| apiVersion: discovery.k8s.io/v1 kind: EndpointSlice metadata: name: my-service-abc123 labels: kubernetes.io/service-name: my-service addressType: IPv4 ports: - name: http port: 8080 endpoints: - addresses: - "10.244.1.2" conditions: ready: true nodeName: node-1
|
- 每个 EndpointSlice 最多 100 个 Endpoint
- 增量更新,减少 apiserver 压力
- 支持拓扑感知路由
7. DNS 服务发现(CoreDNS)
7.1 DNS 记录格式
1 2 3 4 5 6 7 8
| # Service DNS {service-name}.{namespace}.svc.cluster.local
# Pod DNS {pod-ip-dashes}.{namespace}.pod.cluster.local
# StatefulSet Pod DNS {pod-name}.{service-name}.{namespace}.svc.cluster.local
|
7.2 DNS 解析示例
1 2 3 4 5 6 7 8 9
| nslookup my-service
curl http://my-service.other-namespace.svc.cluster.local
|
7.3 CoreDNS 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| apiVersion: v1 kind: ConfigMap metadata: name: coredns namespace: kube-system data: Corefile: | .:53 { errors health { lameduck 5s } ready kubernetes cluster.local in-addr.arpa ip6.arpa { pods insecure fallthrough in-addr.arpa ip6.arpa ttl 30 } prometheus :9153 forward . /etc/resolv.conf { max_concurrent 1000 } cache 30 loop reload loadbalance }
|
7.4 DNS 优化
1 2 3 4 5 6 7 8 9 10 11
| spec: dnsPolicy: ClusterFirst dnsConfig: options: - name: ndots value: "2" - name: timeout value: "2" - name: attempts value: "2"
|
8. Ingress(HTTP 路由)
8.1 Ingress 资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: my-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: ingressClassName: nginx tls: - hosts: - example.com secretName: tls-secret rules: - host: example.com http: paths: - path: /api pathType: Prefix backend: service: name: api-service port: number: 80 - path: / pathType: Prefix backend: service: name: web-service port: number: 80
|
8.2 常用 Ingress Controller
| Controller |
特点 |
| nginx-ingress |
最成熟,功能丰富 |
| Traefik |
自动服务发现,配置简单 |
| HAProxy |
高性能 |
| Istio Gateway |
服务网格集成 |
| AWS ALB |
云原生,对接 AWS ALB |
9. NetworkPolicy(网络策略)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: deny-all-ingress namespace: production spec: podSelector: {} policyTypes: - Ingress - Egress ingress: - from: - namespaceSelector: matchLabels: name: frontend - podSelector: matchLabels: role: api ports: - protocol: TCP port: 8080 egress: - to: - namespaceSelector: matchLabels: name: database ports: - protocol: TCP port: 5432
|
NetworkPolicy 需要 CNI 插件支持(Calico、Cilium、Weave 等)。
10. 拓扑感知路由(Topology Aware Routing)
优先将流量路由到同一可用区的 Pod,减少跨区流量费用:
1 2 3 4
| metadata: annotations: service.kubernetes.io/topology-mode: "Auto"
|
11. 常见网络问题排查
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| kubectl run test --image=busybox --rm -it -- wget -O- http://my-service
kubectl get endpoints my-service
kubectl logs -n kube-system -l k8s-app=kube-proxy
iptables -t nat -L -n | grep <service-ip>
ipvsadm -Ln | grep <service-ip>
kubectl run dns-test --image=busybox --rm -it -- nslookup kubernetes
kubectl exec -it <pod> -- tcpdump -i eth0 -n port 80
|
12. 总结
Kubernetes 网络体系的核心:
- 扁平网络模型:Pod 间直接通信,无 NAT
- kube-proxy:维护 iptables/IPVS 规则,实现 Service 负载均衡
- IPVS 优于 iptables:大规模集群必须使用 IPVS
- CoreDNS:集群内 DNS 服务发现
- Ingress:HTTP/HTTPS 七层路由
- NetworkPolicy:微隔离,零信任网络