Kubernetes网络模型与CNI插件深度解析

深入解析 Kubernetes 网络模型三大原则、CNI 接口规范、主流 CNI 插件(Flannel/Calico/Cilium)对比,以及 Service 实现、Ingress 控制器、Gateway API 和网络排错工具。

Kubernetes 网络是容器编排中最复杂的领域之一。每个 Pod 都需要独立的 IP、跨节点互通、Service 发现——而实现这些的 CNI 插件选择,直接影响集群的性能、安全性和可观测性。


目录


1. Kubernetes 网络模型

Kubernetes 对网络有四个基本要求,这是所有 CNI 插件必须实现的契约:

  1. Pod IP 全局唯一:每个 Pod 拥有独立的 IP,且在集群内不冲突
  2. Pod 之间直接通信:无需 NAT,Pod A 可以直接用 Pod B 的 IP 访问
  3. Pod 与 Node 互通:节点和 Pod 可以双向通信
  4. Service IP 可达:集群内部可以通过 Service 的 ClusterIP 访问后端 Pod
┌─────────────────────────────────────────────────────────┐
│                      Kubernetes Cluster                  │
│                                                         │
│   ┌──────────┐         ┌──────────┐                    │
│   │  Node 1  │─────────│  Node 2  │  ← 节点间三层互通   │
│   │10.0.1.0/24│        │10.0.2.0/24│                    │
│   │          │ Overlay  │          │                    │
│   │ ┌──────┐ │ Network  │ ┌──────┐ │                    │
│   │ │Pod-A │ │◄────────►│ │Pod-B │ │  ← 无需 NAT      │
│   │ │10.1.1│ │          │ │10.1.2│ │                    │
│   │ └──┬───┘ │          │ └──┬───┘ │                    │
│   │    │     │          │    │     │                    │
│   │ ┌──▼───┐ │          │ ┌──▼───┐ │                    │
│   │ │CNI   │ │          │ │CNI   │ │  ← CNI 插件实现   │
│   │ └──────┘ │          │ └──────┘ │                    │
│   └──────────┘          └──────────┘                    │
│                                                         │
│   Service IP (ClusterIP) → kube-proxy → 后端 Pod        │
└─────────────────────────────────────────────────────────┘

2. CNI 接口规范

CNI(Container Network Interface)是一组标准化的网络配置接口,由 CNCF 维护。

CNI 插件调用流程

当 kubelet 创建 Pod 时,通过 CRI(containerd/CRI-O)调用 CNI 插件:

kubelet → CRI (containerd) → CNI Plugin
  │                              │
  │  1. 调用 CNI ADD            │  → 创建 veth pair、分配 IP、设置路由
  │  2. 调用 CNI CHECK          │  → 验证网络配置是否正确
  │  3. 调用 CNI DEL            │  → Pod 删除时清理网络资源

CNI 配置格式

# /etc/cni/net.d/10-calico.conflist
{
  "cniVersion": "0.3.1",
  "name": "k8s-pod-network",
  "plugins": [
    {
      "type": "calico",
      "log_level": "info",
      "datastore_type": "kubernetes",
      "nodename": "node-1",
      "ipam": {
        "type": "calico-ipam",
        "assign_ipv4": "true",
        "ipv4_pools": ["10.1.0.0/16"]
      }
    },
    {
      "type": "portmap",
      "snat": true,
      "capabilities": {"portMappings": true}
    }
  ]
}

CNI 链式调用:CNI 支持多个插件按顺序执行(如 calico → portmap → bandwidth),每个插件处理不同的网络层面。


3. 主流 CNI 插件对比

3.1 Flannel

最老牌、最简单的 CNI 插件,由 CoreOS 开发。

后端模式

后端原理性能适用场景
VXLANUDP 封装,默认端口 8472中等通用场景,跨云
UDP用户态封装较差仅调试
Host-GW直接路由,无封装最好二层互通的局域网
WireGuard加密隧道需要加密

Flannel 配置示例:

apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-flannel-cfg
  namespace: kube-flannel
data:
  cni-conf.json: |
    {
      "name": "cbr0",
      "cniVersion": "0.3.1",
      "plugins": [
        {
          "type": "flannel",
          "delegate": {
            "hairpinMode": true,
            "isDefaultGateway": true
          }
        }
      ]
    }
  net-conf.json: |
    {
      "Network": "10.1.0.0/16",
      "Backend": {
        "Type": "vxlan",
        "VNI": 1,
        "Port": 8472
      }
    }

Flannel 优点

  • 部署简单,单 DaemonSet 即可运行
  • 资源占用低,适合小集群
  • 文档丰富,上手快

