第275篇:Kubernetes 网络:CNI、Pod 网络与 Service

关键词

Kubernetes 网络、CNI、Pod 网络、Service、Cluster IP、kube-proxy、网络策略、容器网络模型


一、Kubernetes 网络模型

1.1 三大网络要求

Kubernetes 对网络提出了四个基本要求(CNI 规范必须满足):

K8s 网络模型核心要求:

1. Pod 间通信(跨节点)
   任意 Pod(在不同节点上)可以直接通信
   不需要 NAT

   Node1: PodA ─────────► Node2: PodB
          10.1.1.2             10.1.2.3
          (直接路由,不经过 NAT)

2. Pod 与 Service 通信
   Pod 通过 Service Cluster IP 访问其他 Pod 组
   kube-proxy 实现负载均衡

3. 节点到 Pod 通信
   节点上的进程可以访问本节点 Pod
   不需要端口映射

4. 外部到 Service 通信
   外部流量通过 NodePort / LoadBalancer / Ingress 进入

1.2 Pod 网络地址

Pod IP 地址分配:

每个 Pod 有一个唯一的 IP 地址(集群内可达)

节点 1(192.168.1.10) ┌──────┐ ┌──────┐ ┌──────┐ └──┬───┘ └──┬───┘ └──┬───┘ ┌──┴────────┴────────┴──┐ └───────────────────────┘ ┌────┴────┐ PodA 10.1.1.2 veth pair 到 CNI cni0/eth0 eth0 PodB 10.1.1.3 PodC 10.1.1.4
▼ 物理网络

┌──────────────────────────────────────────┐ │ 节点 2(192.168.1.20) │ │ PodD: 10.1.2.2 │ │ PodE: 10.1.2.3 │ └──────────────────────────────────────────┘

Pod 网络设计: Pod CIDR:10.1.0.0/16 节点 1:10.1.1.0/24(每个节点分配一个子网) 节点 2:10.1.2.0/24 Pod 地址不重叠,集群唯一


二、CNI(Container Network Interface)

2.1 CNI 是什么

CNI 是 Kubernetes 的网络插件接口标准,定义了容器网络如何配置:

CNI 架构:

kubelet ▼ ┌──────────┐ ┌──────────┐ ┌────────┐ └──────────┘ └──────────┘ └────────┘ └──────────────┴────────────┘ ┌────┴────┐ 调用 CNI 插件 Flannel CNI 插件 CNI 规范 ADD/DEL CHECK Calico CNI 插件 Cilium CNI 插件

CNI 操作: ADD:创建 Pod 时添加网络接口 ┌─ 分配 IP 地址 ├─ 创建 veth pair(一端在 Pod,一端在主机) ├─ 配置路由 └─ 配置网络策略

DEL:删除 Pod 时清理网络 ┌─ 释放 IP 地址 ├─ 删除 veth pair └─ 清理路由

CHECK:检查网络配置是否正常

2.2 CNI 配置

CNI 配置文件(/etc/cni/net.d/):

示例:Flannel 配置

  {
    "name": "cbr0",
    "type": "flannel",
    "delegate": {
      "bridge": "cni0",
      "isDefaultGateway": true,
      "ipMasq": false,
      "hairpinMode": true
    }
  }

示例:Calico 配置

  {
    "name": "k8s-pod-network",
    "cniVersion": "0.3.1",
    "type": "calico",
    "etcd_endpoints": "https://127.0.0.1:2379",
    "log_level": "info",
    "ipam": {
      "type": "calico-ipam",
      "assign_ipv4": "true"
    },
    "policy": {
      "type": "k8s"
    }
  }

三、Pod 网络通信

3.1 同节点 Pod 通信

同节点 Pod 通过 CNI 网桥通信:

节点 1 ┌─────┐ ┌─────┐ └──┬──┘ └──┬──┘ ┌──┴────────────────┴──┐ └──────────┬──────────┘ ┌───┴───┐ PodA eth0 vethA cni0(网桥) 10.1.1.1 eth0 vethB PodB eth0

通信流程: PodA(10.1.1.2) → PodB(10.1.1.3)

1. PodA 发现目标 IP 在同一网段
2. 发送 ARP 请求:Who has 10.1.1.3?
3. cni0 网桥代答(或直接转发)
4. 通过 vethB 到达 PodB
5. 整个过程在节点内完成

3.2 跨节点 Pod 通信

跨节点 Pod 通信——取决于 CNI 插件:

VXLAN 模式(Flannel VXLAN / Calico VXLAN):

┌── 节点 1 ─────────┐ ┌── 节点 2 ─────────┐
PodA: 10.1.1.2 ┌──┴──┐ └──┬──┘ ┌──┴──┐ └──┬──┘ cni0 VXLAN flannel.1 eth0 PodB: 10.1.2.2 ┌──┴──┐ └──┬──┘ ┌──┴──┐ └──┬──┘ eth0 cni0 flannel.1
│ │
└─────── 物理网络 ───────┘

通信流程: PodA(10.1.1.2) → PodB(10.1.2.2)

1. PodA 发现目标不在同一网段 → 发送到网关 cni0
2. cni0 查路由 → 目标 10.1.2.0/24 通过 flannel.1
3. flannel.1 封装 VXLAN → 外层 IP 为节点 2 的 eth0
4. 物理网络转发到节点 2
5. 节点 2 的 flannel.1 解封装 → cni0 → PodB

四、Service 网络

4.1 Cluster IP

Service——为一组 Pod 提供稳定的访问入口:

