3. 租户隔离蓝图设计:基于 CiliumNetworkPolicy 的租户隔离模型、租户标识(Label/ServiceAccount)设计

在 Kubernetes 多租户环境中,网络隔离是保障租户安全的第一道防线。Cilium 通过 CiliumNetworkPolicy (CNP) 提供了比传统 NetworkPolicy 更精细、更高效的隔离能力。本章将深入设计基于 CNP 的租户隔离模型,并明确租户标识(Label / ServiceAccount)的设计策略。

3.1 租户隔离模型架构

本课程采用的租户隔离模型遵循 “命名空间 + 标识 + 策略” 三层架构。每个租户拥有独立的命名空间,通过 ServiceAccount 和自定义 Label 进行身份标识,再通过 CiliumNetworkPolicy 实现东西向与南北向的流量控制。

设计原则:
  • 最小权限:默认拒绝所有跨租户流量,仅显式允许必要通信。
  • 标识驱动:使用 ServiceAccount 作为租户身份的核心载体,Label 作为辅助分组。
  • 策略分层:基础隔离策略由平台团队统一部署,租户自定义策略在命名空间内叠加。
租户隔离模型架构图 租户隔离模型架构图 Kubernetes 集群 租户 A 命名空间 (ns-tenant-a) Pod (app=frontend) sa: tenant-a-sa Pod (app=backend) sa: tenant-a-sa CiliumNetworkPolicy (允许同租户) Label: tenant=tenant-a ServiceAccount: tenant-a-sa 租户 B 命名空间 (ns-tenant-b) Pod (app=web) sa: tenant-b-sa Pod (app=db) sa: tenant-b-sa CiliumNetworkPolicy (允许同租户) Label: tenant=tenant-b ServiceAccount: tenant-b-sa 拒绝 说明: • 每个租户拥有独立命名空间,通过 ServiceAccount 绑定身份。 • 同租户 Pod 共享相同的 tenant Label 和 ServiceAccount,允许内部通信。 • 跨租户流量默认被 CiliumNetworkPolicy 拒绝,实现强隔离。

3.2 租户标识设计:Label 与 ServiceAccount

租户标识是策略匹配的基础。CiliumNetworkPolicy 支持基于 Label 和 ServiceAccount 两种方式进行身份选择。本设计采用 “ServiceAccount 为主,Label 为辅” 的策略。

标识类型 作用范围 设计建议 示例
ServiceAccount 命名空间级别 每个租户创建一个专用 ServiceAccount,作为身份锚点 tenant-a-sa
租户 Label 跨命名空间 使用 tenant=<租户名> 统一标识,便于策略匹配 tenant=tenant-a
应用 Label 命名空间内 用于区分租户内部的不同服务(如 frontend、backend) app=frontend
环境 Label 全局 标识部署环境(prod、staging),用于环境级隔离 env=prod
最佳实践: 将 ServiceAccount 作为策略中的 fromEndpoints 或 toEndpoints 匹配条件,可以避免因 Pod 重启或 Label 变更导致的策略失效。Label 更适合用于分组和可视化。

3.3 CiliumNetworkPolicy 隔离策略设计

基于上述标识设计,我们定义三类核心策略:

  1. 基础拒绝策略(Default Deny):在每个租户命名空间内部署,拒绝所有入站和出站流量,除非被显式允许。
  2. 同租户允许策略:允许相同 tenant Label 的 Pod 之间通信。
  3. 跨租户白名单策略:在需要时,显式允许特定 ServiceAccount 或 Label 的跨租户访问。

3.4 策略示例:同租户内部通信

以下策略允许租户 A 命名空间内所有具有 tenant=tenant-a Label 的 Pod 相互通信:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-same-tenant-a
  namespace: ns-tenant-a
spec:
  endpointSelector:
    matchLabels:
      tenant: tenant-a
  ingress:
    - fromEndpoints:
        - matchLabels:
            tenant: tenant-a
  egress:
    - toEndpoints:
        - matchLabels:
            tenant: tenant-a

3.5 策略示例:跨租户白名单通信

当租户 A 的 backend 服务需要访问租户 B 的 db 服务时,需要在租户 B 的命名空间中创建入站策略:

apiVersion: cilium.io/v2
kind: CiliumNetworkPolicy
metadata:
  name: allow-from-tenant-a-backend
  namespace: ns-tenant-b
spec:
  endpointSelector:
    matchLabels:
      app: db
  ingress:
    - fromEndpoints:
        - matchLabels:
            tenant: tenant-a
            app: backend
注意: 跨租户策略必须部署在目标租户的命名空间中,且需要双方管理员协商确认。Cilium 支持 fromEndpoints 跨命名空间匹配,但前提是源端 Pod 携带了正确的 Label。
策略匹配流程示意图 CiliumNetworkPolicy 策略匹配流程 源 Pod tenant=tenant-a, app=backend Cilium 策略引擎 匹配 Label & ServiceAccount 目标 Pod tenant=tenant-b, app=db 默认拒绝 除非有白名单策略 流程说明: 1. 源 Pod 发起请求 → 2. Cilium 策略引擎检查源端和目标端的 Label/ServiceAccount → 3. 匹配到跨租户白名单策略则允许,否则拒绝。

3.6 标识设计对比总结

维度 Label 方式 ServiceAccount 方式 推荐场景
灵活性 高,可动态增删改 中,创建后相对固定 Label 适合动态分组;ServiceAccount 适合固定身份
安全性 中,Label 可能被误修改 高,ServiceAccount 受 RBAC 保护 核心身份用 ServiceAccount,辅助属性用 Label
策略可读性 中,需要理解 Label 语义 高,ServiceAccount 名称直观 策略中优先使用 ServiceAccount 匹配
运维成本 低,Label 随 Pod 自动继承 中,需要为每个 Pod 指定 ServiceAccount 大规模集群建议结合使用
最终设计决策: 本课程采用 “ServiceAccount 作为租户身份主键,tenant Label 作为辅助分组” 的混合模式。所有 Pod 必须绑定对应租户的 ServiceAccount,同时携带 tenant=<租户名> Label。CiliumNetworkPolicy 中优先使用 fromEndpoints.matchLabels 匹配 ServiceAccount,其次使用 tenant Label 进行批量允许。