2. NetworkPolicy 核心概念
NetworkPolicy 是 Kubernetes 原生的网络安全资源对象,用于定义 Pod 之间以及 Pod 与外部网络之间的流量访问规则。在多租户场景下,它是实现租户隔离、微服务安全边界和最小权限原则的核心手段。本章将深入解析 NetworkPolicy 的资源定义结构、Pod 选择器机制以及 Ingress/Egress 策略类型。
2.1 NetworkPolicy 资源定义结构
一个完整的 NetworkPolicy 资源由 API 版本、元数据、规格三部分组成。规格(spec)中包含了策略的核心控制逻辑:podSelector、policyTypes、ingress 和 egress。
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: demo-policy
namespace: tenant-a
spec:
podSelector:
matchLabels:
app: frontend
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: backend
ports:
- protocol: TCP
port: 8080
egress:
- to:
- ipBlock:
cidr: 10.0.0.0/16
except:
- 10.0.1.0/24
ports:
- protocol: TCP
port: 443
关键字段说明:
- podSelector:必填字段,通过标签选择器指定该策略作用于哪些 Pod。
- policyTypes:声明策略类型,可选 Ingress、Egress 或两者都选。若不指定,默认只启用 Ingress。
- ingress/egress:规则数组,每个规则包含 from/to 和 ports 子字段。
- from/to:支持 podSelector、namespaceSelector、ipBlock 三种匹配方式。
2.2 Pod 选择器机制
Pod 选择器是 NetworkPolicy 的入口,决定了策略的生效范围。它基于 Kubernetes 标准的标签选择器(Label Selector)工作,支持两种匹配模式:
| 选择器类型 | 语法示例 | 匹配逻辑 | 典型场景 |
|---|---|---|---|
| matchLabels | app: frontend |
精确匹配所有指定标签 | 选择单一微服务 |
| matchExpressions | In / NotIn / Exists / DoesNotExist |
基于表达式集合匹配 | 多条件组合筛选 |
最佳实践:在多租户环境中,建议为每个租户的 Pod 打上
tenant: <tenant-id> 和 app: <service-name> 两层标签。NetworkPolicy 的 podSelector 优先使用 app 标签,而租户隔离通过 namespace 或 namespaceSelector 实现,避免策略跨租户泄漏。
2.3 策略类型:Ingress 与 Egress
NetworkPolicy 定义了两种流量方向的控制策略:
- Ingress(入站流量):控制哪些来源可以访问目标 Pod。来源可以是同一命名空间内的 Pod、其他命名空间的 Pod 或外部 IP 段。
- Egress(出站流量):控制目标 Pod 可以访问哪些目的地。目的地同样支持 Pod、命名空间和 IP 段三种模式。
当 policyTypes 中只声明 Ingress 时,Egress 流量默认全部放行;反之亦然。若两者都声明,则未匹配规则的流量将被拒绝。这是 Kubernetes 网络策略的白名单机制:未显式允许的流量一律拒绝。
常见陷阱:如果只定义了 Ingress 规则而未定义 Egress 规则,但
policyTypes 中包含了 Egress,则所有出站流量都会被拒绝。这会导致 Pod 无法访问 DNS、API Server 等基础服务。建议始终在 policyTypes 中明确声明需要控制的类型,避免意外阻断。
2.4 策略类型与流量方向关系图
下图展示了 NetworkPolicy 中 Ingress 和 Egress 策略的流量控制方向,以及三种匹配源/目的地的组合方式:
2.5 多租户场景下的策略组合示例
以下是一个典型的多租户隔离策略配置,展示了如何结合 namespaceSelector 和 podSelector 实现租户间的严格隔离:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: tenant-isolation
namespace: tenant-a
spec:
podSelector:
matchLabels:
tenant: tenant-a
policyTypes:
- Ingress
- Egress
ingress:
- from:
- namespaceSelector:
matchLabels:
tenant: tenant-a
- podSelector:
matchLabels:
app: monitoring
egress:
- to:
- namespaceSelector:
matchLabels:
tenant: tenant-a
- ipBlock:
cidr: 0.0.0.0/0
except:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
策略解读:
- Ingress:只允许来自同一租户(tenant-a)命名空间的 Pod 访问,以及监控服务(app: monitoring)的访问。
- Egress:只允许访问同一租户命名空间的 Pod,以及外部公网(排除私有 IP 段),防止数据泄露到其他租户的内网。
- podSelector:通过
tenant: tenant-a标签确保策略只作用于本租户的 Pod。
2.6 核心概念对比表
| 概念 | 作用范围 | 匹配方式 | 默认行为 | 多租户关键点 |
|---|---|---|---|---|
| podSelector | 本命名空间 | 标签选择器 | 空选择器匹配所有 Pod | 使用租户标签精确限定 |
| namespaceSelector | 跨命名空间 | 命名空间标签 | 不匹配任何命名空间 | 通过租户标签实现隔离 |
| ipBlock | 集群内外 IP | CIDR + except | 不匹配任何 IP | 用于控制外部访问 |
| policyTypes | 策略级别 | Ingress / Egress | 仅 Ingress | 明确声明避免意外阻断 |
2.7 多租户 Pod 选择器设计模式
下图展示了在多租户环境中,如何通过分层标签设计实现精细化的 Pod 选择器策略:
设计建议:在多租户 NetworkPolicy 配置中,建议将租户隔离放在 namespace 层面(通过 namespaceSelector),将服务间访问控制放在 podSelector 层面。这样既保证了租户间的强隔离,又保留了微服务间灵活通信的能力。版本层标签可用于实现蓝绿部署和金丝雀发布时的精细化流量控制。