2. Kubernetes 多租户模型:命名空间隔离、资源配额、租户身份标识与标签策略
在 Kubernetes 中实现多租户故障域管理,首先需要建立清晰的租户边界。本章将深入剖析构成多租户模型的三个核心支柱:命名空间(Namespace)作为隔离单元、资源配额(ResourceQuota)作为资源边界、租户身份标识与标签策略作为运维锚点。这三者共同定义了“哪个租户的 Pod 在什么条件下被驱逐,以及如何被重调度”。
2.1 命名空间隔离:租户的虚拟集群边界
命名空间是 Kubernetes 多租户的基石。每个租户对应一个或多个命名空间,形成逻辑上的虚拟集群。命名空间提供的隔离能力包括:
- 对象名称隔离:不同命名空间中的资源(Pod、Service、ConfigMap 等)可以同名,互不冲突。
- 网络策略作用域:NetworkPolicy 默认只作用于同一命名空间,可限制租户间流量。
- 资源配额绑定:ResourceQuota 和 LimitRange 必须绑定到特定命名空间。
- RBAC 作用域:Role 和 RoleBinding 仅影响指定命名空间内的权限。
最佳实践:对于生产环境,建议为每个租户创建独立的命名空间,并采用统一的命名规范,例如
tenant-{租户ID}-{环境}(如 tenant-acme-prod、tenant-acme-staging)。这有助于在故障排查时快速定位租户边界。
2.2 资源配额:防止租户资源抢占
ResourceQuota 是控制租户资源消耗上限的关键机制。没有配额,一个租户的异常流量或错误配置可能耗尽集群资源,导致其他租户的 Pod 被驱逐。ResourceQuota 可以限制以下维度:
| 资源维度 | 示例配置 | 驱逐影响 |
|---|---|---|
| 计算资源 | requests.cpu: "10"limits.memory: "20Gi" |
超出后新 Pod 创建失败,已有 Pod 可能因节点压力被驱逐 |
| 存储资源 | requests.storage: "100Gi"persistentvolumeclaims: "5" |
超出后无法创建新 PVC,影响有状态工作负载 |
| 对象数量 | pods: "50"services: "10" |
超出后无法创建新对象,避免 etcd 过载 |
| 扩展资源 | nvidia.com/gpu: "2" |
超出后无法调度 GPU 任务 |
关键配置示例:以下 ResourceQuota 为租户 A 的生产命名空间设置资源上限:
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-a-quota
namespace: tenant-acme-prod
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
pods: "50"
persistentvolumeclaims: "10"
requests.storage: "100Gi"
2.3 租户身份标识与标签策略
仅靠命名空间隔离不足以支撑复杂的故障域管理。当 Pod 被驱逐时,调度器需要知道“这个 Pod 属于哪个租户”以及“它的优先级如何”。这就需要一套统一的租户身份标识与标签策略。
2.3.1 标签策略设计原则
- 租户标识:使用
tenant-id标签标记 Pod 所属租户,例如tenant-id: acme-corp。 - 环境标识:使用
environment标签区分生产、预发、测试环境,例如environment: production。 - 优先级标识:使用
priority-tier标签定义 Pod 的调度优先级,例如priority-tier: gold、priority-tier: silver。 - 工作负载类型:使用
workload-type标签区分无状态、有状态、批处理任务。
2.3.2 标签策略与 Pod 驱逐的关系
在 Pod 驱逐场景中,标签策略直接影响驱逐顺序和重调度决策:
| 标签 | 驱逐优先级影响 | 重调度策略 |
|---|---|---|
priority-tier: gold |
最低驱逐优先级,仅在资源极度紧张时被驱逐 | 优先重调度到资源充足的节点 |
priority-tier: silver |
中等驱逐优先级,资源紧张时可能被驱逐 | 按资源可用性重调度 |
priority-tier: bronze |
最高驱逐优先级,资源紧张时首先被驱逐 | 可能被延迟重调度或降级 |
workload-type: batch |
可抢占,允许被高优先级工作负载驱逐 | 重调度到空闲节点或等待资源释放 |
2.4 租户身份标识的代码实践
以下是一个完整的 Deployment 示例,展示了如何通过标签和注解实现租户身份标识:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
namespace: tenant-acme-prod
labels:
tenant-id: acme-corp
environment: production
workload-type: stateless
priority-tier: gold
annotations:
tenant.owner: "platform-team"
tenant.sla: "99.95"
tenant.cost-center: "cc-1234"
spec:
replicas: 3
selector:
matchLabels:
app: frontend
tenant-id: acme-corp
template:
metadata:
labels:
app: frontend
tenant-id: acme-corp
environment: production
priority-tier: gold
workload-type: stateless
spec:
containers:
- name: nginx
image: nginx:1.25
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
注意:标签策略必须与 ResourceQuota 和 PriorityClass 协同工作。如果 Pod 的
priority-tier: gold 标签没有对应的 PriorityClass 配置,调度器将无法正确识别其优先级,可能导致驱逐顺序不符合预期。建议在集群级别定义统一的 PriorityClass 资源,并在 Pod 模板中通过 priorityClassName 引用。
2.5 多租户模型的核心要素总结
| 要素 | 作用 | 与 Pod 驱逐的关系 |
|---|---|---|
| 命名空间 | 逻辑隔离租户资源 | 驱逐操作限定在命名空间范围内,避免跨租户影响 |
| ResourceQuota | 限制租户资源消耗上限 | 超出配额时阻止新 Pod 创建,间接影响驱逐决策 |
| 标签策略 | 标识租户身份和优先级 | 直接决定驱逐顺序和重调度目标 |
| PriorityClass | 定义 Pod 调度优先级 | 与标签策略配合,控制驱逐时的抢占行为 |
课程实践建议:在搭建多租户环境时,先定义标签策略和命名空间规范,再配置 ResourceQuota 和 PriorityClass。这种“先标识、后限制”的顺序可以避免后期因标签不一致导致的驱逐策略失效。