4. Cilium 高级网络策略:基于 FQDN、HTTP 方法、ServiceAccount 与 CIDR 的策略

在 Kubernetes 生产环境中,仅依赖传统的 IP 与端口(L3/L4)网络策略往往无法满足微服务架构下的精细化访问控制需求。Cilium 基于 eBPF 的数据路径允许在 L7 层和应用身份层执行策略,实现“零信任”网络模型。本章将深入解析四种高级策略类型:基于 FQDN 的出站策略、基于 HTTP 方法的 API 策略、基于 Kubernetes ServiceAccount 的身份策略,以及传统的 CIDR 策略。

4.1 基于 FQDN 的策略(Fully Qualified Domain Name)

传统 Kubernetes NetworkPolicy 无法直接通过域名控制出站流量,因为 Pod IP 是动态的。Cilium 的 FQDN 策略允许你使用域名(如 api.example.com)定义出站规则,Cilium 代理会实时解析 DNS 并动态更新 eBPF 映射表。

适用场景: Pod 需要访问外部 API 服务(如 AWS S3、Stripe、GitHub),但禁止访问其他外网 IP。

4.1.1 FQDN 策略工作原理

  1. DNS 嗅探: Cilium 代理通过 eBPF 程序监控 Pod 发出的 DNS 查询(UDP/53)。
  2. 域名缓存: 将解析出的 IP 地址与域名关联,并写入 eBPF Map,设置 TTL 过期时间。
  3. 策略匹配: 当 Pod 发起 TCP 连接时,eBPF 程序检查目标 IP 是否匹配已缓存的 FQDN 条目。
  4. 动态更新: 当 DNS 记录变更或 TTL 过期,Cilium 自动更新 eBPF 映射,无需重启 Pod。
关键优势: 无需预先知道外部服务的 IP 地址范围,策略定义与 DNS 解耦,运维更灵活。

4.1.2 FQDN 策略 YAML 示例

以下策略允许 frontend 命名空间中的 Pod 仅能访问 api.stripe.com 和 s3.amazonaws.com,并拒绝所有其他外部流量。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "fqdn-egress-external"
  namespace: frontend
spec:
  endpointSelector:
    matchLabels:
      app: web-frontend
  egress:
    - toFQDNs:
        - matchName: "api.stripe.com"
        - matchPattern: "*.s3.amazonaws.com"
    - toEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": kube-system
      toPorts:
        - ports:
            - port: "53"
              protocol: UDP
          rules:
            dns:
              - matchPattern: "*"
注意: FQDN 策略必须包含 DNS 解析规则(toPorts 中的 UDP 53),否则 Cilium 无法解析域名,策略将失效。建议使用 matchPattern: "*" 允许所有 DNS 查询,或限制到特定 DNS 服务器。

4.1.3 FQDN 策略对比表

特性 matchName matchPattern
匹配方式 精确域名匹配 通配符前缀匹配(Glob 模式)
示例 api.stripe.com *.s3.amazonaws.com
性能 高(哈希查找) 中(模式匹配)
适用场景 固定域名,如内部 API 多子域名,如 CDN、云存储

4.2 基于 HTTP 方法的策略(L7 协议感知)

Cilium 通过代理模式(Envoy)或原生 eBPF 解析 HTTP/1.x、HTTP/2 和 gRPC 流量,允许在 L7 层基于方法(GET、POST、PUT、DELETE)、路径、Header 等字段实施细粒度访问控制。

4.2.1 HTTP 方法策略结构

策略定义在 toPorts.rules.http 字段中,支持以下匹配条件:

  • method: HTTP 方法(GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS)。
  • path: URL 路径,支持精确匹配和前缀匹配(/api/v1/)。
  • headers: 自定义 Header 键值对匹配。
  • host: HTTP Host Header 匹配。

4.2.2 策略示例:只允许 GET 请求

以下策略允许 frontend 命名空间中的 Pod 仅能对 backend 服务发起 GET 请求,拒绝 POST、PUT、DELETE 等写操作。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "l7-http-get-only"
  namespace: frontend
spec:
  endpointSelector:
    matchLabels:
      app: web-frontend
  egress:
    - toEndpoints:
        - matchLabels:
            app: backend
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
          rules:
            http:
              - method: "GET"
                path: "/api/v1/products"
最佳实践: 对于 RESTful API,建议将写操作(POST/PUT/DELETE)限制在特定的 ServiceAccount 或命名空间,而读操作(GET)可以开放给更多前端服务。

4.2.3 HTTP 策略与 ServiceMesh 对比

维度 Cilium L7 HTTP 策略 Istio/Envoy Sidecar
数据路径 eBPF + 可选 Envoy 代理 Sidecar 代理(iptables 重定向)
延迟开销 低(< 1ms,eBPF 快速路径) 中(1-3ms,Sidecar 处理)
资源消耗 低(无 Sidecar 容器) 高(每个 Pod 额外 Sidecar)
协议支持 HTTP/1.x, HTTP/2, gRPC HTTP/1.x, HTTP/2, gRPC, TCP
策略复杂度 中等(YAML 定义) 高(VirtualService, DestinationRule)

4.3 基于 Kubernetes ServiceAccount 的策略

在零信任模型中,网络策略应基于“身份”而非“IP”。Cilium 原生支持通过 toServices 和 fromEndpoints 中的 matchLabels 引用 ServiceAccount,实现身份感知的访问控制。

4.3.1 ServiceAccount 策略原理

