4. 网络策略基础:CiliumNetworkPolicy 与 CiliumClusterwideNetworkPolicy 的 CRD 定义与生效机制

Cilium 的网络策略模型基于 Kubernetes 的 NetworkPolicy 语义进行了深度扩展,通过两个核心 CRD(Custom Resource Definition)实现:CiliumNetworkPolicy(命名空间级别)与 CiliumClusterwideNetworkPolicy(集群级别)。理解这两个 CRD 的定义结构、字段语义以及生效机制,是掌握 Cilium 网络隔离与安全策略的基础。

4.1 两个 CRD 的定位与差异

特性 CiliumNetworkPolicy (CNP) CiliumClusterwideNetworkPolicy (CCNP)
作用域 仅作用于特定命名空间 作用于整个集群,跨所有命名空间
资源名称 ciliumnetworkpolicies.cilium.io ciliumclusterwidenetworkpolicies.cilium.io
Endpoint 选择器 默认限定在策略所在命名空间 可跨命名空间选择 Pod/Service
典型场景 微服务间细粒度隔离、租户内策略 全局基线策略、DNS 规则、监控/日志组件白名单
优先级 与 CCNP 共同生效,无显式优先级 与 CNP 共同生效,无显式优先级
关键理解:CNP 是命名空间隔离的“租户内策略”,CCNP 是集群管理员定义的“全局护栏”。两者在 Cilium Agent 内部被统一处理为 Endpoint 策略,不存在覆盖关系,而是叠加生效。

4.2 CRD 定义结构解析

两个 CRD 共享相同的核心 Spec 结构,仅顶层元数据不同。以下以 CiliumNetworkPolicy 为例展示其 YAML 定义骨架:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: l7-http-allow
  namespace: production
spec:
  description: "Allow HTTP GET to /api/v1 from frontend"
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/api/v1"
  egress:
    - toEndpoints:
        - matchLabels:
            app: database
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP

4.2.1 核心字段说明

  • endpointSelector:必填字段,通过 LabelSelector 选择策略作用的 Pod 集合。CNP 中仅匹配当前命名空间的 Pod;CCNP 中可跨命名空间匹配。
  • ingress / egress:分别定义入站和出站规则。每个规则块内可包含:
    • fromEndpoints / toEndpoints:基于 Label 的端点选择器
    • fromCIDR / toCIDR:基于 IP 段的规则(适用于外部流量)
    • toPorts:端口与协议定义,支持 L3/L4 以及 L7 规则
    • toFQDNs:基于 DNS 名称的出站规则(需开启 DNS 代理)
  • enableDefaultDeny:隐式行为。一旦为某个方向(ingress/egress)定义了规则,Cilium 会自动为该方向添加默认拒绝规则,未匹配的流量将被丢弃。

4.3 生效机制:从 CRD 到 BPF 映射

Cilium 网络策略的生效并非简单的 YAML 解析,而是经过多层转换最终生成 BPF 映射中的键值对。下图展示了完整的策略生效链路:

Cilium 网络策略生效机制:从 CRD 到 BPF 映射 阶段 1:CRD 定义 CNP / CCNP YAML kube-apiserver 阶段 2:Operator 监听 Cilium Operator 缓存 gRPC 分发 阶段 3:Agent 策略引擎 Selector → Identity 解析 阶段 4:Identity 分配 Label → Security Identity 阶段 5:BPF Map 生成 Policy Map / CIDR Map 阶段 6:BPF 数据路径执行 关键转换逻辑 • endpointSelector → 匹配 Pod 的 Security Identity • fromEndpoints → 源端 Identity 白名单 • toPorts + L7 rules → BPF 中的端口 + HTTP 方法/路径匹配

4.4 策略生效的原子操作:Identity 与 Selector 解析

Cilium 不直接使用 Pod IP 或命名空间作为策略匹配依据,而是引入 Security Identity 概念。每个 Pod 根据其标签组合被分配一个 24 位整数 Identity。策略中的 endpointSelector 和 fromEndpoints 最终被解析为 Identity 集合,写入 BPF Policy Map。

Identity 分配示例:
Pod 标签 app=frontend, version=v2 → Identity 1678
Pod 标签 app=backend → Identity 2345
策略规则 fromEndpoints: {matchLabels: {app: frontend}} → 允许 Identity 1678 的流量

4.4.1 策略合并与冲突处理

当多个 CNP/CCNP 作用于同一个 Endpoint 时,Cilium 采用以下合并规则:

  • 同一方向(ingress/egress)的规则取并集:只要任意一个策略允许某流量,该流量即被允许。
  • 默认拒绝是隐式的:一旦有规则定义,未显式允许的流量被拒绝。若完全没有规则,则默认允许所有流量(与 Kubernetes 原生 NetworkPolicy 行为一致)。
  • L7 规则与 L3/L4 规则共存:L7 规则是 L3/L4 规则的超集,必须先通过 L3/L4 检查,再进入 L7 代理进行 HTTP/gRPC 方法匹配。

4.5 实战:编写一个典型的 CNP 与 CCNP 组合

以下示例展示如何通过 CNP 实现微服务隔离,同时通过 CCNP 设置全局 DNS 白名单:

# CNP:只允许 frontend 访问 backend 的 8080 端口
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: backend-ingress
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: frontend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
---
# CCNP:所有命名空间的 Pod 只能解析内部 DNS
apiVersion: cilium.io/v2
kind: CiliumClusterwideNetworkPolicy
metadata:
  name: global-dns-egress
spec:
  endpointSelector: {}  # 匹配所有 Pod
  egress:
    - toEndpoints:
        - matchLabels:
            k8s:io.kubernetes.pod.namespace: kube-system
            k8s-app: kube-dns
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP
    - toFQDNs:
        - matchName: "*.internal.example.com"
注意:CCNP 中使用 endpointSelector: {} 表示匹配集群中所有 Pod。这种全局策略应谨慎使用,避免意外阻断关键系统组件通信。建议先使用 matchLabels 限定范围,验证后再放宽。

4.6 策略生效验证与调试

部署策略后,可通过以下命令验证其是否按预期生效:

# 查看特定 Pod 的详细策略状态
kubectl exec -n kube-system cilium-xxxxx -- cilium endpoint list

# 查看某个 Endpoint 的 Identity 和关联策略
kubectl exec -n kube-system cilium-xxxxx -- cilium endpoint get 1234

# 实时跟踪策略匹配情况(需开启 monitor)
kubectl exec -n kube-system cilium-xxxxx -- cilium monitor --type policy-verdict

通过 cilium monitor 输出的策略判决日志,可以快速定位流量被允许或拒绝的原因,结合 Identity 编号反查标签,是调优网络策略的核心手段。