3. Cilium网络策略入门:NetworkPolicy资源定义、L3/L4策略规则、基于标签的选择器机制

在Kubernetes原生网络策略的基础上,Cilium通过扩展的CRD(CiliumNetworkPolicy)提供了更强大、更灵活的网络安全控制能力。本章将深入解析Cilium网络策略的核心概念,包括资源定义、L3/L4层策略规则以及基于标签的选择器机制,为后续的准入控制和测试验证打下坚实基础。

3.1 NetworkPolicy资源定义与核心字段

Cilium网络策略资源(CiliumNetworkPolicy)遵循标准的Kubernetes API约定,但引入了许多增强字段。一个完整的策略定义通常包含以下核心部分:

字段路径 类型 说明 示例值
metadata.name string 策略名称,需在命名空间内唯一 allow-frontend-to-backend
spec.endpointSelector LabelSelector 定义策略作用于哪些Pod(目标端点) matchLabels: { app: backend }
spec.ingress []IngressRule 入站流量规则列表 —
spec.egress []EgressRule 出站流量规则列表 —
specs []CiliumNetworkPolicy 用于组合多个策略的数组形式 —

以下是一个基础的CiliumNetworkPolicy示例,它允许带有app: frontend标签的Pod访问带有app: backend标签的Pod的8080端口:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-frontend-to-backend
  namespace: production
spec:
  endpointSelector:
    matchLabels:
      app: backend
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: frontend
    toPorts:
    - ports:
      - port: "8080"
        protocol: TCP
关键区别: 与Kubernetes原生NetworkPolicy不同,CiliumNetworkPolicy默认行为是白名单模式——未显式允许的流量将被拒绝。同时,Cilium支持在spec中使用specs字段进行策略组合,便于复杂场景下的策略管理。

3.2 L3/L4策略规则详解

Cilium网络策略在L3(网络层)和L4(传输层)提供了丰富的匹配能力。L3规则主要基于IP地址或CIDR进行流量控制,而L4规则则关注端口和协议。

3.2.1 L3层规则:基于IP与CIDR

L3规则允许你根据源或目标的IP地址范围来允许或拒绝流量。这在需要与集群外部服务通信时尤为重要。

  • fromCIDR / toCIDR: 精确匹配单个IP或CIDR范围。
  • fromCIDRSet / toCIDRSet: 匹配一组CIDR范围,支持except字段排除特定子网。
  • fromEntities / toEntities: 匹配预定义的实体组,如cluster、host、world(集群外)、all。
spec:
  endpointSelector:
    matchLabels:
      app: api-server
  ingress:
  - fromCIDR:
    - 10.0.0.0/8
    - 192.168.1.0/24
  - fromEntities:
    - cluster
  egress:
  - toCIDR:
    - 0.0.0.0/0
    except:
    - 10.0.0.0/8

3.2.2 L4层规则:基于端口与协议

L4规则在L3的基础上进一步细化,通过toPorts字段指定允许的目标端口和传输层协议。

字段 说明 示例
ports[].port 端口号或端口名称(需与Pod定义一致) "8080" 或 "http"
ports[].protocol 传输层协议,支持TCP、UDP、SCTP、ICMP TCP
rules 高级L7规则(如HTTP、Kafka),属于L7策略范畴 —
注意: 当同时指定L3和L4规则时,流量必须同时满足两个条件才会被允许。例如,fromEndpoints + toPorts意味着只有来自特定端点且发往指定端口的流量才被放行。

3.3 基于标签的选择器机制

Cilium的核心优势之一是其强大的基于标签的选择器机制。与Kubernetes原生策略相比,Cilium支持更丰富的匹配表达式,并且可以跨命名空间选择端点。

3.3.1 选择器类型对比

选择器类型 语法 匹配逻辑 适用场景
matchLabels matchLabels: { key: value } 精确匹配所有指定的键值对(AND逻辑) 简单、确定的端点选择
matchExpressions matchExpressions: [{ key, operator, values }] 支持 In、NotIn、Exists、DoesNotExist 操作符 复杂条件筛选,如排除特定版本
namespaceSelector namespaceSelector: { matchLabels: ... } 根据命名空间的标签选择目标命名空间 跨命名空间策略控制

3.3.2 跨命名空间选择与组合

Cilium允许在fromEndpoints或toEndpoints中同时使用namespaceSelector和podSelector(即matchLabels),实现精细的跨命名空间访问控制。

spec:
  endpointSelector:
    matchLabels:
      app: payment-service
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: order-service
      namespaceSelector:
        matchLabels:
          team: commerce

上述策略表示:仅允许来自team: commerce命名空间中带有app: order-service标签的Pod访问payment-service。

最佳实践: 在服务目录平台中,建议使用命名空间标签(如environment: production、tier: backend)结合应用标签(如app: user-service)来构建层次化的策略模型。这可以大幅减少策略数量,同时保持清晰的访问边界。

3.4 策略规则组合与优先级

当多个CiliumNetworkPolicy应用于同一个端点时,Cilium会按照以下规则进行合并:

  1. 默认拒绝: 一旦任何策略选择了一个端点,该端点默认拒绝所有未显式允许的流量。
  2. 规则合并: 所有匹配的入站和出站规则会进行逻辑或(OR)合并。只要有一个策略允许某条流量,该流量即被放行。
  3. 策略优先级: Cilium本身不提供显式的优先级字段,但可以通过specs数组或更具体的标签选择器来实现策略的精细化控制。
Cilium网络策略规则合并与评估流程 策略A 策略B 策略C 规则合并(OR逻辑) 目标端点(Pod) 流量评估:允许 / 拒绝 默认拒绝 + 显式允许

3.5 实战:编写一个完整的L3/L4策略

以下是一个综合示例,展示了如何为微服务架构中的“订单服务”编写一个包含L3和L4规则的CiliumNetworkPolicy:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: order-service-policy
  namespace: commerce
spec:
  endpointSelector:
    matchLabels:
      app: order-service
  ingress:
  - fromEndpoints:
    - matchLabels:
        app: api-gateway
    toPorts:
    - ports:
      - port: "3000"
        protocol: TCP
  - fromCIDR:
    - 10.100.0.0/16
    toPorts:
    - ports:
      - port: "9090"
        protocol: TCP
  egress:
  - toEndpoints:
    - matchLabels:
        app: payment-service
    toPorts:
    - ports:
      - port: "443"
        protocol: TCP
  - toCIDR:
    - 0.0.0.0/0
    except:
    - 10.0.0.0/8
    - 172.16.0.0/12
    - 192.168.0.0/16
策略解读:
  • 入站: 仅允许来自api-gateway的Pod访问3000端口,以及来自内部网络10.100.0.0/16的请求访问9090端口(用于健康检查)。
  • 出站: 仅允许访问payment-service的443端口,同时允许访问公网(除私有IP段外),用于调用外部支付网关API。