3、Cilium网络策略基础:NetworkPolicy资源定义、Ingress/Egress规则、标签选择器(EndpointSelector)、策略优先级与默认拒绝
在 Kubernetes 原生网络模型中,NetworkPolicy 是控制 Pod 间通信的核心资源。Cilium 在完全兼容 Kubernetes NetworkPolicy 的基础上,通过 CiliumNetworkPolicy (CNP) 扩展了更精细的 L3/L4/L7 控制能力。本章将深入解析策略的构成要素、规则定义与执行逻辑,为后续的迁移与蓝绿发布场景奠定基础。
3.1 NetworkPolicy 资源定义结构
一个标准的 Kubernetes NetworkPolicy 资源由以下核心字段构成:
| 字段 | 类型 | 说明 |
|---|---|---|
| podSelector | LabelSelector | 选择策略生效的目标 Pod 集合 |
| policyTypes | []PolicyType | 声明策略类型:Ingress、Egress 或两者 |
| ingress | []IngressRule | 入站流量规则列表 |
| egress | []EgressRule | 出站流量规则列表 |
关键点: 当
policyTypes 未显式指定时,Kubernetes 默认仅应用 Ingress 规则;Cilium 则建议始终显式声明 policyTypes 以避免歧义。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
spec:
podSelector: {}
policyTypes:
- Ingress
3.2 Ingress / Egress 规则详解
Ingress 和 Egress 规则分别控制进入和离开 Pod 的流量。每条规则由 from(Ingress)或 to(Egress)以及 ports 组成。
3.2.1 Ingress 规则
Ingress 规则通过 from 字段定义允许的源端,支持以下选择器:
- podSelector:允许来自同一 Namespace 内特定标签的 Pod
- namespaceSelector:允许来自特定 Namespace 的所有 Pod
- ipBlock:允许来自特定 CIDR 范围的流量(非 Kubernetes 原生 Pod)
spec:
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
- namespaceSelector:
matchLabels:
project: production
ports:
- protocol: TCP
port: 8080
3.2.2 Egress 规则
Egress 规则通过 to 字段定义允许的目标端,选择器类型与 Ingress 对称:
spec:
egress:
- to:
- podSelector:
matchLabels:
role: database
ports:
- protocol: TCP
port: 5432
最佳实践: 在蓝绿发布场景中,建议为每个版本(blue/green)的 Pod 打上唯一的版本标签,然后通过 Egress 规则精确控制流量只流向同版本的依赖服务,避免跨版本数据污染。
3.3 标签选择器(EndpointSelector)
Cilium 引入的 CiliumNetworkPolicy 使用 endpointSelector 替代 Kubernetes 的 podSelector,但本质都是基于标签的匹配机制。标签选择器支持以下操作符:
| 操作符 | 示例 | 匹配行为 |
|---|---|---|
| In | role In [frontend, api] |
标签值属于集合中的任意一个 |
| NotIn | version NotIn [v1] |
标签值不属于集合 |
| Exists | app Exists |
标签键存在(无论值是什么) |
| DoesNotExist | tier DoesNotExist |
标签键不存在 |
注意: 标签选择器是 AND 逻辑——当在同一个
matchLabels 中指定多个键值对时,Pod 必须同时满足所有条件。如需 OR 逻辑,需在规则中列出多个 from 或 to 条目。
3.4 策略优先级与默认拒绝
Kubernetes 和 Cilium 的策略模型遵循 白名单机制:
- 默认拒绝:一旦任何 NetworkPolicy 选中了一个 Pod,该 Pod 的所有未显式允许的流量都会被拒绝。
- 策略叠加:多个 NetworkPolicy 作用于同一个 Pod 时,规则是 OR 关系——只要任意一个策略允许,流量即被放行。
- 优先级:原生 Kubernetes NetworkPolicy 没有优先级概念,所有策略平等叠加。Cilium 通过
CiliumNetworkPolicy的priority字段(0-65535,数值越小优先级越高)提供显式优先级控制。
迁移启示: 在从传统 NetworkPolicy 迁移到 CiliumNetworkPolicy 时,需注意 Cilium 的优先级机制可以解决策略冲突问题。例如,在蓝绿发布中,可以为新版本 Pod 设置更高优先级的策略,确保灰度期间的流量隔离。
apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
name: allow-frontend-to-backend
spec:
endpointSelector:
matchLabels:
role: backend
ingress:
- fromEndpoints:
- matchLabels:
role: frontend
version: v2 # 仅允许 v2 版本的 frontend 访问
ports:
- port: "8080"
protocol: TCP
priority: 100 # 显式优先级,数值越小优先级越高
3.5 策略执行流程与默认拒绝模型
下图展示了 Cilium 在处理 Pod 网络流量时的策略评估流程:
3.6 策略优先级在蓝绿发布中的应用
在蓝绿发布场景中,策略优先级可以解决以下关键问题:
- 流量隔离:为绿色(新版本)环境设置高优先级策略,确保其仅与同版本服务通信
- 渐进式放行:通过调整优先级,逐步将流量从蓝色(旧版本)迁移到绿色
- 快速回滚:当绿色版本出现问题时,降低其策略优先级或直接删除,恢复蓝色版本的默认策略
实战建议: 在 Cilium 中,建议为每个微服务版本维护独立的 CiliumNetworkPolicy,并使用
priority 字段控制生效顺序。例如,将绿色版本的策略优先级设为 50,蓝色版本设为 100,确保绿色版本的规则优先匹配。
下表总结了不同策略配置在蓝绿发布中的行为:
| 场景 | 策略配置 | 流量行为 |
|---|---|---|
| 仅蓝色运行 | 蓝色策略优先级 100 | 所有流量流向蓝色 |
| 绿色部署完成 | 绿色策略优先级 50 | 绿色优先处理,蓝色作为备份 |
| 灰度测试 | 绿色策略 + 标签选择器限制 | 仅特定标签的流量进入绿色 |
| 回滚 | 删除绿色策略或降低优先级 | 流量自动切回蓝色 |
避坑指南: 不要忘记在 CiliumNetworkPolicy 中显式设置
priority 字段。如果不设置,Cilium 会使用默认优先级 0(最高优先级),可能导致多个策略之间的意外覆盖。建议在团队内建立优先级分配规范,例如:核心服务 0-100,普通服务 101-500,测试服务 501-1000。