深色模式
多租户隔离方案
摘要:本文面向需要在单个或少量集群中承载多个团队/客户、又想控制成本与攻击面的平台工程师。区分软隔离与硬隔离,给出基于原生 K8s 原语的隔离组合,并指出全局资源、节点内核、DNS 等"管不到"的盲区。适用版本:Kubernetes v1.28+。
适用版本与前提
- Kubernetes:v1.28+(HNC 已于 2025 年归档,见下文标注)
- 需 cluster-admin 规划命名空间、配额、网络策略
- 已了解 RBAC、PSA、NetworkPolicy(如有)
软隔离 vs 硬隔离
Kubernetes 在架构上面向单租户:单个控制面在集群所有租户间共享。隔离因此分两档:
| 类型 | 适用 | 手段 | 隔离强度 |
|---|---|---|---|
| 软隔离(Soft) | 企业内部多团队,默认不恶意 | Namespace + RBAC + NetworkPolicy + ResourceQuota + PSA | 逻辑隔离,共享节点内核 |
| 硬隔离(Hard) | 对外 SaaS / 不可信租户 | vCluster / 独立集群 | 控制面甚至节点级隔离 |
软隔离的前提假设
软隔离默认租户"非恶意"。它防的是误操作和内部越权,不防决心逃逸的内核级攻击。若租户运行不可信代码(如 KaaS 场景),必须上硬隔离或安全沙箱运行时。
原生软隔离组合
1. Namespace:逻辑边界基础
Namespace 是软隔离的地基——RBAC、NetworkPolicy、ResourceQuota、ServiceAccount 都需在 Namespace 范围内实现多租。但注意:Namespace 不隔离节点、PV、ClusterRole 等全局资源,且命名空间本身是集群级对象,能看一个就能看全部(除非用 metadata.name 列表过滤)。
2. RBAC:租户间不可互访
为每个租户创建独立 SA 与 Role/RoleBinding,限定在其命名空间内。配合 RBAC 权限模型实战 的最小权限与提权防护。不要复用 default SA。
3. NetworkPolicy:默认拒绝跨租通信
K8s 默认所有 Pod 互通。多租户必须改成默认拒绝 + 仅放行必要通信:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny
namespace: tenant-a
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]
---
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-dns
namespace: tenant-a
spec:
podSelector: {}
policyTypes: ["Egress"]
egress:
- to:
- namespaceSelector: {} # 仅允许出到集群内(含 kube-system DNS)
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 531
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
NetworkPolicy 依赖 CNI
NetworkPolicy 是否生效取决于 CNI(Calico/Cilium 等)。flannel 等部分 CNI 不支持 NetworkPolicy。部署前确认 CNI 能力。[版本相关:各 CNI 实现差异较大]
4. ResourceQuota + LimitRange:防资源耗尽
防止某租户吃满集群导致他人 Pod 被驱逐(DoS)。
yaml
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: tenant-a
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
pods: "50"
---
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-limit
namespace: tenant-a
spec:
limits:
- type: Container
default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 100m
memory: 128Mi1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
5. PSA:统一 Pod 安全基线
在租户命名空间强制 baseline 或 restricted(见 Pod Security Admission),阻断特权容器、hostPath 等逃逸路径。
6. Pod 优先级与抢占:租户间 QoS
用 PriorityClass 给不同租户不同优先级,资源紧张时高优租户抢占低优——适合差异化 SLA 的 SaaS。
全局资源泄漏:软隔离的主要盲区
软隔离管不到的全局资源
以下资源是集群级、跨租户共享,仅靠 Namespace 无法隔离:
- ClusterRole / ClusterRoleBinding / CRD / PV / Namespace 本身:任一租户若被授管理权,可见全集群。
- API server / etcd / CoreDNS:单控制面,任一租户滥用 API 或 DNS 会拖累全集群。攻击者可在任意 Pod 跑
dig SRV *.svc.cluster.local枚举集群服务——需用 CoreDNS 策略插件限制。 - 节点内核:设法拿到节点主机访问权的攻击者可读取该节点上所有 Secret/ConfigMap/Volume,并模拟 kubelet 横向移动。集群是唯一强安全边界。
HNC 与 vCluster(隔离增强)
Hierarchical Namespaces(HNC)
HNC 曾用于把命名空间做成父子层级、向下传播 RBAC/Quota 等策略,减少重复。但其仓库已于 2025 年归档,不再是活跃维护的 K8s 项目。新生产架构不应把 HNC 当作受支持特性;如仍在使用,仅作历史兼容理解。
HNC 状态 [版本相关]
公开资料指 HNC 仓库 2025 年归档,新集群不建议依赖。需要"命名空间即服务"可用 Capsule 等项目替代,但本文不展开其成熟度评估 [未实测]。
vCluster:每租户独立控制面
vCluster 在每个租户命名空间内跑一个独立控制面( Pod 形式),租户拥有自己的 API server / scheduler,消除"全局资源争用"问题,隔离强于软隔离但弱于独立集群,且增加运维复杂度。适合 KaaS / 不可信代码场景。
独立集群:硬隔离天花板
为每个租户单独集群提供最强隔离,但控制面成本高、无法共享计算、管理成百上千集群负担重。仅在强监管/高安全 SaaS 使用。
生产落地清单
TIP
- 评估租户信任等级,定软/硬隔离。
- 每租户独立 Namespace + 专用 SA + 最小 RBAC。
- 默认拒绝 NetworkPolicy + 放行 DNS。
- ResourceQuota + LimitRange 防 DoS。
- PSA
baseline/restricted全量覆盖。 - CoreDNS 策略插件限制跨租户服务发现。
- 不可信代码用安全沙箱运行时或 vCluster / 独立集群。
回滚与清理
- 收紧策略(如默认拒绝 NetworkPolicy)可能瞬间切断现有跨租通信,先
warn/audit观察再 enforce。 - 删除租户命名空间前确认 ResourceQuota 内无关键 PV(PV 是全局资源,不会随命名空间删除而自动回收)。
参考资料
- 阿里云 ACK - 多租户安全,访问日期:2026-10-08。
- Kubernetes 官方文档 - Namespaces,访问日期:2026-10-08。
- vCluster - Comparing Multi-tenancy Options,访问日期:2026-10-08。
- TheServerSide - Hierarchical Kubernetes namespaces explained,访问日期:2026-10-08(含 HNC 2025 归档说明)。
- Kubernetes 官方文档 - Pod Security Admission,访问日期:2026-10-08。