3、基于命名空间的软隔离:命名空间(Namespace)作为租户边界、ResourceQuota与LimitRange配合网络隔离

在多租户 Kubernetes 集群中,命名空间(Namespace)是最基础、最轻量的隔离单元。它不提供硬性的安全边界(如虚拟化或 CVE 级别的隔离),但通过逻辑分组、资源配额与网络策略的组合,能够实现面向租户的软隔离。本章聚焦于如何以 Namespace 为租户边界,配合 ResourceQuota、LimitRange 以及网络策略,构建一套可落地、可审计的多租户隔离方案。

3.1 命名空间作为租户边界的核心模型

每个租户对应一个独立的 Namespace,所有属于该租户的工作负载、配置、服务都部署在该 Namespace 内。这种模型的核心优势在于:

  • 资源命名隔离:不同 Namespace 中的资源可以同名,互不冲突。
  • 权限控制锚点:RBAC 规则可以精确绑定到 Namespace 级别,实现租户管理员自治。
  • 网络策略作用域:NetworkPolicy 默认作用于 Namespace 内的 Pod,天然支持租户间流量阻断。
  • 资源配额挂载点:ResourceQuota 和 LimitRange 直接挂载在 Namespace 上,限制租户的资源消耗上限。
最佳实践: 建议为每个租户创建至少两个 Namespace:一个用于生产环境(如 tenant-a-prod),一个用于开发/测试(如 tenant-a-dev)。这有助于在租户内部进一步隔离环境,同时保持配额管理的灵活性。
基于命名空间的多租户软隔离架构 Kubernetes 集群 Namespace: tenant-a ResourceQuota: cpu=8, mem=32Gi, pods=20 LimitRange: 默认 request/limit 约束 Deployment app: frontend Deployment app: backend NetworkPolicy: 允许同 Namespace 流量 拒绝来自其他 Namespace 的入站 Service: frontend-svc Service: backend-svc Namespace: tenant-b ResourceQuota: cpu=4, mem=16Gi, pods=10 LimitRange: 默认 request/limit 约束 Deployment app: web Deployment app: db NetworkPolicy: 拒绝所有外部入站 仅允许同 Namespace 内通信 Service: web-svc Service: db-svc 隔离 每个 Namespace 拥有独立的 ResourceQuota、LimitRange 和 NetworkPolicy,租户间默认网络隔离

3.2 ResourceQuota:租户资源上限的硬约束

ResourceQuota 是 Kubernetes 内置的准入控制机制,用于限制一个 Namespace 内所有 Pod 的资源总和上限。它防止单个租户过度消耗集群资源,保障其他租户的服务质量。

3.2.1 核心配额维度

配额维度 描述 示例值
requests.cpu 所有 Pod CPU 请求总和上限 8
requests.memory 所有 Pod 内存请求总和上限 32Gi
limits.cpu 所有 Pod CPU 限制总和上限 16
limits.memory 所有 Pod 内存限制总和上限 64Gi
pods Namespace 中允许的最大 Pod 数量 20
services Namespace 中允许的最大 Service 数量 10
persistentvolumeclaims Namespace 中允许的最大 PVC 数量 5

3.2.2 典型 ResourceQuota 配置示例

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-a-quota
  namespace: tenant-a
spec:
  hard:
    requests.cpu: "8"
    requests.memory: "32Gi"
    limits.cpu: "16"
    limits.memory: "64Gi"
    pods: "20"
    services: "10"
    persistentvolumeclaims: "5"
    configmaps: "10"
    secrets: "10"
注意: ResourceQuota 只限制资源的总和上限,不限制单个 Pod 的资源规格。如果不对单个 Pod 做约束,一个租户可能创建一个超大规格的 Pod 挤占配额。因此,ResourceQuota 必须与 LimitRange 配合使用。

3.3 LimitRange:单个 Pod 的资源规格约束

LimitRange 在 Namespace 级别设置 Pod 和容器的默认资源请求/限制,以及最小/最大规格。它弥补了 ResourceQuota 无法约束单个 Pod 的缺陷,确保每个 Pod 的资源声明在合理范围内。

3.3.1 LimitRange 的核心能力

  • 默认值注入:如果 Pod 未显式设置资源 request/limit,LimitRange 会自动注入默认值。
  • 最小/最大约束:限制单个 Pod 或容器的资源规格不能低于最小值或超过最大值。
  • 比例约束:强制 limit/request 的比例,防止过度超卖。

