一、我踩过的RBAC大坑:ArgoCD权限乱套的那些日子

我之前在一家做SaaS服务的公司带DevOps小团队,那时候我们用ArgoCD做K8s的应用部署管理,一开始图省事,给所有开发同学都开了ArgoCD的管理员权限,结果没俩礼拜就出了大问题:一个实习生误删了线上的核心项目配置,导致整个业务中断了40分钟,还差点吃了客户的投诉。后来我们痛定思痛,开始研究ArgoCD的RBAC权限模型,踩了无数坑之后才摸出了精细化分配Project访问控制的门道,今天就把这些经验实实在在地讲给大家听。

1.1 先搞懂ArgoCD的RBAC到底管啥

很多人刚接触ArgoCD的时候,会把它的RBAC和K8s本身的RBAC搞混,其实完全是两回事。K8s的RBAC管的是集群里的Pod、Deployment这些资源的操作权限,而ArgoCD的RBAC管的是你能不能登录ArgoCD控制台、能不能看某个项目、能不能部署应用这些操作。简单说,ArgoCD的RBAC是给人用的权限,K8s的是给集群用的权限,两者是互补的,不是替代的。

ArgoCD的RBAC核心是三个东西:角色(Role)、角色绑定(RoleBinding)、权限规则(Policy)。其中权限规则是最核心的,它的格式是固定的:p, 主体, 资源类型, 操作, 资源路径, 允许/拒绝。比如p, alice, applications, get, *, allow就是说允许用户alice查看所有应用。

二、ArgoCD Project权限的核心逻辑:隔离才是硬道理

ArgoCD里的Project不是随便建的文件夹,它是专门用来做资源隔离的逻辑单元。一个Project可以绑定特定的K8s集群、特定的命名空间、特定的应用类型,甚至能限制部署的资源大小。如果把ArgoCD比作一个公司的办公大楼,那Project就是各个部门的独立办公室,不同部门的人只能进自己的办公室,不能随便串岗。

2.1 Project权限和全局权限的区别

全局权限是针对整个ArgoCD实例的,比如管理员权限就是全局的,能操作所有Project里的所有资源。而Project权限是针对单个Project的,只能操作这个Project里的资源。很多人踩的第一个坑就是把全局权限和Project权限搞混,给用户开了全局权限却忘了限制在特定Project里,导致权限过大。

举个例子,我们之前给前端团队开权限的时候,不小心写了全局的权限规则,结果前端团队的同学能看到后端团队的核心项目,虽然不能操作,但也存在信息泄露的风险。后来我们改成了只给前端团队开前端Project的权限,才解决了这个问题。

三、精细化分配权限的实操步骤:从0到1配置

接下来我就给大家讲具体的配置步骤,所有示例都用ArgoCD原生的配置方式,技术栈统一为ArgoCD v2.8(目前最稳定的版本)。

3.1 第一步:创建独立的Project

首先,我们要给不同的团队创建对应的Project,比如前端团队叫frontend-team,后端团队叫backend-team,测试团队叫test-team。创建Project的方式有两种,一种是通过ArgoCD控制台,一种是通过YAML配置文件,这里我推荐用YAML,方便版本管理。

下面是创建Project的YAML示例,技术栈:ArgoCD v2.8:

apiVersion: argoproj.io/v1alpha1
kind: AppProject
metadata:
  name: frontend-team # Project名称,对应前端团队
  namespace: argocd # Project必须在argocd命名空间下
spec:
  # 允许部署的K8s集群,这里只允许部署到我们的测试集群和生产集群
  destinations:
    - namespace: frontend-test # 前端测试命名空间
      server: https://test-cluster.example.com # 测试集群地址
    - namespace: frontend-prod # 前端生产命名空间
      server: https://prod-cluster.example.com # 生产集群地址
  # 允许使用的Git仓库,这里只允许前端团队用自己的前端仓库
  sourceRepos:
    - https://git.example.com/frontend-team/*
  # 禁止部署的资源类型,比如禁止部署特权Pod,提高安全性
  clusterResourceWhitelist:
    - group: '*'
      kind: '*'
  namespaceResourceBlacklist:
    - group: '*'
      kind: Pod
      verbs: ["create", "delete"]