Flannel 缺点

  • 无 NetworkPolicy 支持(需配合 Calico policy 组件)
  • 无高级网络策略(如 L7 过滤)
  • VXLAN 带来封装开销(~20% 性能下降)

3.2 Calico

功能全面的 CNI 插件,支持路由模式和策略模式。

BGP 模式:Calico 使用 BGP 在节点间交换路由,无需 VXLAN 封装:

节点A 通告:10.1.1.0/24 可达
节点B 通告:10.1.2.0/24 可达
通过 BGP 反射器或直接会话同步路由

当集群节点在同一二层网络时,BGP 模式提供最佳性能(无封装开销)。跨三层网络时可启用 IPIP 或 VXLAN 封装。

Calico 配置(BGP 模式):

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: default-ipv4-ippool
spec:
  cidr: 10.1.0.0/16
  blockSize: 26              # 每个节点分配的 IP 块大小(64 个 IP)
  natOutgoing: true
  disabled: false
  nodeSelector: all()

Calico 的核心能力

能力说明
NetworkPolicy原生支持 L3/L4 策略,配合 Calico Enterprise 支持 L7
eBPF 加速Calico eBPF 模式(替代 kube-proxy)提供更高性能
WireGuard 加密节点间流量自动加密
多网卡支持每个 Pod 多网卡(电信 NFV 场景)
BGP 社区功能通过 BGP 社区属性控制路由发布(如阻止某些节点被外部访问)

Calico eBPF 模式

# 启用 eBPF 模式
kubectl patch installation default --type=merge -p '{"spec": {"calicoNetwork": {"linuxDataplane": "BPF"}}}'

eBPF 模式的优势:

  • 替代 kube-proxy,Service NAT 在 eBPF 中完成(O(1) 查找)
  • 绕过 iptables/ipvs,减少内核数据包处理路径
  • 支持源 IP 保留(Direct Server Return)
  • 降低 CPU 使用率(大规模集群效果明显)

3.3 Cilium

基于 eBPF 的下一代 CNI 插件,提供原生 L3-L7 安全策略和可观测性。

┌──────────────────────────────────────┐
│           Cilium Architecture        │
│                                      │
│  ┌──────────┐    ┌──────────────┐    │
│  │  Hubble  │←───│   Cilium     │    │
│  │(可观测性) │    │  Agent       │    │
│  └──────────┘    │  (eBPF)      │    │
│                  └──────┬───────┘    │
│                         │ eBPF       │
│                  ┌──────▼───────┐    │
│                  │   Kernel     │    │
│                  │   (XDP/TC)   │    │
│                  └──────────────┘    │
└──────────────────────────────────────┘

Cilium 配置示例:

apiVersion: cilium.io/v2alpha1
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: default-deny-ingress
spec:
  endpointSelector: {}
  ingressDeny:
    - {}
---
# 允许 frontend → backend 的 HTTP GET /api
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: backend-policy
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: GET
                path: "/api/.*"

Cilium 的核心优势

能力FlannelCalicoCilium
NetworkPolicy (L3/L4)
NetworkPolicy (L7/HTTP)⚠️ Enterprise✅ 原生
可观测性 (Hubble)⚠️ 有限✅ 原生
eBPF 加速✅ 原生
多集群连接
mTLS (SPIFFE)✅ (Roadmap)
复杂度中高

Hubble 可观测性

# 安装 Hubble CLI
hubble status
hubble observe --namespace production --from-pod frontend
hubble observe --protocol http --http-status 500

3.4 其他 CNI 插件

插件特点适用场景
Weave Net加密默认、自动发现、简单中小集群、安全要求高
AntreaVMware 出品、基于 OVSvSphere 环境、NSX 集成
CanalFlannel + Calico 政策历史方案,现已被 Calico 替代
Kube-OVN基于 OVN/OVS需要高级网络功能(VPC、QoS)
Multus多网卡 CNI 元插件NFV、5G、SR-IOV 场景

4. Service 网络实现

kube-proxy 的三种代理模式

kube-proxy 是实现 Service 虚拟 IP 的核心组件,支持三种模式:

iptables 模式(默认):

Client → Service IP:80
  → iptables PREROUTING 链
    → DNAT 到 Pod IP:8080
      → Pod 处理请求
        → SNAT 回 Service IP(返回路径)
# 查看 iptables 规则
iptables -t nat -L KUBE-SERVICES -n | grep api-service
# 输出:KUBE-MARK-MASQ + KUBE-SVC-... 链 + 概率分配到各 Pod

iptables 模式的会话亲和(sessionAffinity: ClientIP)通过概率规则实现,但大集群下规则数量激增(O(n),n=Service 数量),更新延迟增加。

ipvs 模式

使用内核 IPVS 模块,基于哈希表查找,O(1) 复杂度:

