4. Namespace 隔离机制:Kubernetes Namespace 的作用、资源配额(ResourceQuota)、限制范围(LimitRange)、默认 ServiceAccount 隔离

在多租户集群中,Namespace 是 Kubernetes 实现软隔离的第一道防线。它并非安全边界(如网络策略或节点隔离),而是逻辑分组与资源管理的边界。本章深入剖析 Namespace 的隔离能力、资源配额(ResourceQuota)、限制范围(LimitRange)以及默认 ServiceAccount 的隔离策略,帮助你在控制平面层面构建稳固的租户资源模型。

4.1 Namespace 的核心作用与隔离边界

Namespace 将集群内的对象划分为互不干扰的虚拟空间。每个 Namespace 拥有独立的资源视图,但底层共享同一个物理集群。其核心作用包括:

  • 资源分组:将属于同一租户或项目的 Pod、Service、ConfigMap 等资源归入同一 Namespace,避免命名冲突。
  • 资源配额:通过 ResourceQuota 限制租户可消耗的 CPU、内存、存储等总量。
  • 默认限制:通过 LimitRange 为未显式设置资源请求/限制的 Pod 或容器注入默认值。
  • 访问控制:结合 RBAC,为不同 Namespace 内的 ServiceAccount 授予不同权限。
  • 网络策略:配合 NetworkPolicy 实现 Namespace 级别的网络隔离(本章不展开,后续章节详述)。
关键认知: Namespace 隔离是“逻辑隔离”而非“安全隔离”。恶意租户仍可能通过 API Server 枚举其他 Namespace 的资源名称(除非 RBAC 严格限制)。生产环境必须结合 RBAC、NetworkPolicy 和 Pod Security Standards 才能实现真正的多租户隔离。

4.2 资源配额(ResourceQuota)

ResourceQuota 是控制平面资源模型的核心组件,它定义了 Namespace 级别的资源消耗上限。当租户尝试创建超过配额的资源时,API Server 会直接拒绝请求。

4.2.1 配额类型与配置示例

资源类型 作用范围 示例
计算资源 Pod 的 CPU/内存请求与限制 requests.cpu: "10", limits.memory: "20Gi"
存储资源 PersistentVolumeClaim 的存储总量 requests.storage: "100Gi"
对象数量 Namespace 内各类对象的计数 count/deployments.apps: "10", count/services: "20"
扩展资源 GPU、FPGA 等自定义资源 requests.nvidia.com/gpu: "4"

以下是一个典型的 ResourceQuota 配置,适用于一个中等规模的租户 Namespace:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: tenant-quota
  namespace: tenant-a
spec:
  hard:
    requests.cpu: "8"
    requests.memory: "16Gi"
    limits.cpu: "16"
    limits.memory: "32Gi"
    requests.storage: "50Gi"
    persistentvolumeclaims: "10"
    count/deployments.apps: "15"
    count/services: "20"
    count/secrets: "30"
    count/configmaps: "30"
常见陷阱: 如果只设置 limits.cpu 而未设置 requests.cpu,Pod 可能因未设置请求值而被调度到资源不足的节点。建议始终同时设置 requests 和 limits 的配额,或配合 LimitRange 强制默认值。

4.3 限制范围(LimitRange)

LimitRange 解决了“未显式设置资源约束”的问题。它会在 Pod 或容器创建时,自动注入默认的资源请求/限制,或强制最小/最大值。这对于防止租户创建“无限资源”的 Pod 至关重要。

4.3.1 LimitRange 的三种策略

  • 默认值(Default):当 Pod 未设置 requests 或 limits 时,自动注入默认值。
  • 最小/最大值(Min/Max):强制 Pod 的资源请求/限制必须在指定范围内,超出则拒绝。
  • 比例限制(MaxLimitRequestRatio):限制 limits 与 requests 的比例,防止过度超卖。

示例:为租户 Namespace 设置默认的 CPU 和内存限制:

apiVersion: v1
kind: LimitRange
metadata:
  name: tenant-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
