3、Cilium网络策略基础:NetworkPolicy资源定义、L3/L4策略、基于标签的访问控制

在云原生灾备与蓝绿发布场景中,网络策略是保障流量安全迁移的核心防线。Cilium 基于 eBPF 实现的网络策略不仅兼容 Kubernetes 原生 NetworkPolicy,还提供了更精细的 L3/L4 乃至 L7 控制能力。本章聚焦策略基础:资源定义、L3/L4 规则以及基于标签的访问控制模型。

3.1 Kubernetes NetworkPolicy 资源定义

Kubernetes 原生 NetworkPolicy 是一种命名空间级别的资源,通过 spec.podSelector 选定目标 Pod,再通过 ingress 和 egress 规则定义允许的流量。Cilium 完全兼容该标准,并在此基础上扩展了 CiliumNetworkPolicy 自定义资源。

字段 类型 说明
apiVersion string networking.k8s.io/v1(原生)或 cilium.io/v2(Cilium CRD)
spec.podSelector LabelSelector 选择策略生效的目标 Pod 集合
spec.policyTypes []PolicyType 声明策略类型:Ingress、Egress 或两者
spec.ingress[].from []Peer 入站流量来源:IP 段、命名空间选择器、Pod 选择器
spec.egress[].to []Peer 出站流量目标:IP 段、命名空间选择器、Pod 选择器
spec.ingress[].ports []Port 入站允许的端口与协议(TCP/UDP/SCTP)
spec.egress[].ports []Port 出站允许的端口与协议
关键原则:NetworkPolicy 默认拒绝所有未显式允许的流量。一旦命名空间中有任何 NetworkPolicy 选中了某个 Pod,该 Pod 的未匹配流量将被丢弃。Cilium 遵循同样的白名单模型。

3.2 L3/L4 策略:IP 与端口控制

L3 策略基于源/目标 IP 地址或 CIDR 段进行流量过滤;L4 策略则在 L3 基础上增加端口和协议的匹配。Cilium 通过 eBPF 将规则直接注入内核网络栈,实现高性能的 L3/L4 策略执行。

3.2.1 L3 策略示例:基于 IP 段的访问控制

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: l3-ip-restrict
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: api-server
  policyTypes:
  - Ingress
  ingress:
  - from:
    - ipBlock:
        cidr: 10.0.0.0/24
        except:
        - 10.0.0.5/32
    ports:
    - protocol: TCP
      port: 8080

上述策略仅允许来自 10.0.0.0/24 网段(排除 10.0.0.5)的 TCP 流量访问 app=api-server Pod 的 8080 端口。

3.2.2 L4 策略示例:端口与协议限制

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: l4-port-restrict
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: database
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: api-server
    toPorts:
    - ports:
      - port: "5432"
        protocol: TCP
      - port: "5432"
        protocol: UDP

该 Cilium 策略仅允许 app=api-server 的 Pod 通过 TCP/UDP 5432 端口访问 app=database 的 Pod,其他流量一律拒绝。

灾备提示:在蓝绿发布切换时,L3/L4 策略应提前在目标集群或命名空间部署,避免因 IP 段或端口不一致导致服务中断。建议使用 Cilium 的 toFQDN 规则处理外部依赖的 IP 变动。

3.3 基于标签的访问控制模型

Cilium 将 Kubernetes 标签作为一等公民用于策略定义。相比 IP 段,标签模型更适应动态扩缩容和灾备迁移场景——Pod 重启或漂移后标签不变,策略自动生效。

3.3.1 标签选择器类型

选择器类型 Cilium 字段 匹配范围 典型用途
endpointSelector spec.endpointSelector 本命名空间内 Pod 定义策略目标 Pod
fromEndpoints ingress[].fromEndpoints[] 本命名空间内 Pod 入站流量来源
toEndpoints egress[].toEndpoints[] 本命名空间内 Pod 出站流量目标
fromRequires ingress[].fromRequires[] 跨命名空间 强制要求来源命名空间标签
toRequires egress[].toRequires[] 跨命名空间 强制要求目标命名空间标签

3.3.2 标签策略示例:微服务隔离

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: label-based-isolation
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: ingress-gateway
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP
  egress:
  - toEndpoints:
    - matchLabels:
        app: backend
    toPorts:
    - ports:
      - port: "3000"
        protocol: TCP

该策略实现:frontend Pod 仅接收来自 ingress-gateway 的 80 端口流量,仅允许访问 backend Pod 的 3000 端口。标签变更时策略自动适配,无需修改 IP 规则。

灾备注意事项:跨集群灾备场景中,标签命名规范必须保持一致。如果蓝绿集群使用不同的标签体系,Cilium 策略将无法正确匹配,导致流量被拒绝。建议在 CI/CD 流水线中统一注入标签标准。

3.4 策略执行流程与 eBPF 数据面

Cilium 将 NetworkPolicy 转换为 eBPF 程序挂载到网络钩子点。下图展示了从策略定义到内核执行的完整链路:

Cilium 网络策略执行流程 用户提交策略 K8s API Server Cilium Agent eBPF Map 内核网络栈 策略匹配引擎 允许 / 拒绝 YAML / kubectl apply CRD 存储 策略转换为 eBPF

流程说明:用户通过 kubectl apply 提交策略 → K8s API Server 存储至 etcd → Cilium Agent 监听变化 → 将策略编译为 eBPF 程序并加载到内核 → 流量经过内核网络栈时触发 eBPF 钩子 → 策略匹配引擎根据标签/IP/端口决策 → 最终执行允许或拒绝动作。

3.5 策略优先级与冲突处理

当多个 NetworkPolicy 同时选中同一 Pod 时,Cilium 遵循以下规则:

  • 白名单叠加:所有匹配策略的允许规则取并集,只要有一条策略允许某流量,该流量即被放行。
  • 默认拒绝:如果没有任何策略显式允许某流量,则默认拒绝。
  • CiliumNetworkPolicy 优先级:与原生 NetworkPolicy 同级别,两者叠加生效。Cilium 的 fromRequires/toRequires 可强制附加约束。
  • 策略顺序无关:Kubernetes 和 Cilium 都不依赖策略创建顺序,最终结果由标签匹配和规则并集决定。
灾备最佳实践:在蓝绿发布前,使用 cilium connectivity test 验证策略是否按预期生效。建议将策略定义与 Helm Chart 或 Kustomize 模板绑定,确保两套环境策略一致。

3.6 本章小结

Cilium 网络策略以 Kubernetes 原生 NetworkPolicy 为基础,通过标签驱动实现动态、可移植的 L3/L4 访问控制。在灾备场景中,标签模型避免了 IP 变动带来的策略失效问题,而 eBPF 数据面保证了策略执行的高性能。掌握资源定义、L3/L4 规则和标签选择器,是后续实现蓝绿发布流量迁移和网络灾备验证的前提。