这个配置的作用是,前端团队的所有应用只能部署到指定的两个命名空间,只能用自己的Git仓库,而且不能直接创建或删除Pod,只能通过ArgoCD的应用来管理,大大降低了误操作的风险。

3.2 第二步:创建自定义角色(Role)

创建完Project之后,我们需要给不同的用户创建对应的角色,比如前端团队的开发同学、测试同学、管理员同学,权限都不一样。ArgoCD默认有几个内置角色,比如role:adminrole:user,但这些角色都是全局的,我们需要创建自定义的Project级别的角色。

创建自定义角色的方式是修改ArgoCD的ConfigMap,ConfigMap的名字是argocd-rbac-cm,在argocd命名空间下。下面是配置自定义角色的示例,技术栈:ArgoCD v2.8:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  # 自定义角色:frontend-developer,给前端开发同学用
  policy.csv: |
    # 规则格式:p, 角色名, 资源类型, 操作, 资源路径, 允许/拒绝
    # 允许前端开发查看自己Project里的所有应用
    p, role:frontend-developer, applications, get, frontend-team/*, allow
    # 允许前端开发同步(部署)自己Project里的应用
    p, role:frontend-developer, applications, sync, frontend-team/*, allow
    # 允许前端开发查看自己Project里的部署历史
    p, role:frontend-developer, applications, history, frontend-team/*, allow
    # 禁止前端开发删除自己Project里的应用
    p, role:frontend-developer, applications, delete, frontend-team/*, deny
    # 禁止前端开发修改自己Project的配置
    p, role:frontend-developer, projects, update, frontend-team, deny
  # 内置角色的配置,这里我们关闭默认的全局用户角色,提高安全性
  policy.default: role:readonly

这个配置的作用是,前端开发同学只能查看、部署自己Project里的应用,不能删除应用,也不能修改Project的配置,权限非常精细化。

3.3 第三步:把用户绑定到角色(RoleBinding)

创建完角色之后,我们需要把具体的用户绑定到对应的角色上,这样用户才能拥有对应的权限。绑定的方式也有两种,一种是通过控制台,一种是通过YAML,这里还是推荐用YAML,方便管理。

绑定用户的YAML示例,技术栈:ArgoCD v2.8:

apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-rbac-cm
  namespace: argocd
data:
  # 角色绑定规则,格式:g, 用户名/组名, 角色名
  # 把前端开发同学alice绑定到frontend-developer角色
  g, alice, role:frontend-developer
  # 把前端开发同学bob绑定到frontend-developer角色
  g, bob, role:frontend-developer
  # 把前端测试组的所有同学绑定到frontend-tester角色
  g, frontend-test-group, role:frontend-tester

这里需要注意的是,ArgoCD支持和各种身份认证系统集成,比如LDAP、GitHub、GitLab等,所以这里的用户名可以是LDAP的用户名,也可以是GitHub的用户名,组名也可以是LDAP的组名,这样就可以批量绑定用户,不用一个一个绑定。

3.4 第四步:验证权限配置是否生效

配置完之后,一定要验证权限是否生效,不然配置错了自己都不知道。验证的方式很简单,用不同的用户登录ArgoCD控制台,看能不能看到对应的Project,能不能进行对应的操作。

比如我们用alice登录控制台,应该只能看到frontend-team这个Project,看不到backend-teamtest-team,而且只能查看和同步应用,不能删除应用。如果能看到其他Project,或者能删除应用,那就是配置错了,需要检查Policy的规则。

另外,我们还可以用ArgoCD的命令行工具argocd来验证权限,命令如下,技术栈:ArgoCD v2.8:

# 用alice的账号登录ArgoCD
argocd login argocd.example.com --username alice --password alice123
# 查看alice的权限
argocd account get-user-info
# 尝试查看backend-team的应用,应该会报错
argocd app list --project backend-team

如果最后一个命令报错,说明权限配置是对的,alice不能查看backend-team的应用。

四、常见的坑和避坑指南

在配置的过程中,我踩了很多坑,这里把最常见的几个坑总结一下,给大家避坑。

4.1 坑一:权限规则的顺序问题

ArgoCD的权限规则是按顺序匹配的,先匹配到哪个规则就用哪个规则,所以如果有多个规则的话,一定要把严格的规则放在前面,宽松的规则放在后面。比如你先写了允许所有的规则,再写禁止某个用户的规则,那禁止的规则就不会生效,因为先匹配到了允许的规则。

举个例子,如果你写了下面的规则:

p, role:frontend-developer, applications, *, *, allow
p, role:frontend-developer, applications, delete, frontend-team/*, deny

那前端开发同学就能删除自己Project里的应用,因为第一个规则是允许所有操作,先匹配到了,第二个规则就没用了。正确的顺序应该是把禁止的规则放在前面:

p, role:frontend-developer, applications, delete, frontend-team/*, deny
p, role:frontend-developer, applications, *, *, allow

4.2 坑二:Project的资源路径格式问题

在写权限规则的时候,资源路径的格式一定要对,Project的资源路径是Project名称/*,比如frontend-team/*,不能写成frontend-team,也不能写成*/*,不然规则就匹配不到。

