
别只用 Namespace 做隔离了你的 K8s 集群还在裸奔。写在前面坦白说我见过太多团队的 K8s 集群隔离方案只有一个建个 Namespace然后就没有然后了。这不是隔离这是心理安慰。去年帮一个 AI 创业公司做架构咨询他们 5 个团队模型训练、推理服务、数据工程、MLOps、前端应用共用一套 K8s 集群。结果某天数据工程团队的一个 Pod 因为挂载了错误的 ServiceAccount直接访问了推理服务的数据库——数据泄露全公司紧急停服 6 小时。事后复盘CTO 说了句让我记到现在的话“我们以为 Namespace 是墙结果它只是一条粉笔线。”今天这篇文章我就把 K8s 多租户隔离这件事彻底讲透。从 Namespace 的逻辑隔离到 NetworkPolicy 的网络隔离再到 Cilium 的零信任策略——三层递进层层加码。读完你会发现原来 K8s 的安全水位比你想象的高得多。一、为什么说 Namespace 只是软隔离先上一张全景图让你直观感受三层架构的差距graph TB subgraph 第一层Namespace 逻辑隔离软隔离 direction LR NS_ML[ ml-teambr/Namespace] NS_DE[ data-teambr/Namespace] NS_INF[⚙️ infra-teambr/Namespace] end subgraph 第二层NetworkPolicy 网络隔离传输层 NP_IN[ Ingress 规则br/只允许 ml-team→data-team:5432] NP_EG[ Egress 规则br/禁止 data-team→外网] NP_DEF[ Default Denybr/默认拒绝所有流量] end subgraph 第三层Cilium 零信任应用层 CL_L7[ L7 策略br/仅允许 GET /api/v1/models] CL_DNS[ DNS 策略br/仅允许 *.internal.example.com] CL_MESH[ ClusterMeshbr/跨集群加密通信] end NS_ML -- NP_IN NS_DE -- NP_IN NP_IN -- CL_L7 NP_EG -- CL_DNS NP_DEF -- CL_MESH style NS_ML fill:#e1f5fe,stroke:#0288d1 style NS_DE fill:#f3e5f5,stroke:#7b1fa2 style NS_INF fill:#e8f5e9,stroke:#388e3c style CL_L7 fill:#ffebee,stroke:#c62828 style CL_DNS fill:#fff3e0,stroke:#ef6c00 style CL_MESH fill:#e8eaf6,stroke:#2835931.1 Namespace 到底隔离了什么Namespace 是 K8s 最基础的隔离单元。它的核心能力是逻辑分组——把集群资源按命名空间划分让不同团队感觉自己在用独立的集群。具体来说Namespace 隔离的是隔离维度是否隔离说明Pod/Service/Deployment 可见性✅ 是kubectl get pods -n ml-team只能看到本命名空间ConfigMap/Secret✅ 是默认不能跨命名空间引用ServiceAccount✅ 是每个命名空间独立的 SARBAC 权限✅ 是通过 RoleRoleBinding 限定范围网络流量❌否不同 Namespace 的 Pod 默认可以互通节点资源❌ 否所有 Namespace 共享节点CRD❌ 否CRD 是集群级别的⚠️第一个警告Namespace 不隔离网络流量。默认情况下ml-team命名空间的 Pod 可以直接访问data-team命名空间的任何 Pod。这就是文章开头那个事故的根本原因。1.2 一个真实的攻击面假设你有这样一个简单部署# 模型训练团队 - ml-team 命名空间 apiVersion: v1 kind: Namespace metadata: name: ml-team --- apiVersion: apps/v1 kind: Deployment metadata: name: training-job namespace: ml-team spec: replicas: 2 selector: matchLabels: app: training-job template: metadata: labels: app: training-job spec: containers: - name: trainer image: pytorch/pytorch:2.1.0 --- # 推理服务团队 - inference-team 命名空间 apiVersion: v1 kind: Namespace metadata: name: inference-team --- apiVersion: apps/v1 kind: Deployment metadata: name: model-server namespace: inference-team spec: replicas: 3 selector: matchLabels: app: model-server template: metadata: labels: app: model-server spec: containers: - name: server image: myregistry/model-server:v2 ports: - containerPort: 8080 - containerPort: 9090 # 管理端口包含模型权重和敏感配置部署完成后training-job的 Pod可以直接 curl inference-team 的 9090 管理端口。没有任何阻拦。这就是只靠 Namespace 的后果。二、第一层加固RBAC Namespace 的资源与权限隔离在进入网络隔离之前先解决谁能干什么的问题。2.1 完整 RBAC 配置第一个建议为每个团队创建独立的 ServiceAccount然后通过 RoleRoleBinding 精准授权。永远不要给团队直接绑定 cluster-admin 或直接使用 default ServiceAccount。# # 1. 创建专用 ServiceAccount # apiVersion: v1 kind: ServiceAccount metadata: name: ml-team-sa namespace: ml-team --- # # 2. Role定义 ml-team 命名空间内的权限 # apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ml-team-role namespace: ml-team rules: # 允许管理 Pod 和 Deployment - apiGroups: [] resources: [pods, pods/log, pods/exec, services, configmaps, secrets] verbs: [get, list, watch, create, update, patch, delete] - apiGroups: [apps] resources: [deployments, replicasets, statefulsets] verbs: [get, list, watch, create, update, patch, delete] # 允许管理 Job 和 CronJob训练任务常用 - apiGroups: [batch] resources: [jobs, cronjobs] verbs: [get, list, watch, create, update, patch, delete] # 允许查看 ResourceQuota 使用情况 - apiGroups: [] resources: [resourcequotas, limitranges] verbs: [get, list, watch] # ⚠️ 明确禁止不能创建/修改 RBAC 规则 # 不授予 rbac.authorization.k8s.io 的任何权限 --- # # 3. RoleBinding把 Role 绑定到 SA # apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: ml-team-binding namespace: ml-team subjects: - kind: ServiceAccount name: ml-team-sa namespace: ml-team - kind: Group name: ml-team-members # 对接企业 OIDC/LDAP 的组 apiGroup: rbac.authorization.k8s.io roleRef: kind: Role name: ml-team-role apiGroup: rbac.authorization.k8s.io --- # # 4. 为推理服务团队创建只读跨命名空间访问 # 允许推理团队查看 ml-team 的训练状态 # apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: ml-team-readonly namespace: ml-team rules: - apiGroups: [] resources: [pods, pods/log, jobs] verbs: [get, list, watch] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: inference-read-ml namespace: ml-team subjects: - kind: ServiceAccount name: inference-team-sa namespace: inference-team roleRef: kind: Role name: ml-team-readonly apiGroup: rbac.authorization.k8s.io⚠️第二个警告Role 是命名空间级别的ClusterRole 是集群级别的。如果一个团队需要跨命名空间读权限用 RoleBinding 绑定 ClusterRole 到特定命名空间而不是直接给 ClusterRoleBinding。后者会赋予全集群的权限。2.2 最小权限原则实战RBAC 的核心哲学是最小权限Least Privilege。设计权限时遵循三个原则默认拒绝新建 SA 没有任何权限逐项添加精准授权只给需要的 verbs避免用*通配符定期审计每季度用kubectl auth can-i --list审计权限三、第二层加固ResourceQuota LimitRange 的资源配额权限是解决了但如果一个团队把集群资源吃光了怎么办3.1 完整资源配额配置第二个建议每个团队命名空间必须绑定 ResourceQuota这不是可选配置是底线配置。没有配额一个失控的 Job 就能让全集群瘫痪。# # 1. ResourceQuota限制命名空间总资源用量 # apiVersion: v1 kind: ResourceQuota metadata: name: ml-team-quota namespace: ml-team spec: hard: # --- 计算资源配额 --- requests.cpu: 32 # 总 CPU 请求量上限 requests.memory: 128Gi # 总内存请求量上限 limits.cpu: 64 # 总 CPU 限制量上限 limits.memory: 256Gi # 总内存限制量上限 # --- GPU 资源配额AI 团队必须 --- requests.nvidia.com/gpu: 8 # 最多申请 8 张 GPU # --- 对象数量配额 --- count/pods: 50 # 最多 50 个 Pod count/services: 20 # 最多 20 个 Service count/configmaps: 30 # 最多 30 个 ConfigMap count/secrets: 20 # 最多 20 个 Secret count/persistentvolumeclaims: 10 # 最多 10 个 PVC count/jobs.batch: 20 # 最多 20 个 Job count/deployments.apps: 15 # 最多 15 个 Deployment # --- 存储配额 --- requests.storage: 500Gi # 总存储请求量上限 # 按 StorageClass 限制禁止使用高性能 SSD 做临时存储 premium-ssd.storageclass.storage.k8s.io/requests.storage: 0 --- # # 2. LimitRange限制单个 Pod/Container 的资源范围 # apiVersion: v1 kind: LimitRange metadata: name: ml-team-limits namespace: ml-team spec: limits: # --- 对 Container 的限制 --- - type: Container default: cpu: 2 memory: 4Gi defaultRequest: cpu: 500m memory: 1Gi max: cpu: 8 memory: 32Gi nvidia.com/gpu: 2 # 单个容器最多 2 张 GPU min: cpu: 100m memory: 128Mi # maxLimitRequestRatio: 限制 limits/requests 比例防止超卖 maxLimitRequestRatio: cpu: 4 # limits.cpu / requests.cpu ≤ 4 memory: 2 # limits.memory / requests.memory ≤ 2 # --- 对 PVC 的限制 --- - type: PersistentVolumeClaim max: storage: 100Gi # 单个 PVC 最大 100Gi min: storage: 1Gi关键参数解释参数含义为什么重要requests.xxx调度器保证的最低资源防止空手套白狼不声明 requests 的 Pod 可能被驱逐limits.xxx容器能使用的上限防止单 Pod 吃光节点资源defaultRequest不声明时的默认值防止忘记写 resources的 PodmaxLimitRequestRatioBurstable 比例上限防止声明 requests100m 但 limits32 的超卖行为⚠️第三个警告LimitRange 的default和defaultRequest只在 Pod没有显式声明resources 时生效。如果团队把所有 Pod 都写死resources.requests.cpu: 100m但实际使用 8 核——LimitRange 拦不住需要配合 Vertical Pod AutoscalerVPA。四、第三层加固NetworkPolicy 的网络隔离终于进入正题了——网络隔离。这是从软隔离到硬隔离的分水岭。4.1 网络策略的核心概念NetworkPolicy 是 K8s 原生的网络防火墙。它基于标签选择器Label Selector来定义 Pod 之间的流量规则。三个核心概念PodSelector策略作用于哪些 PodIngress入站谁能访问我Egress出站我能访问谁关键前提NetworkPolicy 需要 CNI 插件支持。Calico、Cilium、Weave Net 都支持Flannel 默认不支持需要额外配置。4.2 默认拒绝 白名单放行策略第三个建议每个团队命名空间的第一条 NetworkPolicy永远是Default Deny All。然后再逐条添加白名单规则。用拒绝所有 按需放行替代放行所有 逐条拒绝。# # 1. 默认拒绝所有入站流量 # apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-ingress namespace: ml-team spec: podSelector: {} # 空选择器 匹配所有 Pod policyTypes: - Ingress --- # # 2. 默认拒绝所有出站流量 # apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: default-deny-egress namespace: ml-team spec: podSelector: {} policyTypes: - Egress --- # # 3. 白名单规则1允许推理服务访问模型训练 Pod 的 8080 端口 # apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-inference-to-training namespace: ml-team spec: podSelector: matchLabels: app: training-job # 作用于 training-job 的 Pod policyTypes: - Ingress ingress: - from: # 只允许 inference-team 命名空间的 model-server Pod - namespaceSelector: matchLabels: kubernetes.io/metadata.name: inference-team podSelector: matchLabels: app: model-server ports: - protocol: TCP port: 8080 # 只允许访问 8080拒绝 9090 管理端口 --- # # 4. 白名单规则2允许训练 Pod 访问数据团队的 PostgreSQL # apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-training-egress-postgres namespace: ml-team spec: podSelector: matchLabels: app: training-job policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: data-team podSelector: matchLabels: app: postgres ports: - protocol: TCP port: 5432 --- # # 5. 白名单规则3允许 DNS 查询几乎所有 Pod 都需要 # apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-dns-egress namespace: ml-team spec: podSelector: {} policyTypes: - Egress egress: - to: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: kube-system podSelector: matchLabels: k8s-app: kube-dns ports: - protocol: UDP port: 53 - protocol: TCP port: 53 --- # # 6. 监控探针白名单允许 kube-system 的 Prometheus 抓取指标 # apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: allow-monitoring namespace: ml-team spec: podSelector: {} policyTypes: - Ingress ingress: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: monitoring podSelector: matchLabels: app: prometheus ports: - protocol: TCP port: 90904.3 NetworkPolicy 的局限性标准 K8s NetworkPolicy 很强大但有几个硬伤限制说明影响仅 L3/L4只能按 IP/端口过滤不能按 HTTP 方法或路径无法做到只允许 GET /api/v1/models拒绝 POST无 DNS 策略不能按域名过滤出站流量Pod 可能访问恶意域名无加密流量不加密明文传输敏感数据可能被中间人截获单集群不能跨集群定义策略多集群架构需要额外方案标签变化无感知如果 Pod 被删重建标签变了策略可能静默失效安全漏洞这就是为什么我们需要第三层Cilium。五、终极防线Cilium NetworkPolicy 的零信任策略5.1 Cilium 是什么一句话Cilium 是基于 eBPF 的云原生网络、安全、可观测性平台。它用 Linux 内核的 eBPF 技术在数据路径上执行策略性能极高功能远超标准 NetworkPolicy。对于多租户隔离Cilium 的核心价值在于L7应用层策略按 HTTP 方法、路径、Header 过滤流量DNS 策略按域名白名单控制出站流量透明加密WireGuard 或 IPsec 加密跨节点流量身份感知基于 Pod 标签的身份而非 IP 地址做策略ClusterMesh跨集群的服务发现和策略同步这一层的架构如下graph LR subgraph K8s 集群 A subgraph ml-team Namespace PA[training-jobbr/Podbr/IP: 10.0.1.5] end subgraph inference-team Namespace PB[model-serverbr/Podbr/IP: 10.0.2.8] end CA[Cilium Agentbr/eBPF 程序] end subgraph K8s 集群 B subgraph data-team Namespace PC[postgresbr/Podbr/IP: 10.1.3.12] end CB[Cilium Agentbr/eBPF 程序] end PA --|L7 策略检查br/✅ GET /api/v1/modelsbr/❌ DELETE /api/v1/models| CA CA --|WireGuard 加密隧道| CB CB --|DNS 策略检查br/✅ *.internal.example.combr/❌ external-api.com| PC style CA fill:#1a237e,color:#fff,stroke:#ff6f00,stroke-width:2px style CB fill:#1a237e,color:#fff,stroke:#ff6f00,stroke-width:2px style PA fill:#e3f2fd,stroke:#1565c0 style PB fill:#fce4ec,stroke:#c62828 style PC fill:#e8f5e9,stroke:#2e7d325.2 CiliumNetworkPolicy 完整示例Cilium 提供了 CRDCiliumNetworkPolicy是标准 NetworkPolicy 的超集。# # 1. Cilium L7 策略只允许特定 HTTP 方法访问模型服务 # apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: model-server-l7-policy namespace: inference-team spec: endpointSelector: matchLabels: app: model-server ingress: # 规则1允许 GET /api/v1/models只读查询 - fromEndpoints: - matchLabels: app: frontend toPorts: - ports: - port: 8080 protocol: TCP rules: http: - method: GET path: /api/v1/models/.* # 正则匹配只允许查模型 - method: POST path: /api/v1/inference # 允许推理请求 # 规则2允许 ML 团队 Pod 的 DELETE 操作管理接口 - fromEndpoints: - matchLabels: team: ml-team toPorts: - ports: - port: 8080 protocol: TCP rules: http: - method: GET path: /api/v1/.* - method: DELETE path: /api/v1/models/.* --- # # 2. Cilium DNS 策略只允许解析特定域名 # 这是标准 NetworkPolicy 完全做不到的 # apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: dns-egress-whitelist namespace: ml-team spec: endpointSelector: matchLabels: app: training-job egress: # 允许访问内部服务 - toEndpoints: - matchLabels: app: model-server io.kubernetes.pod.namespace: inference-team # 允许 DNS 查询必须先允许 DNS - toEndpoints: - matchLabels: k8s:io.kubernetes.pod.namespace: kube-system k8s:k8s-app: kube-dns toPorts: - ports: - port: 53 protocol: UDP rules: dns: - matchPattern: *.internal.example.com # 只允许内部域名 - matchPattern: pypi.org # 允许 Python 包索引 - matchPattern: *.docker.com # 允许 Docker 镜像拉取 # 允许基于 DNS 解析结果的 HTTPS 出站仅白名单域名 - toFQDNs: - matchPattern: *.internal.example.com - matchPattern: pypi.org - matchPattern: *.docker.com toPorts: - ports: - port: 443 protocol: TCP --- # # 3. Cilium ClusterMesh 跨集群策略 # 集群 A 的 Pod 只能访问集群 B 中特定身份的服务 # apiVersion: cilium.io/v2 kind: CiliumNetworkPolicy metadata: name: cross-cluster-training-to-data namespace: ml-team spec: endpointSelector: matchLabels: app: training-job egress: # 允许跨集群访问 data-team 的 PostgreSQL - toEndpoints: - matchLabels: app: postgres team: data-team # 注意Cilium 的身份模型基于标签不关心 IP # ClusterMesh 自动同步标签到所有集群 toPorts: - ports: - port: 5432 protocol: TCP --- # # 4. Cilium 透明加密配置CiliumConfig CRD # apiVersion: cilium.io/v2alpha1 kind: CiliumConfig metadata: name: default namespace: kube-system spec: encryption: enabled: true type: wireguard # 或 ipsec nodeEncryption: true # 节点间流量也加密第四个建议Cilium DNS 策略是反制数据外泄的利器。很多攻击手法依赖 DNS 隧道DNS Tunneling来绕过传统防火墙。Cilium 的 DNS 白名单从内核层面就封死了这条路。5.3 ClusterMesh跨集群的身份感知ClusterMesh 是 Cilium 的跨集群通信方案它的核心设计理念是不依赖 Service 类型不需要 LoadBalancer 或 NodePort身份同步标签identity通过 etcd 在集群间同步策略一致同一个CiliumNetworkPolicy可以作用于跨集群流量透明加密WireGuard 自动加密跨集群流量sequenceDiagram participant PodA as training-jobbr/(集群A, ml-team) participant CA as Cilium Agent A participant CB as Cilium Agent B participant PodB as postgresbr/(集群B, data-team) PodA-CA: TCP SYN → postgres:5432 CA-CA: ① 查询本地策略br/✅ egress 允许→apppostgres CA-CA: ② 查询身份缓存br/目标身份ID4567 CA-CB: ③ WireGuard 加密隧道 CB-CB: ④ 查询本地策略br/✅ ingress 允许←apptraining-job CB-PodB: ⑤ 转发流量到目标 Pod PodB--CB: 响应 CB--CA: ⑥ WireGuard 解密 CA--PodA: 响应 Note over CA,CB: 全程加密身份验证br/不依赖 IP 地址六、三层隔离对比总结一张表看清楚三层架构的能力差距能力维度仅 Namespace NetworkPolicy Cilium逻辑分组✅✅✅RBAC 权限隔离✅✅✅资源配额限制✅需配置✅✅网络隔离L3/L4❌✅✅默认拒绝流量❌✅✅按 HTTP 方法/路径过滤❌❌✅DNS 域名白名单❌❌✅跨节点流量加密❌❌✅跨集群策略❌❌✅身份感知非 IP 依赖❌❌✅可观测性Hubble❌❌✅入群门槛极低中等较高适用场景开发测试生产环境多租户/合规/零信任落地建议开发/测试环境Namespace RBAC ResourceQuota 基本够用生产环境必须加上 NetworkPolicy且第一条策略一定是 Default Deny多团队共享集群Namespace RBAC ResourceQuota NetworkPolicy 是最低配置金融/医疗/合规场景必须上 CiliumL7 策略 DNS 策略 透明加密缺一不可多云/混合云Cilium ClusterMesh 是目前最成熟的跨集群方案之一⚠️第四个警告额外赠送网络策略的测试不要在生产环境做。先在 Staging 环境用kubectl exec验证每条策略的实际效果确认无误后再推生产。一次配错的 NetworkPolicy 可能导致整个服务不可用。七、实战 Checklist5 个 AI 团队共享集群的完整配置清单假设你有 5 个团队ml-team、inference-team、data-team、mlops-team、frontend-team。每个团队必须配置的 8 件套[ ] 1. 独立 Namespace [ ] 2. 专用 ServiceAccount [ ] 3. Role最小权限 RoleBinding [ ] 4. ResourceQuota总资源上限 [ ] 5. LimitRange单 Pod 资源范围 [ ] 6. NetworkPolicy - Default Deny Ingress [ ] 7. NetworkPolicy - Default Deny Egress [ ] 8. NetworkPolicy - 白名单规则按需集群级别额外配置[ ] 9. Node 污点和容忍度关键系统 Pod 绑定专用节点 [ ] 10. PodSecurityPolicy / Pod Security Admission限制特权容器 [ ] 11. OPA/Gatekeeper自定义策略引擎可选 [ ] 12. CiliumNetworkPolicyL7 DNS 加密推荐 [ ] 13. Hubble 可观测性流量监控和审计 [ ] 14. 审计日志定期审查 kubectl 操作记录 文末三件套 一句话总结Namespace 是粉笔线NetworkPolicy 是铁丝网Cilium 是指纹识别防弹玻璃——K8s 多租户隔离至少盖两层最好盖三层。 延伸阅读Kubernetes NetworkPolicy 官方文档Cilium NetworkPolicy 文档Cilium ClusterMesh 指南Kubernetes RBAC Good PracticeseBPF 技术概述 下期预告《AI 团队的 K8s GPU 调度指南从 Device Plugin 到 MIG 再到 Kubeflow》——GPU 利用率从 30% 提升到 85% 的实战方案。关注我别走丢。原创不易如果这篇文章帮你避开了至少一个生产事故请点赞 收藏 关注三连支持 有问题欢迎评论区交流看到必回。标签K8s多租户NamespaceNetworkPolicyCiliumRBAC隔离