2. 多租户基础概念:租户定义、租户隔离模型与资源配额设计

在多租户故障域隔离演练中,清晰定义“租户”是后续所有策略与指标采集的起点。租户不仅是逻辑上的用户分组,更是资源边界、故障边界与安全边界的统一抽象。本节从租户定义出发,逐步展开隔离模型、配额机制与命名空间设计,为后续 OPA 策略注入提供基础语义。

2.1 租户定义:从业务实体到资源边界

在云原生环境中,租户(Tenant)是一个拥有独立资源视图、独立访问控制、独立故障域的逻辑实体。租户可以对应一个组织、一个部门、一个项目组,甚至一个微服务。租户的核心属性包括:

  • 身份标识:全局唯一的租户 ID(如 tenant-001),用于资源标签与审计。
  • 资源配额:CPU、内存、存储、网络带宽等上限。
  • 策略域:OPA 策略作用范围,如允许的镜像仓库、网络策略、Pod 安全标准。
  • 故障域:租户内故障不应扩散到其他租户,如节点亲和性、Pod 反亲和、AZ 分布。
实战提示:在演练场景中,建议为每个租户分配独立的 OPA 策略绑定(Assignments),通过 input.tenant_id 区分策略生效范围,避免全局策略误伤。

2.2 租户隔离模型:SaaS vs PaaS

隔离模型决定了租户之间共享基础设施的程度,直接影响故障域半径和 OPA 策略复杂度。下表对比了两种主流模型:

维度 SaaS 多租户(软隔离) PaaS 多租户(硬隔离)
资源池 共享集群,通过命名空间隔离 独立集群或独立节点组
故障域 租户间共享故障域(如节点宕机影响多个租户) 租户拥有独立故障域(节点、AZ 级别隔离)
OPA 策略粒度 细粒度:每个命名空间绑定不同策略 粗粒度:集群级策略,租户间策略差异小
资源配额 Namespace ResourceQuota + LimitRange ClusterResourceQuota 或节点分配
典型场景 内部开发环境、测试环境 金融、合规、生产核心业务

在故障域隔离演练中,SaaS 模型更考验 OPA 策略的精细度与告警分层能力,因为一个节点故障可能波及多个租户,需要快速定位“哪个租户的哪些工作负载”受到影响。

关键结论:演练场景推荐使用 SaaS 软隔离模型,因为它能暴露更多跨租户故障扩散问题,OPA 指标采集与告警分层在此模型下价值最大。

2.3 租户资源配额与命名空间设计

命名空间(Namespace)是 Kubernetes 中实现租户隔离的基本单元。合理的命名空间设计需要同时满足资源配额、策略绑定与故障域隔离三个目标。

2.3.1 命名空间命名规范

建议采用分层命名,便于 OPA 策略通过正则匹配:

# 格式:<tenant-id>-<environment>-<workload-type>
tenant-001-prod-frontend
tenant-001-prod-backend
tenant-001-staging-frontend
tenant-002-prod-database

2.3.2 资源配额模板

每个租户的命名空间应绑定 ResourceQuota 与 LimitRange,防止单个租户资源滥用导致其他租户故障。以下是一个典型配额配置:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-quota
  namespace: tenant-001-prod-frontend
spec:
  hard:
    requests.cpu: "8"
    requests.memory: "16Gi"
    limits.cpu: "16"
    limits.memory: "32Gi"
    persistentvolumeclaims: "5"
    pods: "50"
---
apiVersion: v1
kind: LimitRange
metadata:
  name: tenant-limits
  namespace: tenant-001-prod-frontend
spec:
  limits:
  - max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container

2.3.3 故障域隔离设计

在命名空间层面,通过 Pod 反亲和与拓扑分布约束实现故障域隔离:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app-frontend
  namespace: tenant-001-prod-frontend
spec:
  replicas: 3
  template:
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - frontend
            topologyKey: "kubernetes.io/hostname"
      topologySpreadConstraints:
      - maxSkew: 1
        topologyKey: "topology.kubernetes.io/zone"
        whenUnsatisfiable: DoNotSchedule
演练避坑:如果命名空间未绑定 ResourceQuota,单个租户的 Pod 突发可能耗尽节点资源,导致同节点其他租户 Pod 被驱逐。OPA 策略应强制要求每个命名空间必须绑定配额,否则拒绝创建 Pod。

2.4 租户隔离模型与命名空间关系图

下图展示了 SaaS 模型下租户、命名空间、资源配额与故障域之间的逻辑关系:

多租户隔离模型与命名空间关系 SaaS 多租户隔离模型:租户 → 命名空间 → 配额 → 故障域 租户 A(tenant-001) ns: tenant-001-prod-frontend ResourceQuota: CPU 8 / Mem 16Gi LimitRange: 100m~2 CPU / 128Mi~4Gi PodAntiAffinity: hostname ns: tenant-001-prod-backend ResourceQuota: CPU 16 / Mem 32Gi LimitRange: 200m~4 CPU / 256Mi~8Gi TopologySpread: zone ns: tenant-001-staging-frontend ResourceQuota: CPU 4 / Mem 8Gi LimitRange: 100m~1 CPU / 128Mi~2Gi No PodAntiAffinity(共享节点) 租户 B(tenant-002) ns: tenant-002-prod-database ResourceQuota: CPU 32 / Mem 64Gi LimitRange: 500m~8 CPU / 1Gi~16Gi PodAntiAffinity: hostname + zone ns: tenant-002-prod-cache ResourceQuota: CPU 16 / Mem 32Gi LimitRange: 200m~4 CPU / 512Mi~8Gi TopologySpread: hostname ns: tenant-002-dev-tools ResourceQuota: CPU 2 / Mem 4Gi LimitRange: 100m~500m / 128Mi~1Gi 共享节点,无严格隔离 每个命名空间绑定独立 ResourceQuota + LimitRange,OPA 策略通过命名空间标签(tenant-id)区分策略生效范围

2.5 租户资源配额与 OPA 策略联动

OPA 策略在资源配额管理中扮演“准入控制器”角色,确保每个命名空间在创建时即绑定合规的配额配置。以下是一个 OPA 策略片段,强制要求命名空间必须包含 ResourceQuota:

package kubernetes.admission

# 拒绝没有 ResourceQuota 的命名空间
deny[msg] {
  input.request.kind.kind == "Namespace"
  input.request.operation == "CREATE"
  not has_resource_quota(input.request.object.metadata.name)
  msg := sprintf("命名空间 %v 必须绑定 ResourceQuota,请先创建配额对象", [input.request.object.metadata.name])
}

has_resource_quota(ns_name) {
  quota := data.resource_quotas[_]
  quota.metadata.namespace == ns_name
}
演练要点:在故障域隔离演练中,OPA 指标采集应关注每个租户的 ResourceQuota 使用率(如 quota_used_percent),当某个租户的配额使用率超过 80% 时触发告警,提前规避资源争抢导致的跨租户故障。

2.6 租户隔离模型对比总结

对比项 SaaS 模型(本课程采用) PaaS 模型
隔离粒度 命名空间级 集群/节点级
OPA 策略复杂度 高(需区分租户标签) 低(集群级统一策略)
故障域半径 共享节点/AZ,故障易扩散 独立节点/AZ,故障隔离好
资源利用率 高(资源共享) 低(资源预留)
演练价值 高(暴露真实故障扩散场景) 低(故障域天然隔离)