比如你写了p, role:frontend-developer, applications, get, frontend-team, allow,那这个规则就不会生效,因为资源路径的格式不对,正确的应该是frontend-team/*

4.3 坑三:内置角色的默认权限问题

ArgoCD默认有一个内置的角色role:user,这个角色的权限是全局的,能查看所有Project里的所有应用,如果你在ConfigMap里把policy.default设置成了role:user,那所有没有绑定角色的用户都会拥有这个权限,非常危险。

所以我们一定要把policy.default设置成role:readonly,这个角色只能查看ArgoCD的基本信息,不能查看任何Project里的应用,这样就算有新用户注册,也不会拥有过大的权限。

4.4 坑四:身份认证和权限绑定的同步问题

如果ArgoCD是和LDAP、GitHub等身份认证系统集成的,那用户的组名和用户名一定要和身份认证系统里的一致,不然绑定就会失败。比如你在LDAP里的组名是frontend-team,但在ArgoCD的绑定规则里写的是frontend-group,那绑定就不会生效。

另外,身份认证系统里的用户组如果有变动,比如新增了一个用户,一定要及时更新ArgoCD里的绑定规则,不然新用户就没有权限,或者权限不对。

五、技术优缺点分析

ArgoCD的RBAC权限模型有优点,也有缺点,我们要根据自己的实际情况来选择。

5.1 优点

首先,ArgoCD的RBAC模型非常灵活,支持自定义角色、自定义权限规则,能满足各种精细化的权限需求。其次,ArgoCD的RBAC模型和Project结合得非常好,能实现不同团队、不同项目的完全隔离,大大提高了安全性。第三,ArgoCD的RBAC模型支持和各种身份认证系统集成,能批量管理用户和组,提高了管理效率。

5.2 缺点

首先,ArgoCD的RBAC模型的配置比较复杂,需要理解权限规则的格式、Project的隔离逻辑、角色绑定的方式,新手很容易踩坑。其次,ArgoCD的RBAC模型的调试比较麻烦,配置错了很难快速定位问题,需要一步步验证。第三,ArgoCD的RBAC模型的权限规则是全局的,不能针对单个用户设置个性化的权限,只能通过角色来绑定,不够灵活。

六、应用场景总结

ArgoCD的RBAC权限模型适合各种规模的团队,尤其是有多个团队、多个项目的中大型团队。比如SaaS公司的多租户场景,每个租户对应一个Project,每个租户的用户只能访问自己的Project;比如互联网公司的多团队场景,每个团队对应一个Project,每个团队的用户只能访问自己的Project;比如金融公司的合规场景,需要严格限制不同用户的操作权限,ArgoCD的RBAC模型能满足合规要求。

七、文章总结

ArgoCD的RBAC权限模型是一个非常强大的工具,但要想用好它,需要理解它的核心逻辑,避免踩坑。我们在配置的时候,一定要先创建独立的Project,再创建自定义的角色,然后把用户绑定到对应的角色上,最后一定要验证权限是否生效。只要按照这个步骤来,就能实现不同团队的精细化Project访问控制,大大提高ArgoCD的安全性。