┌──────────────────────────────────────────┐ │ Service: my-app │ │ Cluster IP: 10.96.0.10 (虚拟 IP) │ │ Selector: app=my-app │ │ Port: 80 → TargetPort: 8080 │ │ │ │ 后端 Pod: │ │ PodA: 10.1.1.2:8080 │ │ PodB: 10.1.2.2:8080 │ │ PodC: 10.1.3.2:8080 │ └──────────────────────────────────────────┘

Client ── 10.96.0.10:80 ──► kube-proxy
--- --- ---
▼ ▼ ▼
┌──────┐ ┌──────┐ ┌──────┐
PodA 10.1.1.2 PodB 10.1.2.2

Cluster IP 的特点: 虚拟 IP,不绑定任何网络接口 只能集群内部访问 kube-proxy 实现负载均衡 默认轮询(Round Robin)

4.2 kube-proxy 模式

kube-proxy 的实现方式:

模式 1:iptables(默认)

  # 为 Service 10.96.0.10:80 生成的 iptables 规则
  -A PREROUTING -m comment --comment "my-app" -j KUBE-SVC-XXXX
  -A KUBE-SVC-XXXX -m statistic --mode random --probability 0.33 -j KUBE-SEP-A
  -A KUBE-SVC-XXXX -m statistic --mode random --probability 0.50 -j KUBE-SEP-B
  -A KUBE-SVC-XXXX -j KUBE-SEP-C

  -A KUBE-SEP-A -p tcp -m tcp -j DNAT --to-destination 10.1.1.2:8080
  -A KUBE-SEP-B -p tcp -m tcp -j DNAT --to-destination 10.1.2.2:8080
  -A KUBE-SEP-C -p tcp -m tcp -j DNAT --to-destination 10.1.3.2:8080

  优点:稳定、无需额外组件
  缺点:规则多(大规模集群 10K+ 规则)、更新慢

模式 2:IPVS(大规模推荐)

  # IPVS 模式配置
  kubectl edit configmap kube-proxy -n kube-system
    mode: ipvs

  # 查看 IPVS 规则
  ipvsadm -Ln
  IP Virtual Server version 1.2.1
    -> 10.96.0.10:80 rr
      -> 10.1.1.2:8080       Masq    1      0          0
      -> 10.1.2.2:8080       Masq    1      0          0
      -> 10.1.3.2:8080       Masq    1      0          0

  优点:高性能(O(1) 查找)、支持多种调度算法
  缺点:需要加载 ip_vs 内核模块

4.3 NodePort / LoadBalancer

Service 类型——对外暴露:

NodePort: 在每个节点上开放一个静态端口(30000-32767) 外部流量通过 节点IP:NodePort 访问

┌──────┐ NodePort:31080 ┌──────┐
Client ──► Node1:31080 ────► PodA
Node2:31080 ──► PodB

apiVersion: v1 kind: Service metadata: name: my-app spec: type: NodePort ports: - port: 80 nodePort: 31080 targetPort: 8080

LoadBalancer(云厂商提供): NodePort 的升级版 云厂商创建负载均衡器 自动分配公网 IP

Client └──────┘ ───► 10.96.0.10 云 LB(公网IP) └──────┘ ───► Pod
└──────────────┘

五、K8s 网络策略

5.1 NetworkPolicy

NetworkPolicy——K8s 原生的 Pod 级防火墙:

  基于标签选择器
  白名单模式(默认拒绝,显式允许)

示例:

  apiVersion: networking.k8s.io/v1
  kind: NetworkPolicy
  metadata:
    name: web-allow
  spec:
    podSelector:
      matchLabels:
        app: web                          # 目标 Pod
    policyTypes:
    - Ingress
    - Egress
    ingress:
    - from:
      - podSelector:
          matchLabels:
            app: app                       # 只允许 App Pod 访问
      ports:
      - protocol: TCP
        port: 8080
    egress:
    - to:
      - podSelector:
          matchLabels:
            app: db                        # 只允许访问 DB Pod
      ports:
      - protocol: TCP
        port: 3306

  NetworkPolicy 需要 CNI 插件支持:
    Calico ✓
    Cilium ✓
    Flannel ✗(不支持 NetworkPolicy)

六、总结

知识点 核心要点
K8s 网络模型 Pod 互通无 NAT,Pod ↔ Service,外部 → Service
CNI 插件式网络接口,负责 Pod 网络配置
同节点通信 通过 CNI 网桥(cni0)直接桥接
跨节点通信 VXLAN/Geneve 隧道或 BGP 路由
Service Cluster IP 虚拟 IP,kube-proxy 转发
kube-proxy iptables(默认)或 IPVS(大规模)
NodePort 每个节点开放端口,外部通过 NodeIP:Port 访问
NetworkPolicy Pod 级防火墙,基于标签选择器

七、思考

  1. Kubernetes 网络模型对 Pod 间通信提出了怎样的要求?为什么要求"不需要 NAT"?
  2. CNI 插件的 ADD 操作执行了哪些步骤?从 Pod 创建到网络连通,CNI 完成了哪些配置?
  3. 跨节点 Pod 通信中,Flannel VXLAN 模式下数据包的封装和解封装流程是怎样的?
  4. kube-proxy 的 iptables 模式和 IPVS 模式有什么区别?在 5000 个 Service 的集群中,为什么推荐 IPVS?
  5. NetworkPolicy 为什么需要 CNI 插件支持?Flannel 为什么不能实现 NetworkPolicy?

下篇预告:第276篇《Flannel、Calico、Cilium 方案对比》——三种主流 CNI 插件的架构对比、性能、功能特性与选型建议。