4. CiliumNetworkPolicy 基础:策略模型与编写

CiliumNetworkPolicy (CNP) 是 Cilium 提供的 Kubernetes 自定义资源,用于定义基于 eBPF 的数据平面访问控制规则。与标准 Kubernetes NetworkPolicy 相比,CNP 支持 L3/L4 以及 L7 协议过滤,并引入更灵活的标签选择机制。本章聚焦于策略模型、标签选择器与 L3/L4 策略编写。

4.1 策略模型:Ingress 与 Egress

CiliumNetworkPolicy 遵循 Kubernetes 网络策略的通用模型,将流量分为两个方向:

  • Ingress(入站):控制进入 Pod 的流量。定义哪些来源可以访问目标 Pod。
  • Egress(出站):控制从 Pod 发出的流量。定义目标 Pod 可以访问哪些外部端点。

每个策略规则可以包含多个 fromEndpoints(Ingress)或 toEndpoints(Egress)选择器,以及可选的端口与协议限制。默认情况下,未匹配任何策略的 Pod 允许所有流量;一旦应用了 CNP,未显式允许的流量将被拒绝。

关键概念: Cilium 的策略模型是“白名单”机制。只有被规则明确允许的流量才会通过,其余全部丢弃。这与 Kubernetes NetworkPolicy 的默认拒绝行为一致,但 Cilium 提供了更细粒度的控制能力。
CiliumNetworkPolicy 策略模型:Ingress 与 Egress CiliumNetworkPolicy 策略模型 目标 Pod app=frontend Ingress 来源 app=ingress-gateway 允许入站 Egress 目标 app=backend 允许出站 策略生效逻辑 未匹配任何规则的流量默认拒绝 | 支持同时定义 Ingress 和 Egress 规则

4.2 标签选择器与 EndpointSelector

Cilium 使用 EndpointSelector 作为核心选择机制,基于 Kubernetes 标签(Labels)匹配 Pod。与 Kubernetes NetworkPolicy 的 podSelector 类似,但 Cilium 支持更丰富的匹配表达式。

选择器类型 YAML 字段 匹配行为 示例
标签匹配(matchLabels) matchLabels 精确匹配所有指定标签的键值对 app: frontend
表达式匹配(matchExpressions) matchExpressions 支持 In、NotIn、Exists、DoesNotExist 操作符 tier In [web, api]
任意标签(空选择器) 不指定 匹配所有 Endpoint(谨慎使用) —
实践要点: 在编写 CNP 时,优先使用 matchLabels 进行精确匹配;当需要基于标签集合进行灵活筛选时,使用 matchExpressions。避免使用空选择器,以免意外开放过多流量。

4.3 L3/L4 网络策略编写

L3 策略基于 IP 地址或 CIDR 进行控制;L4 策略则在 L3 基础上增加端口和传输层协议(TCP/UDP)限制。CiliumNetworkPolicy 通过 fromEndpoints/toEndpoints 实现 L3 选择,通过 toPorts 实现 L4 限制。

4.3.1 基础 L3/L4 策略示例

以下示例展示一个完整的 CNP,允许来自 app=ingress-gateway 的 Pod 访问 app=frontend 的 Pod 的 80/TCP 端口:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-ingress-to-frontend
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: ingress-gateway
    toPorts:
    - ports:
      - port: "80"
        protocol: TCP

4.3.2 Egress 策略示例

以下示例限制 app=frontend 的 Pod 只能访问 app=backend 的 Pod 的 8080/TCP 端口:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: restrict-frontend-egress
  namespace: default
spec:
  endpointSelector:
    matchLabels:
      app: frontend
  egress:
  - toEndpoints:
    - matchLabels:
        app: backend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP

4.3.3 使用 CIDR 的 L3 策略

当需要控制对外部 IP 范围的访问时,使用 toCIDR 或 fromCIDR:

spec:
  egress:
  - toCIDR:
    - 10.0.0.0/24
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP
注意: CIDR 策略仅适用于 L3 控制,不涉及 Pod 标签选择。使用 CIDR 时,确保目标 IP 范围准确,避免误拦截或误放行。
L3/L4 策略匹配流程 L3/L4 策略匹配流程 流量到达 Pod L3 匹配 来源/目标 IP 或标签 L4 匹配 端口 + 协议 (TCP/UDP) 允许通过 匹配失败则拒绝 L3 不匹配 → 丢弃 L4 不匹配 → 丢弃 两者都匹配 → 放行

4.4 策略编写最佳实践

  • 最小权限原则:只允许必要的流量,拒绝其余所有。从零开始逐步添加规则。
  • 使用命名空间隔离:结合 fromEndpoints 的 matchLabels 和命名空间选择器,限制跨命名空间访问。
  • 验证策略生效:使用 cilium connectivity test 或 kubectl exec 进行端到端验证。
  • 避免重叠规则冲突:Cilium 会合并所有匹配的规则,但建议保持规则清晰,避免逻辑冲突。
  • 使用注释记录策略目的:在 YAML 中添加 description 注释,便于团队维护。
调试技巧: 使用 kubectl describe ciliumnetworkpolicy <policy-name> 查看策略状态;使用 cilium endpoint list 检查 Pod 是否被正确识别并应用了策略。