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,以及来自集群外部的流量。
下图展示了该策略的准入控制逻辑:
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编写后,可以通过以下步骤快速部署并验证策略效果:
- 部署测试Pod: 创建两个测试Pod,分别带有
app=order-service和app=api-gateway标签。 - 应用策略: 使用
kubectl apply -f allow-api-gateway-to-order.yaml部署策略。 - 验证连通性:
- 从
api-gatewayPod访问order-service的8080端口,应成功。 - 从
api-gatewayPod访问order-service的其他端口(如9090),应失败。 - 从其他Pod(如
frontend)访问order-service的8080端口,应失败。
- 从
- 查看策略状态: 使用
kubectl get cnp和cilium endpoint list命令确认策略已正确加载。
生产建议: 在编写策略时,建议先使用
fromEndpoints 配合 matchLabels 进行粗粒度控制,再逐步细化到 toPorts 和 fromCIDR。同时,可以利用Cilium的 hubble observe 命令实时观察流量是否被策略允许或拒绝,这对于调试和审计非常有帮助。