每个 Pod 都关联一个 ServiceAccount。Cilium 通过 Kubernetes API 监听 ServiceAccount 与 Pod 的绑定关系,并将身份信息注入 eBPF 程序。策略匹配时,直接检查 Pod 的 ServiceAccount 标签,而非 IP 地址。

核心优势: 即使 Pod 被重新调度、IP 发生变化,策略依然有效。身份与 IP 解耦,适合动态集群。

4.3.2 策略示例:限制特定 ServiceAccount 的访问

以下策略只允许 service-account: payment-processor 的 Pod 访问 database 服务的 3306 端口。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "sa-to-database"
  namespace: payment
spec:
  endpointSelector:
    matchLabels:
      app: database
  ingress:
    - fromEndpoints:
        - matchLabels:
            "k8s:io.kubernetes.pod.namespace": payment
            "k8s:app.kubernetes.io/name": payment-processor
      toPorts:
        - ports:
            - port: "3306"
              protocol: TCP
注意: ServiceAccount 标签通常以 k8s: 前缀表示 Kubernetes 原生标签。Cilium 会自动将 ServiceAccount 名称转换为标签 k8s:io.kubernetes.pod.serviceaccount,但更推荐使用自定义 matchLabels 结合命名空间限制。

4.3.3 身份策略与 CIDR 策略对比

维度 ServiceAccount 策略 CIDR 策略
匹配依据 Kubernetes 身份(ServiceAccount) IP 地址范围
动态性 高(Pod 重建后自动适配) 低(IP 变化需手动更新)
适用场景 集群内部微服务间访问 集群外部系统、传统 VM 环境
安全性 高(身份不可伪造) 中(IP 可被欺骗)

4.4 CIDR 策略(Classless Inter-Domain Routing)

CIDR 策略是 Cilium 中最基础的 L3 层策略,用于控制 Pod 对特定 IP 地址段的访问。虽然不如 FQDN 或 ServiceAccount 策略灵活,但在与外部传统系统(如物理数据库、VPN 网关)通信时不可或缺。

4.4.1 CIDR 策略语法

使用 toCIDR 和 fromCIDR 字段,支持 IPv4 和 IPv6 地址段。

apiVersion: "cilium.io/v2"
kind: CiliumNetworkPolicy
metadata:
  name: "cidr-egress-external-db"
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  egress:
    - toCIDR:
        - 10.100.20.0/24
        - 192.168.1.100/32
      toPorts:
        - ports:
            - port: "5432"
              protocol: TCP

4.4.2 CIDR 策略与集群网络冲突

重要: 当 toCIDR 定义的 IP 段与 Kubernetes Pod CIDR 或 Service CIDR 重叠时,Cilium 会优先匹配集群内部端点策略(toEndpoints)。建议将 CIDR 策略仅用于外部 IP,内部通信使用 toEndpoints 或 toServices。

4.4.3 CIDR 策略最佳实践

  • 最小化范围: 尽量使用 /32 精确 IP 或 /24 小段,避免开放大段公网 IP。
  • 结合 FQDN: 对于外部 API,优先使用 FQDN 策略;仅当外部服务无固定域名或 DNS 不可靠时,才使用 CIDR。
  • 审计与监控: 使用 cilium monitor 或 Hubble 观察 CIDR 策略命中情况,定期清理未使用的规则。

4.5 四种策略的协同架构

在实际生产环境中,这四种策略通常组合使用,形成分层防御体系。下图展示了典型微服务架构中的策略部署模型。

Cilium 高级网络策略协同架构 Cilium 高级网络策略协同架构 Kubernetes 集群内部 外部网络 / 传统系统 Frontend Pod SA: web-frontend Backend Pod SA: api-server Database Pod SA: db-reader 外部 API api.stripe.com 传统数据库 10.100.20.0/24 CDN 服务 *.cdn.example.com FQDN 策略 HTTP 方法策略 SA 身份策略 CIDR 策略 GET /api/v1/products 内部 Pod 外部服务 策略标注

4.6 策略冲突与优先级

当多种策略类型同时作用于同一个 Pod 时,Cilium 遵循以下优先级规则:

  1. Deny 规则优先: 任何显式的 deny 规则(CiliumNetworkPolicy 或 CiliumClusterwideNetworkPolicy 中的 deny 字段)优先级最高。
  2. L7 规则覆盖 L3/L4: 如果同时存在 L7 HTTP 规则和 L3/L4 端口规则,L7 规则会进一步限制允许的 HTTP 方法、路径等。
  3. 最具体规则生效: 对于同一流量,匹配条件最具体的策略生效。例如,toFQDNs 中的 matchName 比 matchPattern 更具体。
  4. 默认拒绝: 如果没有显式允许规则,所有流量默认被拒绝(白名单模式)。
调试建议: 使用 cilium policy trace 命令模拟流量路径,查看哪些策略被命中。例如:cilium policy trace --src-k8s-pod default/frontend-pod --dst-k8s-pod default/backend-pod --dport 8080

4.7 本章小结

本章详细介绍了 Cilium 四种高级网络策略类型:

  • FQDN 策略: 通过域名控制出站流量,适合访问外部 API 和 CDN。
  • HTTP 方法策略: 在 L7 层限制 HTTP 方法、路径和 Header,实现 API 级安全。
  • ServiceAccount 策略: 基于 Kubernetes 身份进行访问控制,适合集群内部微服务间通信。
  • CIDR 策略: 基于 IP 地址段控制流量,用于与传统外部系统集成。