2. Kubernetes 网络基础回顾:Pod网络、Service、Ingress与网络策略(NetworkPolicy)核心概念
在深入多租户网络策略命中与隔离之前,必须重新夯实 Kubernetes 网络模型的四个核心支柱:Pod 网络、Service、Ingress 与 NetworkPolicy。这四个组件共同构成了应用交付的南北向与东西向通信骨架,也是 Helm Chart 在编排网络资源时的直接操作对象。
2.1 Pod 网络:扁平 IP 与容器间通信
Kubernetes 要求所有 Pod 在集群内拥有唯一的 IP 地址,且无需 NAT 即可直接通信。这一“扁平网络”模型由 CNI(Container Network Interface)插件实现,常见实现包括 Calico、Flannel、Cilium 等。
| 特性 | 说明 |
|---|---|
| Pod IP 唯一性 | 每个 Pod 在集群范围内获得一个独立的 IP 地址,跨 Node 通信无需端口映射。 |
| 容器间通信 | 同一 Pod 内的多个容器共享网络命名空间(IP + 端口),通过 localhost 通信。 |
| Pod 间通信 | 不同 Pod 通过各自 IP 直接通信,CNI 负责路由或 Overlay 封装。 |
| Node 到 Pod | Node 上的 kube-proxy 或 CNI 路由规则确保宿主机可访问任意 Pod IP。 |
2.2 Service:稳定的访问抽象层
Pod 是脆弱的,IP 会随重建而变化。Service 通过标签选择器将一组 Pod 抽象为一个稳定的虚拟 IP(ClusterIP)或 DNS 名称,并提供负载均衡与服务发现能力。
- ClusterIP: 默认类型,仅在集群内部可达,适合后端服务间调用。
- NodePort: 在每个 Node 上开放一个静态端口,外部流量可通过
<NodeIP>:<NodePort>访问。 - LoadBalancer: 云厂商或裸金属 LB 集成,自动分配公网 IP,外部流量直接进入。
- Headless Service: 不分配 ClusterIP,直接返回后端 Pod IP 列表,用于 StatefulSet 或自定义负载均衡。
# 一个典型的 ClusterIP Service 定义
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
2.3 Ingress:南北向流量的统一网关
Ingress 是 Kubernetes 原生的七层(HTTP/HTTPS)流量入口,将外部请求路由到集群内部的 Service。它通常由 Ingress Controller(如 Nginx、Traefik、HAProxy)实现,并支持 TLS 终止、虚拟主机路由、路径重写等高级功能。
| Ingress 特性 | 多租户场景价值 |
|---|---|
| 基于 Host 路由 | 通过 spec.rules.host 区分不同租户的域名,如 tenant-a.example.com 与 tenant-b.example.com。 |
| 基于 Path 路由 | 同一域名下通过路径前缀隔离,如 /tenant-a/ 与 /tenant-b/。 |
| TLS 证书管理 | 每个租户可绑定独立的 TLS 证书,通过 Secret 隔离。 |
| 注解(Annotations) | Ingress Controller 通过注解实现限流、白名单、CORS 等租户级策略。 |
# 多租户 Ingress 示例:基于 Host 路由
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-tenant-ingress
annotations:
nginx.ingress.kubernetes.io/limit-rps: "100"
spec:
rules:
- host: tenant-a.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tenant-a-svc
port:
number: 80
- host: tenant-b.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tenant-b-svc
port:
number: 80
2.4 NetworkPolicy:细粒度的流量防火墙
NetworkPolicy 是 Kubernetes 原生的网络隔离机制,基于标签选择器定义 Pod 级别的入站(Ingress)与出站(Egress)规则。它工作在 OSI 第三/四层(IP + 端口),部分 CNI 实现(如 Cilium)可扩展至七层。
| NetworkPolicy 字段 | 作用 |
|---|---|
podSelector |
选择策略生效的目标 Pod 集合(标签匹配)。 |
policyTypes |
指定策略类型:Ingress(入站)、Egress(出站),或两者同时。 |
ingress.from |
允许入站流量的来源:ipBlock、namespaceSelector、podSelector。 |
egress.to |
允许出站流量的目标:同上。 |
ports |
限制允许的端口与协议(TCP/UDP/SCTP)。 |
# 多租户隔离示例:仅允许同命名空间内的 Pod 访问
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-cross-namespace
namespace: tenant-a
spec:
podSelector: {} # 匹配该命名空间所有 Pod
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: tenant-a
ports:
- protocol: TCP
port: 8080
2.5 四层网络模型关系图
下图展示了从外部流量到 Pod 容器的完整路径,以及 NetworkPolicy 在 Pod 边界施加的隔离点。
2.6 多租户网络策略命中逻辑
在多租户环境中,NetworkPolicy 的“命中”取决于三个关键因素的组合:Pod 标签、命名空间标签与策略顺序。Kubernetes 对 NetworkPolicy 采用“先允许后拒绝”的累加模型,即所有匹配的 Ingress/Egress 规则取并集。
- 检查目标 Pod 的命名空间是否包含任何 NetworkPolicy。
- 如果存在,则默认拒绝所有未显式允许的流量。
- 遍历所有 NetworkPolicy 的
podSelector,匹配目标 Pod 标签。 - 对于匹配的策略,检查
ingress.from或egress.to中的来源/目标条件。 - 如果至少一条策略的规则匹配,则流量被允许;否则被拒绝。
下表总结了不同隔离策略的命中效果:
| 策略配置 | 允许流量来源 | 多租户隔离效果 |
|---|---|---|
podSelector: {} + 空 ingress |
无 | 完全隔离该命名空间所有 Pod,拒绝所有入站流量。 |
namespaceSelector: {matchLabels: {team: a}} |
标签为 team=a 的命名空间 |
仅允许同团队命名空间的 Pod 访问,实现租户级隔离。 |
ipBlock: {cidr: 10.0.0.0/8} |
特定 IP 段 | 允许来自集群内部或特定 CIDR 的流量,适合混合云场景。 |
podSelector: {matchLabels: {role: frontend}} |
同命名空间内特定标签的 Pod | 微服务级别的细粒度隔离,适用于同一租户内的分层架构。 |
namespaceSelector 匹配的是命名空间本身的标签,而非命名空间内 Pod 的标签。要允许特定命名空间的所有 Pod 访问,必须确保目标命名空间具有正确的标签,并在策略中引用该标签。
2.7 多租户网络策略隔离架构图
下图展示了一个典型的多租户集群中,NetworkPolicy 如何在不同命名空间之间实施隔离,同时允许必要的跨租户通信(如共享监控服务)。
2.8 本章小结
- Pod 网络 提供扁平 IP 模型,是通信的基础,但默认无隔离。
- Service 提供稳定的访问抽象,但多租户场景需注意标签冲突。
- Ingress 控制南北向流量,通过 Host/Path 实现租户级路由。
- NetworkPolicy 是东西向流量的核心隔离手段,基于标签选择器实现白名单模型。
- 多租户网络策略的命中逻辑依赖于 Pod 标签、命名空间标签 与 策略累加 的精确组合。