3.3.2 典型 LimitRange 配置示例

apiVersion: v1
kind: LimitRange
metadata:
  name: tenant-a-limits
  namespace: tenant-a
spec:
  limits:
  - max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "500m"
      memory: "1Gi"
    defaultRequest:
      cpu: "200m"
      memory: "512Mi"
    type: Container

3.3.3 ResourceQuota 与 LimitRange 的配合关系

维度 ResourceQuota 作用 LimitRange 作用 配合效果
资源总量 限制 Namespace 内所有 Pod 的资源总和 不涉及 防止租户整体资源超限
单 Pod 规格 不涉及 限制单个 Pod 的最小/最大资源 防止单个 Pod 规格过大或过小
默认值 不涉及 为未显式声明的 Pod 注入默认值 确保所有 Pod 都有资源声明,配额计算准确
超卖控制 限制 limits 总和 限制 limit/request 比例 双重保障,避免资源争抢
ResourceQuota 与 LimitRange 配合流程 用户提交 Pod 可能未设置资源声明 步骤 1:LimitRange 准入检查 注入默认值 / 校验 min/max / 校验比例 步骤 2:ResourceQuota 准入检查 校验 Namespace 资源总和是否超限 拒绝创建 返回错误信息 Pod 创建成功 资源声明已校验 LimitRange 先校验单 Pod 规格,ResourceQuota 后校验 Namespace 总量,双重保障租户资源隔离

3.4 网络隔离策略的配合

仅靠 Namespace 逻辑分组无法实现网络层面的隔离。默认情况下,不同 Namespace 中的 Pod 可以互相通信。要实现租户间的网络隔离,必须显式部署 NetworkPolicy。

3.4.1 默认拒绝所有入站流量

在每个租户 Namespace 中部署一条默认拒绝入站的 NetworkPolicy,确保外部流量无法直接访问该 Namespace 内的 Pod。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-ingress
  namespace: tenant-a
spec:
  podSelector: {}
  policyTypes:
  - Ingress

3.4.2 允许同 Namespace 内部通信

在默认拒绝的基础上,显式允许同 Namespace 内的 Pod 互相通信,保障租户内部服务正常调用。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-same-namespace
  namespace: tenant-a
spec:
  podSelector: {}
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: tenant-a
  policyTypes:
  - Ingress

3.4.3 跨租户通信的白名单机制

如果某些场景需要跨租户通信(如共享监控服务),必须通过显式的 NetworkPolicy 白名单开放。这要求运维团队建立严格的审批流程。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-monitoring-from-tenant-b
  namespace: tenant-a
spec:
  podSelector:
    matchLabels:
      app: metrics-exporter
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          kubernetes.io/metadata.name: tenant-b
      podSelector:
        matchLabels:
          app: prometheus
  policyTypes:
  - Ingress
关键原则: 网络隔离策略应遵循“默认拒绝,按需开放”的原则。每个租户 Namespace 的初始状态应该是网络封闭的,只有经过审批的跨租户流量才被允许。这种模式与 ResourceQuota 和 LimitRange 共同构成了“软隔离”的完整闭环。

3.5 软隔离方案的局限性

基于 Namespace 的软隔离方案虽然轻量、易管理,但存在以下局限性,需要在架构设计时充分考虑:

局限性 说明 缓解措施
共享内核 所有 Pod 共享同一宿主机内核,存在内核级逃逸风险 结合 Pod Security Admission 或使用 gVisor/Kata Containers
网络策略覆盖范围 NetworkPolicy 仅控制 L3/L4 流量,无法管控 L7 应用层 引入 Service Mesh(如 Istio)实现 L7 策略
CNI 插件依赖 NetworkPolicy 需要 CNI 插件支持(如 Calico、Cilium) 选择支持 NetworkPolicy 的 CNI 插件,并验证其行为
资源配额粒度 ResourceQuota 无法区分不同优先级的工作负载 结合 PriorityClass 和资源预留机制
运维复杂度 租户数量增多时,Namespace 和策略管理成本上升 使用 GitOps 和策略即代码(如 Kyverno)自动化管理
重要提示: 软隔离方案适用于信任度较高的多租户场景(如企业内部部门间隔离)。对于需要强隔离的 SaaS 多租户或金融级合规场景,建议考虑虚拟节点(如 AWS Fargate)、多集群或硬件虚拟化方案。