4. 网络隔离策略:NetworkPolicy 原理、Ingress/Egress 规则、多租户网络隔离实战、Calico/Cilium 集成

在多租户 Kubernetes 集群中,网络隔离是防止租户间横向移动攻击、保障数据合规与业务边界的关键防线。本章从 Kubernetes 原生 NetworkPolicy 的声明式模型出发,逐步深入到 Ingress/Egress 规则设计、多租户网络隔离实战模式,并对比 Calico 与 Cilium 两大主流 CNI 插件的集成方案。

4.1 NetworkPolicy 核心原理

NetworkPolicy 是 Kubernetes 中用于控制 Pod 间网络访问的 API 资源。它通过标签选择器(Label Selector)定义“谁可以访问谁”,而非基于 IP 地址或 CIDR 块,从而与 Pod 的动态生命周期解耦。

概念 说明 示例
PodSelector 指定策略生效的目标 Pod 集合 matchLabels: { app: frontend }
PolicyTypes 声明策略类型:Ingress、Egress 或两者 Ingress / Egress
Ingress 规则 定义允许进入 Pod 的流量来源 from: - podSelector: ...
Egress 规则 定义允许 Pod 外发的流量目标 to: - ipBlock: ...
默认拒绝 一旦有 NetworkPolicy 匹配 Pod,未显式允许的流量默认被拒绝 白名单模型
关键理解: NetworkPolicy 是“白名单”机制。只要 Namespace 中存在一条匹配 Pod 的 NetworkPolicy,该 Pod 的所有未显式允许的入站或出站流量都会被拒绝。因此,多租户隔离通常从“默认拒绝所有”策略开始,再逐条开放必要规则。

4.2 Ingress / Egress 规则详解

4.2.1 Ingress 规则

Ingress 规则控制进入 Pod 的流量。支持三种来源选择器:

  • podSelector:允许来自同一 Namespace 内特定标签的 Pod。
  • namespaceSelector:允许来自特定 Namespace 的所有 Pod。
  • ipBlock:允许来自特定 CIDR 范围的流量(如集群外服务或监控系统)。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: tenant-a
spec:
  podSelector:
    matchLabels:
      app: backend
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

4.2.2 Egress 规则

Egress 规则控制 Pod 对外发起的连接。同样支持三种目标选择器,常用于限制 Pod 访问外部数据库、DNS 或互联网。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: restrict-egress-dns-only
  namespace: tenant-b
spec:
  podSelector:
    matchLabels:
      app: worker
  policyTypes:
  - Egress
  egress:
  - to:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          k8s-app: kube-dns
    ports:
    - protocol: UDP
      port: 53
  - to:
    - ipBlock:
        cidr: 10.0.0.0/8
        except:
        - 10.96.0.0/12  # 排除 Service CIDR
常见陷阱: 当同时定义 Ingress 和 Egress 规则时,务必检查 policyTypes 字段是否包含两者。如果只写 Ingress,Egress 规则不会生效,Pod 仍可自由外发流量。反之亦然。

4.3 多租户网络隔离实战模式

在多租户场景中,网络隔离通常采用分层策略:

  1. 租户级 Namespace 隔离:每个租户独占一个 Namespace,通过 RBAC 限制跨 Namespace 访问。
  2. 默认拒绝所有流量:在每个租户 Namespace 中部署一条拒绝所有 Ingress/Egress 的基线策略。
  3. 按需开放规则:根据业务需求,逐条添加允许特定 Pod 间通信的规则。
  4. 共享服务例外:允许访问集群 DNS、监控、日志收集等共享基础设施。
层级 策略示例 作用范围
基线拒绝 拒绝所有 Ingress + Egress 每个租户 Namespace
租户内部通信 允许同 Namespace 内特定标签 Pod 互访 单个 Namespace
跨租户服务 允许访问共享 Namespace 中的服务 跨 Namespace
外部访问 允许访问特定 CIDR 或外部 API 集群外
实战建议: 使用 namespaceSelector 配合 matchLabels 实现跨租户的精细控制。例如,为共享监控 Namespace 打上 role: monitoring 标签,然后在租户策略中允许 Egress 到该标签的 Namespace。
多租户网络隔离策略分层架构 租户 A Namespace frontend backend NetworkPolicy: 默认拒绝 + 内部允许 租户 B Namespace worker cache NetworkPolicy: 默认拒绝 + 内部允许 共享服务 Namespace (monitoring, logging, dns) Prometheus Fluentd CoreDNS Egress 允许 Egress 允许 X 禁止 说明: 每个租户 Namespace 内部通过 NetworkPolicy 实现默认拒绝 + 内部允许;跨租户流量被显式禁止;所有租户可 Egress 到共享服务 Namespace 中的基础设施 Pod。

4.4 Calico 与 Cilium 集成方案

Kubernetes 原生 NetworkPolicy 功能有限(仅支持 L3/L4 过滤),且依赖 CNI 插件实现。Calico 和 Cilium 是两大主流增强方案,各自提供了更丰富的网络隔离能力。

