4. 编写第一个CiliumNetworkPolicy:基于Pod Selector的L3/L4准入策略

本节将带领你编写第一个真正的Cilium网络策略——一个基于Pod选择器(Pod Selector)的L3/L4层准入控制策略。该策略的核心目标是:只允许特定来源的Pod通过指定端口访问目标Pod,拒绝其他所有流量。这是Kubernetes环境中最基础、最常用的安全隔离手段。

4.1 策略模型与核心概念

在动手编写YAML之前,需要理解CiliumNetworkPolicy的匹配逻辑。与Kubernetes原生的NetworkPolicy不同,Cilium的策略模型更加灵活且具备身份感知能力。

概念 说明 在策略中的角色
Endpoint Selector 选择策略生效的目标Pod(即被保护的Pod) 定义在 spec.endpointSelector 中
Ingress / Egress 控制入站(ingress)和出站(egress)流量方向 定义在 spec.ingress 或 spec.egress 中
From Endpoint Selector 在ingress规则中,指定允许哪些来源Pod访问 定义在 fromEndpoints 字段中
To Ports 在规则中,指定允许通信的目标端口与协议 定义在 toPorts 字段中
关键区别: Cilium的 endpointSelector 对应的是“被保护的对象”,而 fromEndpoints 对应的是“被允许的访问来源”。这种设计使得策略的意图更加清晰,也更容易进行细粒度的控制。

4.2 场景设定:保护“订单服务”

假设我们有一个微服务应用:

  • 目标Pod: app=order-service,运行在 default 命名空间,监听 8080 端口(TCP协议)。
  • 允许访问的来源: 只有标签为 app=api-gateway 的Pod可以访问。
  • 拒绝所有其他流量: 包括来自其他命名空间、其他标签的Pod,以及来自集群外部的流量。

下图展示了该策略的准入控制逻辑:

基于Pod Selector的L3/L4准入策略流程图 L3/L4准入策略:只允许API Gateway访问Order Service 来源 Pod app=api-gateway CiliumNetworkPolicy endpointSelector: app=order-service 目标 Pod app=order-service 允许端口: TCP 8080 ❌ 拒绝其他来源 (如: app=frontend) 策略拒绝 (无匹配规则)

4.3 编写第一个CiliumNetworkPolicy YAML

根据上述场景,我们编写一个完整的CiliumNetworkPolicy资源定义。该策略将部署在 default 命名空间,并作用于该命名空间内的Pod。

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-api-gateway-to-order
  namespace: default
spec:
  description: "允许api-gateway访问order-service的TCP 8080端口"
  endpointSelector:
    matchLabels:
      app: order-service
  ingress:
    - fromEndpoints:
        - matchLabels:
            app: api-gateway
      toPorts:
        - ports:
            - port: "8080"
              protocol: TCP
YAML关键字段解析:
  • spec.endpointSelector:选择目标Pod,即 app=order-service。所有发往这些Pod的入站流量都将受到该策略的管控。
  • spec.ingress:定义入站规则。
  • fromEndpoints:指定允许的来源Pod。这里只允许标签为 app=api-gateway 的Pod。
  • toPorts:指定允许的目标端口和协议。这里只允许 TCP 8080 端口。

4.4 策略生效后的行为验证

当该策略被应用到集群后,Cilium Agent会将其转换为BPF程序并下发到节点。以下是策略生效前后的流量对比:

场景 来源Pod标签 目标端口 策略生效前 策略生效后
合法访问 app=api-gateway TCP 8080 ✅ 允许 ✅ 允许
非法端口 app=api-gateway TCP 9090 ✅ 允许 ❌ 拒绝
非法来源 app=frontend TCP 8080 ✅ 允许 ❌ 拒绝
非法来源+非法端口 app=frontend TCP 9090 ✅ 允许 ❌ 拒绝
重要提醒: CiliumNetworkPolicy默认采用白名单(默认拒绝)模式。一旦为某个endpointSelector定义了任何ingress规则,所有未显式允许的入站流量都会被拒绝。这与Kubernetes原生NetworkPolicy的行为一致。因此,在编写策略时,务必确保所有合法的访问来源都被包含在 fromEndpoints 中。

4.5 部署与验证步骤

完成YAML编写后,可以通过以下步骤快速部署并验证策略效果:

  1. 部署测试Pod: 创建两个测试Pod,分别带有 app=order-service 和 app=api-gateway 标签。
  2. 应用策略: 使用 kubectl apply -f allow-api-gateway-to-order.yaml 部署策略。
  3. 验证连通性:
    • 从 api-gateway Pod访问 order-service 的8080端口,应成功。
    • 从 api-gateway Pod访问 order-service 的其他端口(如9090),应失败。
    • 从其他Pod(如 frontend)访问 order-service 的8080端口,应失败。
  4. 查看策略状态: 使用 kubectl get cnp 和 cilium endpoint list 命令确认策略已正确加载。
生产建议: 在编写策略时,建议先使用 fromEndpoints 配合 matchLabels 进行粗粒度控制,再逐步细化到 toPorts 和 fromCIDR。同时,可以利用Cilium的 hubble observe 命令实时观察流量是否被策略允许或拒绝,这对于调试和审计非常有帮助。