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
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策略范畴 | — |
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会按照以下规则进行合并:
- 默认拒绝: 一旦任何策略选择了一个端点,该端点默认拒绝所有未显式允许的流量。
- 规则合并: 所有匹配的入站和出站规则会进行逻辑或(OR)合并。只要有一个策略允许某条流量,该流量即被放行。
- 策略优先级: Cilium本身不提供显式的优先级字段,但可以通过
specs数组或更具体的标签选择器来实现策略的精细化控制。
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。