最佳实践: 在每个租户 Namespace 创建时,同时部署 ResourceQuota 和 LimitRange。ResourceQuota 控制总量上限,LimitRange 控制单个 Pod 的边界,两者配合形成“总量 + 单量”的双重约束。

4.4 默认 ServiceAccount 隔离

每个 Namespace 创建时,Kubernetes 会自动生成一个名为 default 的 ServiceAccount。如果 Pod 未显式指定 serviceAccountName,则会自动挂载该 default ServiceAccount 的 。在多租户场景下,这可能导致严重的安全风险:

  • 权限泄露:default ServiceAccount 通常绑定有集群级别的角色(如 view 或 edit),租户 Pod 可能意外获得访问其他 Namespace 资源的权限。
  • 滥用:如果 default ServiceAccount 的 被泄露,攻击者可能利用它进行横向移动。

4.4.1 隔离策略

策略 操作 效果
禁用自动挂载 在 Pod 或 Namespace 级别设置 automountServiceAccountToken: false Pod 不自动挂载任何 ServiceAccount
最小权限绑定 为 default ServiceAccount 绑定一个空角色或仅限本 Namespace 的只读角色 即使挂载 ,也无法访问其他 Namespace
专用 ServiceAccount 为每个应用创建独立的 ServiceAccount,并绑定最小权限 实现细粒度权限控制,避免共享 default 账号
自动轮换 启用 Bound Service Account Volume(Kubernetes 1.21+) 具有时间限制,降低泄露风险

以下是一个 Namespace 级别的配置,禁用 default ServiceAccount 的自动挂载:

apiVersion: v1
kind: Namespace
metadata:
  name: tenant-a
  annotations:
    # 禁用该 Namespace 下所有 Pod 的默认  挂载
    serviceaccounts.kubernetes.io/default-automount-service-account-: "false"
推荐做法: 在集群初始化时,通过准入控制器(如 OPA Gatekeeper 或 Kyverno)强制要求每个 Namespace 必须显式设置 automountServiceAccountToken 策略,并禁止使用 default ServiceAccount 运行生产工作负载。

4.5 综合隔离架构图

下图展示了 Namespace 隔离机制中 ResourceQuota、LimitRange 和 ServiceAccount 的协同工作流程:

Namespace 隔离机制协同架构 Namespace: tenant-a ResourceQuota CPU: 8 cores (requests) Memory: 16Gi (requests) Storage: 50Gi LimitRange Default CPU: 500m Default Mem: 1Gi Min/Max 约束 ServiceAccount 隔离策略 禁用自动挂载 | 最小权限绑定 | 专用 ServiceAccount | 轮换 防止 泄露与跨 Namespace 越权 ResourceQuota 控制总量上限,LimitRange 约束单 Pod 边界,ServiceAccount 隔离防止权限扩散 三者共同构成 Namespace 级别的资源与安全隔离基础

4.6 实战建议与避坑指南

  • 配额硬限制:ResourceQuota 是硬限制,一旦达到上限,后续创建请求会被立即拒绝。建议为每个租户预留 20% 的缓冲配额,避免因突发流量导致 Pod 创建失败。
  • LimitRange 与 ResourceQuota 的冲突:如果 LimitRange 设置的默认值超过了 ResourceQuota 的剩余容量,Pod 创建会失败。建议先设置 LimitRange,再设置 ResourceQuota,并确保默认值在配额范围内。
  • 默认 ServiceAccount 清理:对于生产租户 Namespace,建议删除或禁用 default ServiceAccount 的权限绑定,并创建专用的 ServiceAccount 用于工作负载。
  • 监控与告警:使用 kubectl describe resourcequota -n tenant-a 查看当前使用量,并配置 Prometheus 告警规则,当配额使用率超过 80% 时触发通知。
总结: Namespace 隔离机制是控制平面资源模型的基石。通过 ResourceQuota 控制总量、LimitRange 约束单量、ServiceAccount 隔离权限,你可以为每个租户构建一个资源边界清晰、安全可控的虚拟集群。下一章将深入网络策略,探讨如何在 Namespace 之间实现精细化的网络隔离。