特性 Calico Cilium
数据平面 eBPF / iptables / Windows HNS eBPF(内核级)
L3/L4 策略 完全兼容 Kubernetes NetworkPolicy 完全兼容 Kubernetes NetworkPolicy
L7 策略 通过 Envoy sidecar(Application Layer Policy) 原生 eBPF L7 策略(HTTP/gRPC/Kafka/DNS)
全局网络策略 GlobalNetworkPolicy(跨 Namespace) CiliumClusterwideNetworkPolicy
DNS 策略 支持基于 FQDN 的 Egress 规则 原生支持基于 FQDN 的 Egress 规则
可观测性 Calico Enterprise / Calico Cloud Hubble(内置 eBPF 可观测性)
性能开销 低(eBPF 模式) 极低(纯 eBPF 内核态)

4.4.1 Calico 集成要点

  • 安装模式:推荐使用 eBPF 数据平面以获得最佳性能,需内核版本 ≥ 5.3。
  • 全局网络策略:使用 GlobalNetworkPolicy 定义跨 Namespace 的基线规则,例如“禁止所有跨租户流量”。
  • FQDN 策略:通过 DNS 字段在 Egress 规则中允许访问特定域名,避免硬编码 IP。
  • 网络隔离层级:Calico 支持在 Namespace、节点、甚至主机级别实施隔离。
# Calico 全局网络策略示例:禁止所有跨 Namespace 流量
apiVersion: projectcalico.org/v3
kind: GlobalNetworkPolicy
metadata:
  name: deny-cross-namespace
spec:
  selector: all()
  ingress:
  - action: Deny
    source:
      namespaceSelector: "projectcalico.org/name != 'kube-system'"
      notNamespaceSelector: "projectcalico.org/name == '${NAMESPACE}'"
  egress:
  - action: Deny
    destination:
      namespaceSelector: "projectcalico.org/name != 'kube-system'"
      notNamespaceSelector: "projectcalico.org/name == '${NAMESPACE}'"

4.4.2 Cilium 集成要点

  • 核心优势:原生 eBPF 实现,无需 iptables 或 sidecar,性能与可观测性极强。
  • L7 策略:可直接在 NetworkPolicy 中定义 HTTP 方法、路径、gRPC 服务等应用层规则。
  • Hubble:内置网络可观测性工具,实时查看流量、策略命中与拒绝日志。
  • ClusterMesh:支持多集群网络隔离策略统一管理。
# Cilium L7 HTTP 策略示例:仅允许 GET /api/v1/orders
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-orders-api
  namespace: tenant-a
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
      rules:
        http:
        - method: "GET"
          path: "/api/v1/orders"
选型建议:
  • 如果团队需要 L7 策略 + 原生可观测性,且内核版本 ≥ 5.10,优先选择 Cilium。
  • 如果团队已有 Calico 生态(如 Calico Enterprise),或需要 Windows 节点支持,选择 Calico。
  • 两者都支持 Kubernetes 原生 NetworkPolicy,迁移成本较低。
Calico vs Cilium 网络隔离架构对比 Calico 架构 Kubernetes NetworkPolicy (L3/L4 兼容) GlobalNetworkPolicy (跨 Namespace 基线策略) Application Layer Policy (通过 Envoy sidecar 实现 L7) 数据平面:eBPF / iptables (内核 ≥ 5.3 推荐 eBPF) Cilium 架构 Kubernetes NetworkPolicy (L3/L4 兼容) CiliumNetworkPolicy (L7) (原生 HTTP/gRPC/Kafka 策略) Hubble 可观测性 (实时流量、策略命中/拒绝日志) 数据平面:纯 eBPF (内核 ≥ 5.10 推荐) 对比 Calico 通过 Envoy sidecar 实现 L7 策略,适合已有 Envoy 生态的团队;Cilium 原生 eBPF L7 策略性能更高,且内置 Hubble 可观测性,适合追求极致性能与可观测性的场景。

4.5 实战:多租户网络隔离策略部署流程

  1. 确认 CNI 插件:检查集群当前使用的 CNI 是否支持 NetworkPolicy(Calico、Cilium、Weave、Antrea 等支持)。
  2. 创建基线拒绝策略:为每个租户 Namespace 创建默认拒绝所有 Ingress 和 Egress 的 NetworkPolicy。
  3. 开放共享服务:添加 Egress 规则允许访问 kube-system 中的 CoreDNS、监控 Namespace 中的 Prometheus 等。
  4. 租户内部通信:根据应用架构,添加允许同 Namespace 内特定 Pod 间通信的 Ingress 规则。
  5. 跨租户例外:如果存在合法的跨租户服务调用(如共享 API 网关),使用 namespaceSelector 精确开放。
  6. 验证与监控:使用 kubectl describe networkpolicy 查看策略详情,结合 Hubble(Cilium)或 calicoctl(Calico)验证流量是否被正确允许或拒绝。
避坑指南:
  • 不要忘记在 policyTypes 中同时声明 Ingress 和 Egress,否则未声明的方向不受限制。
  • 使用 ipBlock 时注意排除 Service CIDR 和 Pod CIDR,避免意外阻断集群内部通信。
  • 在 Cilium 中启用 L7 策略前,确保已开启 Hubble 并配置正确的端口映射。