# ipvs 支持的负载均衡算法
ipvsadm -Ln | grep Scheduling
# 输出:rr (轮询) / lc (最少连接) / dh (目标哈希) / sh (源哈希) / sed (最短期望延迟) / nq (永不排队)

性能对比(不同 Service 数量下的规则更新延迟):

Service 数量iptables 规则更新ipvs 更新
1,000~100ms~5ms
10,000~5s~5ms
50,000~30s+~10ms

推荐:1,000 Service 以下用 iptables(简单),以上强烈建议 ipvs。

nftables 模式(K8s 1.29+):

mode: "nftables"
  • 使用 nf_tables 子系统(iptables 的后继者)
  • 规则更清晰、性能更好
  • 新集群推荐,旧集群迁移需谨慎

ExternalTrafficPolicy

spec:
  externalTrafficPolicy: Local   # 保留源 IP,但可能导致负载不均
  # 或
  externalTrafficPolicy: Cluster  # 默认,负载均衡但丢失源 IP

Local 模式的流量不平衡问题:如果 3 个 Pod 分布在 2 个节点上,节点 A 有 1 个 Pod,节点 B 有 2 个 Pod,外部 LB 将流量均匀分到节点 A 和 B,导致节点 A 上的 Pod 获得 50% 流量,节点 B 上的每个 Pod 仅获得 25%。

解决方案:topologyKeys 或 PodTopologySpread + 外部 LB 的健康检查配置。


5. Ingress 与 Gateway API

Ingress 控制器对比

控制器特点适用场景
NGINX Ingress最流行、功能全面、稳定通用场景
Traefik自动服务发现、原生支持 Let’s Encrypt云原生、动态环境
HAProxy高性能、低延迟金融、高频交易
KongAPI 网关功能(限流、认证、插件)需要 API 管理
Emissary-ingress基于 Envoy、支持 gRPC微服务、gRPC

Gateway API:Ingress 的下一代

Ingress 的局限:所有规则放在单个资源中,难以多团队共享管理。Gateway API 引入分层模型:

GatewayClass → Gateway → HTTPRoute
     ↑            ↑           ↑
 集群管理员    平台工程师    应用开发者
# GatewayClass:集群级别,定义控制器类型
apiVersion: gateway.networking.k8s.io/v1
kind: GatewayClass
metadata:
  name: nginx
spec:
  controllerName: gateway.nginx.org/nginx-gateway-controller

---
# Gateway:定义监听端口和 TLS
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
  name: public-gateway
  namespace: ingress-nginx
spec:
  gatewayClassName: nginx
  listeners:
    - name: https
      protocol: HTTPS
      port: 443
      tls:
        mode: Terminate
        certificateRefs:
          - name: wildcard-cert
      allowedRoutes:
        namespaces:
          from: All   # 允许所有 namespace 绑定路由

---
# HTTPRoute:应用团队定义路由规则
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: api-routes
  namespace: production
spec:
  parentRefs:
    - name: public-gateway
      namespace: ingress-nginx
  hostnames:
    - api.example.com
  rules:
    - matches:
        - path:
            type: PathPrefix
            value: /orders
      backendRefs:
        - name: order-service
          port: 80
    - matches:
        - path:
            type: PathPrefix
            value: /users
      backendRefs:
        - name: user-service
          port: 80

Gateway API 优势

  • 角色分离:集群管理员、平台团队、应用团队各司其职
  • 多协议支持:HTTP、TCP、UDP、gRPC、TLS
  • 增强路由:权重分流、重定向、重写、跨 Namespace 引用
  • 可扩展性:支持自定义策略(如限流、认证通过 PolicyAttachment)

现状(2025):Ingress 仍是主流,Gateway API 成熟度稳步提升,新项目可考虑直接使用 Gateway API。


6. DNS 服务发现

CoreDNS 架构

CoreDNS 是 K8s 默认的集群 DNS,通过 Watch API Server 自动同步 Service/Endpoint 信息:

Pod DNS 查询
  ↓
/etc/resolv.conf → nameserver 10.96.0.10(CoreDNS ClusterIP)
  ↓
CoreDNS
  ├── kubernetes 插件:处理 .cluster.local 域名
  ├── cache 插件:缓存 DNS 结果
  ├── forward 插件:转发外部查询到上游 DNS
  └── prometheus 插件:暴露 DNS 指标

默认 DNS 解析路径:

<service>.<namespace>.svc.cluster.local
# 短域名(同 namespace)
<service>
<service>.<namespace>

CoreDNS 配置优化

apiVersion: v1
kind: ConfigMap
metadata:
  name: coredns
  namespace: kube-system
