命名空间作为租户边界
在多租户 Kubernetes 集群中,命名空间(Namespace)是逻辑隔离的第一道防线。它不提供网络层面的硬隔离,但为资源配额、访问控制、网络策略提供了清晰的作用域边界。理解命名空间的本质、创建方式与最佳实践,是构建安全多租户架构的基石。
2.1 命名空间的概念
命名空间是 Kubernetes 集群内的一种虚拟分区机制,用于将集群物理资源划分为多个逻辑单元。每个命名空间内的资源名称必须唯一,但不同命名空间之间允许存在同名资源。
| 特性 | 说明 |
|---|---|
| 资源作用域 | Pod、Service、Deployment、ConfigMap、Secret 等资源属于命名空间级别 |
| 全局资源 | Node、PersistentVolume、ClusterRole、Namespace 本身不属于任何命名空间 |
| 默认命名空间 | 集群安装后自动创建 default、kube-system、kube-public、kube-node-lease |
| 隔离粒度 | 逻辑隔离,非网络硬隔离;需配合 NetworkPolicy 实现网络隔离 |
关键认知:命名空间是租户边界的逻辑起点,但仅靠命名空间无法阻止跨命名空间的 Pod 通信。必须结合 RBAC、ResourceQuota、NetworkPolicy 才能构成完整的租户隔离方案。
2.2 命名空间的创建与管理
2.2.1 通过命令行创建
# 创建命名空间
kubectl create namespace tenant-alpha
# 查看所有命名空间
kubectl get namespaces
# 查看命名空间详细信息
kubectl describe namespace tenant-alpha
2.2.2 通过 YAML 清单创建
apiVersion: v1
kind: Namespace
metadata:
name: tenant-beta
labels:
team: beta
environment: production
isolation-level: strict
# 应用 YAML 文件
kubectl apply -f namespace-beta.yaml
2.2.3 命名空间生命周期管理
| 操作 | 命令 | 注意事项 |
|---|---|---|
| 创建 | kubectl create namespace <name> |
名称需符合 DNS 标签规范(小写字母、数字、连字符) |
| 查看 | kubectl get ns <name> -o yaml |
可查看命名空间的最终状态(Active 或 Terminating) |
| 删除 | kubectl delete namespace <name> |
删除命名空间会级联删除其下所有资源,操作不可逆 |
| 更新标签 | kubectl label namespace <name> key=value |
标签常用于 NetworkPolicy 选择器和 RBAC 绑定 |
⚠ 删除风险:删除命名空间时,其下所有 Pod、Service、ConfigMap、PVC 等资源会被立即清理。生产环境中务必确认命名空间内无运行中的关键业务,或先执行资源备份。
2.3 命名空间作为逻辑隔离单元的最佳实践
2.3.1 租户命名空间设计模式
在多租户场景中,推荐为每个租户分配独立的命名空间,并采用统一的命名规范与标签体系。
# 租户命名空间命名规范示例
tenant-{租户ID}-{环境}
# 实际案例
tenant-alpha-production
tenant-alpha-staging
tenant-beta-production
2.3.2 标签标准化策略
为每个命名空间附加标准标签,便于后续 NetworkPolicy 选择、资源监控与成本分摊。
apiVersion: v1
kind: Namespace
metadata:
name: tenant-gamma-prod
labels:
tenant-id: gamma
environment: production
compliance-level: pci-dss
owner: platform-team
2.3.3 资源配额与限制范围
通过 ResourceQuota 和 LimitRange 防止单个租户耗尽集群资源。
apiVersion: v1
kind: ResourceQuota
metadata:
name: tenant-quota
namespace: tenant-alpha
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
persistentvolumeclaims: 5
pods: 50
apiVersion: v1
kind: LimitRange
metadata:
name: tenant-limits
namespace: tenant-alpha
spec:
limits:
- default:
cpu: 500m
memory: 512Mi
defaultRequest:
cpu: 200m
memory: 256Mi
type: Container
2.3.4 命名空间隔离最佳实践清单
- 每个租户一个命名空间:避免多个租户共享同一命名空间,防止资源名称冲突与权限混乱。
- 使用标签标识租户属性:为命名空间打上
tenant-id、environment、compliance等标签,便于自动化策略管理。 - 设置 ResourceQuota:为每个租户命名空间设置 CPU、内存、存储、Pod 数量的硬限制。
- 配置 LimitRange:为命名空间内的容器设置默认资源请求与限制,防止单个 Pod 异常占用。
- 启用 NetworkPolicy:默认拒绝入站流量,仅允许同命名空间内通信或显式授权的跨命名空间访问。
- 绑定 RBAC 角色:为租户管理员授予其命名空间内的
admin或edit角色,限制集群级别权限。 - 禁止使用 default 命名空间:生产环境应将 default 命名空间视为不可用,强制所有工作负载部署在指定租户命名空间。
实践要点:命名空间是租户隔离的起点而非终点。一个健壮的多租户架构 = 命名空间(逻辑边界)+ ResourceQuota(资源边界)+ NetworkPolicy(网络边界)+ RBAC(权限边界)。
2.4 命名空间隔离架构示意
下图展示了一个典型的多租户集群中,命名空间如何作为逻辑隔离单元组织租户资源,以及 NetworkPolicy 如何控制跨命名空间流量。
2.5 命名空间状态与故障排查
命名空间可能处于以下状态,理解这些状态有助于快速定位多租户环境中的问题。
| 状态 | 含义 | 常见原因 |
|---|---|---|
| Active | 命名空间正常运行,可部署资源 | 正常状态 |
| Terminating | 命名空间正在被删除,但仍有资源残留 | 存在 Finalizer 未清理、CRD 资源未删除、APIService 引用 |
| Missing | 命名空间不存在 | 已被删除或从未创建 |
排查技巧:当命名空间卡在 Terminating 状态时,执行
kubectl get namespace <name> -o json | jq '.spec.finalizers' 查看残留的 Finalizer。若确认无影响,可使用 kubectl replace --raw "/api/v1/namespaces/<name>/finalize" -f <json> 强制移除 Finalizer。
2.6 命名空间设计决策对比
| 设计维度 | 推荐做法 | 不推荐做法 |
|---|---|---|
| 租户映射 | 一个租户一个命名空间 | 多个租户共享一个命名空间 |
| 命名规范 | tenant-{id}-{env} 统一前缀 |
无规律、无标识的命名 |
| 标签体系 | 标准标签:tenant-id, environment, owner | 无标签或标签不完整 |
| 资源配额 | 每个命名空间必设 ResourceQuota + LimitRange | 依赖集群默认值或不设置 |
| 网络策略 | 默认拒绝入站 + 显式允许规则 | 依赖命名空间逻辑隔离,不配置 NetworkPolicy |
| RBAC 权限 | 租户管理员仅拥有命名空间级别 role | 授予集群级别 cluster-admin 权限 |
命名空间作为租户边界,是构建多租户 Kubernetes 集群的第一步。下一层隔离将由 NetworkPolicy 提供网络层面的精细控制,确保即使 Pod IP 被泄露,也无法越权访问其他租户的资源。