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)。这有助于在故障排查时快速定位租户边界。
命名空间隔离与租户映射关系 命名空间隔离与租户映射关系 Kubernetes 集群 租户 A 命名空间 tenant-acme-prod Pod-A1 app: frontend Pod-A2 app: backend Service-A type: ClusterIP ConfigMap-A data: config 租户 B 命名空间 tenant-beta-prod Pod-B1 app: web Pod-B2 app: worker Service-B type: ClusterIP Secret-B type: Opaque 命名空间提供名称、网络策略、RBAC 和资源配额的逻辑隔离边界

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 可抢占,允许被高优先级工作负载驱逐 重调度到空闲节点或等待资源释放
租户标签策略与驱逐决策流程 租户标签策略与驱逐决策流程 Pod 标签集合 tenant-id / environment / priority-tier / workload-type 驱逐优先级评估 基于 priority-tier 和 workload-type 计算驱逐分数 Gold 优先级 最低驱逐风险 Silver 优先级 中等驱逐风险 Bronze 优先级 最高驱逐风险 租户重调度决策 根据租户标签和资源配额,将 Pod 重调度到合适的节点或等待资源释放 标签策略是连接“租户身份”与“驱逐行为”的桥梁,必须与 ResourceQuota 和 PriorityClass 协同工作

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。这种“先标识、后限制”的顺序可以避免后期因标签不一致导致的驱逐策略失效。