4. 多租户命名空间设计:命名空间作为租户边界、命名空间命名规范、标签策略
在 Kubernetes 多租户体系中,命名空间(Namespace)是最基础、最直接的租户隔离边界。一个设计良好的命名空间体系,不仅决定了网络策略的生效范围,还直接影响运维效率、审计清晰度和自动化能力。本章将深入剖析如何将命名空间作为租户边界,并给出命名规范与标签策略的最佳实践。
4.1 命名空间作为租户边界
Kubernetes 原生提供的命名空间隔离机制,天然适合作为多租户的“软墙”。每个租户独占一个或多个命名空间,通过 RBAC、ResourceQuota、NetworkPolicy 等机制实现资源与网络的逻辑隔离。
将命名空间作为租户边界,需要遵循以下核心原则:
- 独占性:每个租户至少拥有一个独立的命名空间,不允许跨租户共享命名空间。
- 不可穿透性:默认情况下,不同命名空间的 Pod 无法直接通信;如需跨租户通信,必须显式通过 NetworkPolicy 放行。
- 资源配额绑定:每个租户命名空间绑定独立的 ResourceQuota 和 LimitRange,防止资源争抢。
- 审计边界:所有审计日志、监控指标、成本核算均以命名空间为粒度进行聚合。
下图展示了以命名空间为租户边界的典型架构:
4.2 命名空间命名规范
统一的命名规范是自动化运维和策略继承的基础。混乱的命名会导致 NetworkPolicy 选择器失效、监控数据难以聚合、审计日志无法追溯。推荐采用以下分层命名模式:
<租户标识>-<环境>-<区域/模块>
各字段说明如下表:
| 字段 | 说明 | 示例值 | 约束 |
|---|---|---|---|
| 租户标识 | 租户的唯一缩写,建议 3-8 位小写字母 | fin、ecom、aipl | 全局唯一,不可变更 |
| 环境 | 部署环境类型 | dev、stg、prod | 固定枚举值 |
| 区域/模块 | 可选字段,用于大型租户的子模块划分 | core、pay、user | 非必填,建议不超过 2 级 |
命名规范示例:
fin-prod—— 金融租户生产环境ecom-stg-pay—— 电商租户预发布环境的支付模块aipl-dev-core—— AI 平台租户开发环境的核心模块
4.3 标签策略
标签(Label)是 Kubernetes 中实现灵活选择与策略绑定的核心机制。在多租户场景下,标签策略决定了 NetworkPolicy 能否精准匹配目标 Pod,以及运维工具能否高效聚合资源。
4.3.1 强制标签体系
每个命名空间及其下的所有资源,必须携带以下强制标签:
| 标签键 | 标签值示例 | 作用 |
|---|---|---|
tenant |
fin、ecom | 标识所属租户,用于 NetworkPolicy 的 namespaceSelector |
environment |
dev、stg、prod | 标识环境,用于环境级策略隔离 |
tier |
frontend、backend、data | 标识服务层级,用于东西向流量策略 |
team |
platform、payment | 标识负责团队,用于审计与成本分摊 |
4.3.2 标签在 NetworkPolicy 中的应用
通过标签选择器,可以实现精细化的跨租户或跨环境策略控制。以下是一个基于标签的 NetworkPolicy 示例:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-fin-prod
namespace: ecom-prod
spec:
podSelector:
matchLabels:
tier: frontend
ingress:
- from:
- namespaceSelector:
matchLabels:
tenant: fin
environment: prod
- podSelector:
matchLabels:
tier: backend
该策略允许来自 fin-prod 命名空间的所有 Pod,以及本命名空间中带有 tier: backend 标签的 Pod,访问 ecom-prod 命名空间中带有 tier: frontend 标签的 Pod。
4.3.3 标签自动化校验
为确保标签策略被严格执行,建议使用 准入控制器(Admission Controller) 或 OPA/Gatekeeper 进行强制校验。以下是一个 Gatekeeper 约束模板示例:
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("Missing required labels: %v", [missing])
}
下图展示了标签策略在 NetworkPolicy 选择器中的匹配流程:
4.4 命名空间设计清单
在实施多租户命名空间设计时,建议对照以下清单逐项检查:
- 命名规范已定义:是否形成了团队统一的命名模板?是否通过自动化工具(如脚手架)生成命名空间?
- 强制标签已绑定:每个命名空间是否都携带了
tenant、environment、tier等核心标签? - 标签校验已启用:是否部署了 OPA/Gatekeeper 或类似工具,在资源创建时强制校验标签完整性?
- NetworkPolicy 基线已配置:是否为每个命名空间配置了默认拒绝入站/出站的基线策略?
- 资源配额已设置:每个命名空间是否绑定了 ResourceQuota 和 LimitRange?
- 审计与监控已对接:日志和监控系统是否以命名空间为粒度进行数据聚合?
kubectl get ns --show-labels | grep -E "tenant|environment"如果输出中缺少关键标签,说明命名空间设计存在遗漏,需要立即补充。