data:
  Corefile: |
    .:53 {
      errors
      health {
        lameduck 5s
      }
      ready
      # K8s 插件配置
      kubernetes cluster.local in-addr.arpa ip6.arpa {
        pods insecure       # 创建 Pod A 记录
        fallthrough in-addr.arpa ip6.arpa
        ttl 30              # 缓存 TTL
      }
      # 缓存配置
      cache 30 {
        success 9984 300    # 成功响应缓存 5 分钟
        denial 9984 60      # NXDOMAIN 缓存 1 分钟
      }
      # 转发到外部 DNS
      forward . /etc/resolv.conf {
        max_concurrent 1000
      }
      # 循环避免热点
      loadbalance round_robin
      prometheus :9153
    }

生产优化

  • cache 调优:根据应用 DNS 查询频率调整 TTL
  • autopath:减少短域名查询的 search 域遍历(ndots:5 问题)
  • NodeLocal DNSCache:每个节点运行 DNS 缓存 DaemonSet,减少 CoreDNS 压力

7. 网络排错工具箱

常用诊断命令

# 1. 查看 Pod IP 和所在节点
kubectl get pods -o wide

# 2. Pod 内执行网络诊断
kubectl exec -it <pod> -- /bin/sh
  # Ping 测试
  ping <target-pod-ip>
  # DNS 解析
  nslookup kubernetes.default.svc.cluster.local
  # 端口连通
  nc -zv <service-ip> 80

# 3. 查看 Service 的 Endpoint
kubectl get endpoints <service>

# 4. 跨节点抓包
kubectl debug node/<node> -it --image=nicolaka/netshoot
  tcpdump -i any -n host <pod-ip>

CNI 专用工具

# Calico
calicoctl node status              # 查看 BGP 状态
calicoctl get ippool -o wide      # 查看 IP 池
kubectl logs -n calico-system -l k8s-app=calico-node

# Cilium
cilium status                      # Cilium 健康状态
cilium endpoint list               # 查看端点
cilium policy get                  # 查看策略
cilium monitor --type drop         # 查看被丢弃的包

# Flannel
kubectl logs -n kube-flannel -l app=flannel
# 查看子网分配
cat /run/flannel/subnet.env

常见网络问题

问题症状排查解决
Pod 无法访问 Service连接超时kubectl get endpoints检查 selector 标签匹配、Pod 是否 Running
DNS 解析失败nslookup 超时kubectl logs -n kube-system -l k8s-app=kube-dns检查 CoreDNS Pod 运行状态、NetworkPolicy 限制
跨节点 Pod 不通同节点通、跨节点不通检查 CNI 后端(VXLAN 端口、BGP 会话)防火墙放行 VXLAN 端口(8472/4789)
CNI IP 耗尽Pod 无法创建kubectl get ippools (Calico)扩容 IP 池或减小 blockSize

8. CNI 选型建议

场景推荐 CNI理由
小规模集群(<50 节点)Flannel 或 Calico简单够用
中大规模集群(50-500 节点)Calico (BGP) 或 Cilium性能 + 策略
需要 NetworkPolicyCalico 或 CiliumFlannel 不原生支持
需要 L7 策略(HTTP/gRPC)Cilium原生 eBPF L7 过滤
金融/高安全要求Cilium + Hubble 或 Calico Enterprise审计日志 + 策略
电信/NFV(多网卡)Multus + Calico/Cilium多网卡支持
vSphere/NSX 环境Antrea与 NSX 集成
阿里云/腾讯云 ACK/TKE托管集群自带(通常 Flannel 或 Terway)云厂商优化
AWS EKSVPC CNI(原生 AWS 网络)或 CalicoVPC 原生 IP 或 overlay

总结

主题核心要点
网络模型四大基本原则:唯一 IP、无 NAT、节点互通、Service 可达
CNI 规范ADD/CHECK/DEL 三大操作,支持链式调用
Flannel最简单,VXLAN 封装,适合入门和小集群
Calico功能全面,BGP 模式高性能,eBPF 加速
CiliumeBPF 原生,L7 策略,Hubble 可观测性,面向未来
Service 实现iptables(默认)→ ipvs(大规模)→ nftables(新方向)
IngressNGINX 主流,Gateway API 为未来标准
DNSCoreDNS 默认,NodeLocal DNSCache 减负载
排错describe pod → endpoint → service → CNI 日志 → tcpdump

网络是 Kubernetes 的基石,也是最容易出问题的环节。选择合适的 CNI 插件、合理配置 Service 和 NetworkPolicy,是保障集群稳定运行的关键。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「云原生」更多文章

  1. Kubernetes多集群联邦:Karmada、Crossplane与Istio多集群实战
  2. CNCF云原生技术全景图:从毕业项目到前沿方向
  3. 容器运行时深度解析:从runc到containerd到安全容器