3. 多云Kubernetes平台身份与访问治理

当企业从单集群走向多云多集群,身份与访问治理会从“能登录、能授权”升级为“谁能以什么身份、在哪些集群、对哪些资源、做什么操作,并且可追溯”。多云环境最大的变化不是 Kubernetes API 本身,而是身份源分散、集群边界增多、权限映射链路变长。如果每个集群各自维护用户和角色,人员离职、岗位轮换、临时授权都会变成审计黑洞。因此,本节围绕统一身份源、RBAC、OIDC、服务账户、最小权限、跨集群角色映射、审计与合规基线展开,目标是建立一条可验证的身份信任链。

统一身份源:把“人”的入口收敛

多云平台不应让运维人员直接使用集群内静态用户或客户端证书登录。推荐做法是以企业 IdP(如 Keycloak、Azure AD、Okta、LDAP 对接的统一认证服务)作为唯一身份源,Kubernetes API Server 通过 OIDC 接入。OIDC 的核心参数包括 issuer-url、client-id、username-claim、groups-claim。例如:

--oidc-issuer-url=https://idp.example.com/realms/platform
--oidc-client-id=kubernetes
--oidc-username-claim=preferred_username
--oidc-groups-claim=groups
--oidc-groups-prefix=oidc:

其中 groups-claim 决定后续 RBAC 的绑定对象。若 IdP 中用户属于 platform-sre 组,则 API Server 看到的组名是 oidc:platform-sre。这样,人员变动只需在 IdP 调整组成员关系,无需在每个集群增删用户。需要注意:OIDC 只解决“认证”,不解决“授权”;授权仍由各集群 RBAC 完成。

RBAC:把权限绑定到角色而不是个人

Kubernetes RBAC 由 Role/ClusterRole 与 RoleBinding/ClusterRoleBinding 组成。Role 是命名空间级,ClusterRole 是集群级;Binding 把主体(User、Group、ServiceAccount)与角色关联。多云治理中应坚持只给 Group 绑定,不给个人绑定,因为个人绑定无法随 IdP 组变化自动收敛。一个典型的只读角色如下:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: platform-viewer
rules:
- apiGroups: [""]
  resources: ["pods","services","configmaps"]
  verbs: ["get","list","watch"]
- apiGroups: ["apps"]
  resources: ["deployments","statefulsets"]
  verbs: ["get","list","watch"]

再通过 ClusterRoleBinding 将 oidc:platform-viewer 组绑定到该角色。这里的关键判断是:verbs 是否包含 write 类动作。如果只读角色出现 create、update、delete、patch,就应视为越权风险。最小权限不是“少给一点”,而是“按任务闭环给到刚好够用”。

服务账户:工作负载的身份不能复用人的身份

Pod 访问 API Server 时使用 ServiceAccount,而不是用户身份。每个命名空间默认有 default ServiceAccount,但不应让业务 Pod 直接使用它。推荐为每个工作负载创建独立 ServiceAccount,并只绑定所需 Role。例如日志采集器只需要读取 Pod 和 Namespace:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: log-collector
  namespace: observability
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: pod-reader
  namespace: observability
rules:
- apiGroups: [""]
  resources: ["pods","namespaces"]
  verbs: ["get","list","watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: log-collector-binding
  namespace: observability
subjects:
- kind: ServiceAccount
  name: log-collector
  namespace: observability
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

在多云场景中,还要控制 ServiceAccount 的令牌投射。默认的长期 Secret Token 已不推荐,应使用 automountServiceAccountToken: false 或投射短期令牌,并限制 audience。若工作负载需要访问外部云服务,优先使用云厂商的 Workload Identity / IRSA / OIDC 联邦,而不是把云 AK 写入 Secret。

跨集群角色映射:同一角色名,不同集群落地

多云平台通常有中心管控集群和多个业务集群。跨集群角色映射的核心是:中心定义角色语义,各集群落地为本地 RBAC。例如中心定义 platform-viewer、platform-operator、platform-admin 三档,通过 GitOps 将 ClusterRole 和 Binding 分发到各集群。映射时要处理命名空间差异:中心叫 team-a,集群 B 可能叫 ns-team-a,需要在分发层做命名空间重写。下图展示统一身份源到多集群 RBAC 的信任链与映射关系:

多云 Kubernetes 身份信任链与跨集群 RBAC 映射 统一身份源 IdP 用户 / 组 / MFA groups: platform-sre OIDC issuer OIDC Token JWT + groups API Server 认证 验证签名 / 过期时间 提取 User + Groups oidc:platform-sre 授权判定 RBAC 匹配 RBAC 授权层 ClusterRole: platform-viewer ClusterRoleBinding → oidc:platform-sre verbs: get / list / watch 集群 A(中心管控) ns: platform-system ClusterRole: platform-viewer Binding: oidc:platform-sre 状态:已同步 集群 B(业务) ns: ns-team-a ClusterRole: platform-viewer Binding: oidc:platform-sre 状态:已同步 集群 C(边缘) ns: edge-team-a ClusterRole: platform-viewer Binding: oidc:platform-sre 状态:待同步 GitOps 分发与映射层 角色语义:viewer / operator / admin 命名空间重写:team-a → ns-team-a 审计:谁在何时改了 Binding 合规基线:禁止个人绑定、禁止 cluster-admin 直授、ServiceAccount 最小化 ServiceAccount 独立身份

图中可以看到,用户身份从 IdP 出发,经 OIDC 认证后进入 API Server,再由 RBAC 判定权限;而工作负载身份走 ServiceAccount 通道,两者不应混用。跨集群映射层负责把中心角色语义翻译成各集群的本地 RBAC,并处理命名空间差异。

审计与合规基线:让权限可追溯、可收敛

审计要回答三个问题:谁、在哪个集群、对什么资源做了什么。Kubernetes Audit Policy 应至少记录 RequestResponse 级别的写操作和 Metadata 级别的读操作。关键字段包括 user.username、user.groups、verb、resource、namespace、responseStatus.code。例如一条审计日志显示 oidc:platform-sre 对 deployments 执行了 delete,若该组本应只读,就应立即告警。

合规基线建议固化为可检查的规则,而不是停留在文档:

  • 禁止个人绑定:RoleBinding/ClusterRoleBinding 的 subjects 中不得出现 kind: User,只允许 Group 和 ServiceAccount。
  • 禁止直授 cluster-admin:除 break-glass 账户外,任何组不得绑定 cluster-admin;break-glass 账户必须启用 MFA 并单独审计。
  • ServiceAccount 最小化:默认命名空间不得自动挂载令牌;每个工作负载使用独立 SA,且 Role 中不得出现 * 资源或 * verbs。
  • 跨集群一致性:同一角色名在各集群的 rules 差异必须可解释,差异项需登记例外并设置复核周期。
  • 审计留存:审计日志集中采集到中心存储,保留周期不少于 180 天,并支持按用户、集群、资源三维检索。
落地顺序建议:先接 OIDC 统一认证,再收敛 RBAC 到组绑定,然后治理 ServiceAccount,最后用 GitOps 做跨集群分发和审计基线校验。每一步都应能在审计日志中看到前后变化。

多云身份治理的最终判断标准不是“配置是否写完”,而是:新增或离职一名成员时,是否只需改 IdP 组;新增一个集群时,是否只需挂载同一套角色语义;发生越权时,是否能在审计日志中定位到具体用户、集群和资源。做到这三点,身份与访问治理才算真正闭环。