- 云原生
- 后端
- 开发工具
- 微服务
【免费下载链接】operator-sdk
SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.
Operator 在集群中运行时,通常会借助一个主 ServiceAccount(由 Deployment 的serviceAccountName指定)获得执行调谐所需的权限。但在实际生产环境中,Operator 创建的对象可能横跨多个命名空间、涉及 OpenShift 安全上下文约束(SCC)等特殊资源,单一账户的权限要么过大、要么不足。Operator-SDK 提供了operator-sdk generate bundle的--extra-service-accounts标志,让你可以在生成 Bundle(ClusterServiceVersion / CSV)时,将额外的 ServiceAccount 及其绑定的 Role/ClusterRole 权限一并纳入 CSV,实现"一个 Operator、多个最小权限账户"的部署形态。
本文以仓库文档 multi-sa.md 为主线,结合源码讲解该标志的完整配置流程、底层权限归并逻辑与测试验证,读完即可在自己的 Operator 项目中落地多 ServiceAccount 方案。
为什么需要多个 ServiceAccount
Kubernetes 中的 ServiceAccount 是 Pod 访问 API Server 的身份凭证。默认情况下,使用operator-sdk init脚手架创建的 Operator 只有一个 Deployment 账户,所有由该 Operator 创建的 Pod、Job、CronJob 等负载如果复用同一账户,就会继承过宽的权限面。
文档明确指出:
There may be a need to have multiple service accounts to provide only the necessary permissions to various objects that the operator creates on a Kubernetes cluster.
即:Operator 创建的不同对象可能需要不同的权限集合,通过为它们分配独立的 ServiceAccount,可以将权限精确限定到"该对象完成工作所必需的最小范围"。这在以下场景尤为典型:
- Operator 在目标命名空间创建执行任务的 Pod,需要访问特定 ConfigMap/Secret,但不应该拥有集群级管理权限;
- 在 OpenShift 上运行的 Operator 需要为某些工作负载授予
privilegedSCC(SecurityContextConstraint),但不应将这种高风险权限授予 Operator 自身账户。
--extra-service-accounts标志是什么
在 cmd.go 中可以看到该标志的准确定义:
fs.StringSliceVar(&c.extraServiceAccounts, "extra-service-accounts", nil, "Names of service accounts, outside of the operator's Deployment account, "+ "that have bindings to {Cluster}Roles that should be added to the CSV")关键信息有三点:
- 类型为
StringSliceVar:接受以逗号分隔的字符串列表,因此可以在一次生成中指定多个额外账户,例如--extra-service-accounts sa-a,sa-b,sa-c; - 默认值为
nil:不指定时,行为与旧版本完全一致,只处理 Deployment 引用的那个账户; - 作用范围:这些账户是"Deployment 账户之外的"账户,它们通过 RoleBinding / ClusterRoleBinding 绑定的 {Cluster}Role 会被收集进生成的 CSV 权限字段。
CLI 参考文档 operator-sdk_generate_bundle.md 中给出的说明与之完全一致:这些账户是"拥有 {Cluster}Roles 绑定、应被添加到 CSV 的 ServiceAccount 名称"。
第一步:更新 Makefile 的 bundle 目标
为了让权限配置在每次重新生成 Bundle 时不被覆盖,文档建议修改项目Makefile中的bundle目标,把标志固化进去:
bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files. operator-sdk generate kustomize manifests -q cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG) $(KUSTOMIZE) build config/manifests | operator-sdk generate bundle -q --overwrite --extra-service-accounts myOperator-name-additional-service-account --version $(VERSION) $(BUNDLE_METADATA_OPTS) operator-sdk bundle validate ./bundle其中myOperator-name-additional-service-account需要替换为"附加到 Operator 名称之后"的账户名。整条链路为:
operator-sdk generate kustomize manifests -q:刷新 kustomize manifests;kustomize edit set image:把管理器镜像更新为最新构建的$(IMG);kustomize build config/manifests | operator-sdk generate bundle ...:构建清单并通过管道交给 bundle 生成器;--overwrite:允许覆盖已存在的 Bundle 元数据与 Dockerfile(cmd.go 中该标志默认即为true);operator-sdk bundle validate ./bundle:生成后立即校验 Bundle 合法性。
由于--extra-service-accounts是幂等生成流程的一部分,每次运行make bundle都会重新应用该账户列表,因此手工修改生成的 CSV 不会在下一次生成时被保留——正确做法就是把账户声明固化在 Makefile 中。
第二步:为每个额外账户创建 RBAC 资源
文档强调:以下步骤需要对每一个额外的 ServiceAccount 重复执行。
1. 创建 ServiceAccount
cat << EOF > config/rbac/additional_service_account.yaml apiVersion: v1 kind: ServiceAccount metadata: name: additional-service-account namespace: system EOF命名空间system是 kustomize 默认的替换占位符,make bundle时会被替换为实际部署命名空间。
2. 创建角色绑定(RoleBinding 或 ClusterRoleBinding)
文档示例使用ClusterRoleBinding,将账户绑定到集群级角色:
cat << EOF > config/rbac/additional_role_binding.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: additional-service-account-rolebinding roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: additional-service-account-role subjects: - kind: ServiceAccount name: additional-service-account namespace: system EOF如果只需要命名空间内权限,改用RoleBinding并让roleRef.kind: Role即可。注意:绑定是 CSV 权限归并的关键入口,生成器正是通过"绑定中的 ServiceAccount subject"反查角色的。
3. 创建带目标权限的角色
文档示例创建一个ClusterRole,仅授予对 OpenShiftprivilegedSCC 的use权限:
cat << EOF > config/rbac/additional_role.yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: creationTimestamp: null name: additional-service-account-role rules: - apiGroups: - security.openshift.io resourceNames: - privileged resources: - securitycontextconstraints verbs: - use EOF这是多 ServiceAccount 最典型的实战用途:Operator 自身账户保持低权限,而需要运行特权容器的工作负载单独绑定一个仅含securitycontextconstraints/use权限的账户,把高敏感权限限制在最小范围内。
第三步:把 RBAC 文件注册进 kustomization.yaml
新创建的三个文件必须登记到 RBAC 的 kustomization 中,否则kustomize build config/manifests不会收集它们:
cat << EOF >> config/rbac/kustomization.yaml # Add MyCustomObject service account - additional_service_account.yaml - additional_role.yaml - additional_role_binding.yaml EOF对应的可参考仓库结构是 testdata/go/v4/memcached-operator/config/rbac:脚手架默认的 RBAC 目录正是config/rbac,其中包含service_account.yaml、role.yaml、role_binding.yaml等基础文件,新增文件遵循同样的组织方式即可。
源码原理:CSV 如何归并账户与权限
理解了配置流程后,再深入源码看--extra-service-accounts到底做了什么。核心逻辑在 clusterserviceversion.go 的SplitCSVPermissionsObjects(extraSAs []string):
// Create a set of ServiceAccount names to match against below. csvSAs := make(map[string]struct{}) for _, dep := range c.Deployments { saName := dep.Spec.Template.Spec.ServiceAccountName if saName == "" { saName = defaultServiceAccountName // "default" } csvSAs[saName] = struct{}{} } for _, extraSA := range extraSAs { csvSAs[extraSA] = struct{}{} }这段代码揭示了归并规则:
- 生成器首先收集所有 Deployment 的
serviceAccountName(未显式指定时按default处理)作为"CSV 内账户集合"; - 再把
--extra-service-accounts传入的账户名并入同一个集合; - 然后遍历所有 RoleBinding / ClusterRoleBinding,凡是 subject 中出现了集合内账户名的绑定,其
roleRef指向的 Role / ClusterRole 就会被归入 CSV 的spec.install.spec.permissions(命名空间级)或clusterPermissions(集群级); - 未被任何集合内账户绑定的 Role / ClusterRole、以及绑定了非集合账户的绑定对象,则被归入
out,由 manifests.go 中的GetManifestObjects原样写入 Bundle 的 manifests 目录(bundle/manifests/),不进入 CSV 权限字段。
函数注释对此总结得很精确(clusterserviceversion.go):
SplitCSVPermissionsObjects splits Roles and ClusterRoles bound to ServiceAccounts in Deployments and extraSA's. Roles and ClusterRoles bound to RoleBindings associated with ServiceAccounts are added to inPerms. ClusterRoles bound to ClusterRoleBindings associated with ServiceAccounts are added to inCPerms.
而ExtraServiceAccounts字段在 clusterserviceversion.go 中的注释同样点明:它们是"在通过 Bindings 匹配要纳入 CSV 的 {Cluster}Roles 时需要考虑的 ServiceAccount 名称"。
此外,manifests.go 中removeNamespace会把写入 manifests 目录的对象 namespace 清空——这是为了通过 OLM 校验,因为命名空间资源由 OLM 在安装时动态注入。
测试验证:多账户权限归并行为
仓库中的单元测试 clusterserviceversion_test.go 直接验证了上述行为。测试构造了my-dep-account(Deployment 账户)与my-other-account(额外账户)两个 ServiceAccount,以及一组交错绑定的 Role/ClusterRole:
- 当只传 Deployment 账户(
SplitCSVPermissionsObjects(nil))时,role2、clusterrole2以及相关的绑定、my-other-account本身全部落入out,即被排除在 CSV 之外; - 当传入
[]string{"my-other-account"}时,role1、role2进入inPerms,clusterrole1、clusterrole2进入inCPerms,out为空——所有权限都被正确吸收进 CSV。
这从测试层面印证了多账户场景下"权限全量归并、账户与绑定正确入 CSV"的实现事实。
生成后的结果与验证
执行make bundle后,建议从两个方面验证:
- 查看 CSV 权限字段:打开
bundle/manifests/<operator-name>.clusterserviceversion.yaml,在spec.install.spec下应能看到:permissions:与额外账户存在 RoleBinding 关联的 Role 规则;clusterPermissions:与额外账户存在 ClusterRoleBinding 关联的 ClusterRole 规则(如文档示例中的 SCCuse权限);deployments段仍指向 Operator 自身的 Deployment 与主账户。
- 查看 manifests 目录:
bundle/manifests/下会额外写出未被 CSV 吸收的 RBAC 对象(manifests.go),它们由 OLM 安装时一并部署。
同时make bundle末尾的operator-sdk bundle validate ./bundle会执行 OLM 相关校验,若有权限字段格式问题会直接报错,是每轮修改后的必要检查步骤。
注意事项小结
--extra-service-accounts接受逗号分隔的多个账户名(StringSliceVar类型,见 cmd.go),一次可声明多个;- 每个额外账户都需要独立完成"ServiceAccount + 绑定 + 角色 + kustomization 注册"四步,缺一不可;
- 只有"绑定中 subject 包含目标账户"的 Role/ClusterRole 才会被写入 CSV;与任何已声明账户无关的 RBAC 会被原样放入 Bundle manifests 而非 CSV;
- 账户名单应固化在
Makefile的bundle目标中,否则重新生成时手工改动会被覆盖; - 生成器将 Deployment 未显式指定
serviceAccountName视为default(见 clusterserviceversion.go),因此显式声明账户名有助于避免歧义。
通过以上配置,你的 Operator 可以在保持自身低权限的同时,为集群内不同职责的工作负载分别授予恰如其分的权限,实现真正意义上的多 ServiceAccount 最小权限部署。
- 云原生
- 后端
- 开发工具
- 微服务
【免费下载链接】operator-sdk
SDK for building Kubernetes applications. Provides high level APIs, useful abstractions, and project scaffolding.
相关推荐
Argo Workflows 服务账户(ServiceAccount)配置实战指南:RBAC 绑定、权限模型与最小权限实践
Argo Workflows 服务账户(ServiceAccount)配置实战指南:RBAC 绑定、权限模型与最小权限实践 导读 本文围绕 Argo Workf
云原生容器编排工作流自动化任务调度后端Apache Airflow 自定义 Operator 附加链接(Extra Links):为任务 UI 增加外部系统入口
Apache Airflow 自定义 Operator 附加链接(Extra Links):为任务 UI 增加外部系统入口 Apache Airflow 的 O
后端任务调度工作流自动化数据编排批处理数据工程流程编排Astro Storefront图像优化技巧:利用astro:assets提升网站性能
Astro Storefront图像优化技巧:利用astro:assets提升网站性能 在现代电商网站开发中,图像优化是提升网站性能的关键因素之一。Astro
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考