GitLab K8s Executor部署应用报RBAC权限Forbidden错误排查
GitLab Kubernetes Executor部署作业RBAC Forbidden问题根因与修复
根因说明
问题核心很明确:RBAC权限绑定的服务账号,和CI作业Pod实际使用的服务账号不匹配,你配置的权限规则本身没有遗漏:
- 最初设置
clusterWideAccess: true时,GitLab Runner Helm Chart的默认逻辑是只创建集群范围的ClusterRole、ClusterRoleBinding,不会生成命名空间级Role,这也是你第一次查gitlab命名空间下没有Role资源的原因。但此时生成的ClusterRoleBinding,只会把权限绑定给Chart自动创建的gitlab-runner专属服务账号,和跑作业的Pod没有关系。 - 后续把
clusterWideAccess改成false后,Chart确实会在gitlab命名空间下生成带所需权限的gitlab-runnerRole,也会创建对应的RoleBinding,但这个RoleBinding同样只把权限绑定给gitlab-runner服务账号。 - 你用的Kubernetes Executor启动CI作业Pod时,默认用的是gitlab命名空间下的
default服务账号,这个账号默认没有任何Kubernetes资源操作权限,所以执行kubectl apply时直接报Forbidden,提示system:serviceaccount:gitlab:default没有deployments、services的操作权限。
你之前手动创建RoleBinding,把gitlab-runner Role的权限绑给default账号后问题临时解决,刚好印证了这个根因。
规范修复方案
不建议长期用手动创建RoleBinding的临时方案,后续Helm升级、配置变更很容易出现配置漂移,推荐两种标准修复方式:
- 方案一(推荐):修改Runner的values.yaml,指定Kubernetes Executor启动的作业Pod直接使用
gitlab-runner服务账号,配置片段如下:
runners: kubernetes: service_account: "gitlab-runner"
改完执行helm upgrade更新Runner发布即可,不需要额外调整RBAC规则,Chart自动生成的权限绑定已经覆盖gitlab-runner账号的所有需求。
- 方案二:如果业务要求作业Pod必须用
default服务账号,就在values.yaml里自定义RBAC配置,额外增加一条绑定到default账号的RoleBinding,不要手动用kubectl创建资源,保证所有配置通过Helm统一管理。
补充提醒:你的CI脚本里是把
$kube_config变量base64解码后作为kubectl的配置文件,如果这个变量存的是Pod内置服务账号的访问凭证,就会直接走Pod挂载的服务账号权限校验,和上述逻辑完全匹配;如果存的是独立的管理员凭证,不会出现这类SA权限问题,但凭证泄露风险很高,生产环境不推荐这么用。
内容的提问来源于stack exchange,提问作者sqr
相关产品推荐
相关产品推荐

