TT Lab
开始
学习 学习路径 课程

GitOps 与 Argo CD

点了同步却毫无反应——用文件判定策略

在 TT Lab 中继续学习

目标

亲手编写 argocd-rbac-cm 的 policy.csv,并用 argocd admin settings rbac 在没有服务器的情况下检查语法和判定。完成后,就可以把“这个人应该能做这件事”的表与策略一起放进仓库,并作为回归检查来运行。

为什么重要

Argo CD 的权限与 Kubernetes RBAC 是另一张表。在集群里没有任何权限的人,只要有 Argo CD 账号,就能以 Argo CD 所拥有的权限同步任何东西——所以真正的边界是由 policy.csv 划定的。然而这个文件在部署之后由人点击试过之前,很难知道写得对不对。argocd admin settings rbac 能仅凭本地文件完成这一判定。把策略当作代码处理,并在每次修改时运行期望表,也因此成为可能。权限一旦放宽,就没有人会去收紧——如果没有留下表作为收紧的依据,就更是如此。

步骤

  1. 创建 /root/ga-rbac/policy.csv。其中有两行 p,让 role:dev 能对 dev 项目的应用执行 get 和 sync;还有一行 g,把 alice 绑定到该角色。argocd admin settings rbac validate --policy-file /root/ga-rbac/policy.csv 必须通过。
  2. 在 /root/ga-rbac/can-basic.txt 中写四行。每行有 <주체> <동작> <객체> <답>(占位符依次为主体、操作、对象、答案)四个字段,以空格分隔。要询问的四项是 alice get dev/web、alice sync dev/web、alice sync prod/web、bob sync dev/web,答案直接写 argocd admin settings rbac can <주체> <동작> applications <객체> --policy-file(占位符依次为主体、操作、对象)输出的 Yes 或 No。
  3. 在 /root/ga-rbac/broken.csv 中写一份故意出错的策略——去掉 p 行最后的 allow/deny 字段即可。把 argocd admin settings rbac validate --policy-file /root/ga-rbac/broken.csv 的输出连同标准错误一起保存到 /root/ga-rbac/broken.txt。该文件中必须包含说明策略无效的句子。
  4. 创建 /root/ga-rbac/deny.csv。role:oncall 可以对 prod/* 执行 sync,唯独 prod/payments 是 deny。把 deny 行写在 allow 行之前,并把 carol 绑定到该角色。然后在 /root/ga-rbac/deny.txt 中写两行——prod/web <답> 和 prod/payments <답>(占位符为答案)。
  5. 把 /root/ga-rbac/argocd-rbac-cm.yaml 写成 ConfigMap 的样子。名称是 argocd-rbac-cm,命名空间是 argocd,data.policy.default 是 role:readonly,data.policy.csv 原样包含第 1 步的三行。这个文件同样可以直接传给 --policy-file——用不属于任何角色的 zoe 分别询问 get 和 sync,确认两者的差别。
  6. 用 rbac can 询问一个不存在的资源名称(workloads)和一个不存在的操作(deploy),把两次输出连同标准错误一起追加到 /root/ga-rbac/strict.txt。接着对同样的问题加上 --strict=false,把结果保存到 /root/ga-rbac/loose.txt。策略文件使用第 1 步的 policy.csv。
  7. 在 kwok 集群的 argocd 命名空间中创建 AppProject ga-team-a(先保存为 /root/ga-rbac/appproject.yaml,再应用)。在 spec.roles 中放入名称为 deployer 的角色,并写入一行策略 p, proj:ga-team-a:deployer, applications, sync, ga-team-a/*, allow 和组 ga-team-a-oncall。把同样的策略行和 g, dana, proj:ga-team-a:deployer 也写到 /root/ga-rbac/project-role.csv 中,并用 rbac can 确认判定相同。
  8. 在 /root/ga-rbac/matrix.tsv 中写至少六行,以制表符分隔——格式为 <주체>\t<동작>\t<자원>\t<객체>\t<기대>(占位符依次为主体、操作、资源、对象、期望值),期望值是 Yes 或 No。Yes 和 No 都必须至少出现一行。/root/ga-rbac/check-rbac.sh 逐行读取这张表,针对 /root/ga-rbac/argocd-rbac-cm.yaml 运行 rbac can,匹配则输出 OK …,不匹配则输出 MISMATCH …,只写到标准输出,只要有一行不匹配就必须以非 0 退出码结束。把它的输出保存到 /root/ga-rbac/matrix-result.txt。

参考

写一份策略并检查语法

创建 /root/ga-rbac/policy.csv。其中有两行 p,让 role:dev 能对 dev 项目的应用执行 get 和 sync;还有一行 g,把 alice 绑定到该角色。argocd admin settings rbac validate --policy-file /root/ga-rbac/policy.csv 必须通过。

p 行有 p, <주체>, <자원>, <동작>, <객체>, allow|deny(占位符依次为主体、资源、操作、对象)六个字段。资源是 applications,对象采用 <프로젝트>/<앱이름>(占位符依次为项目、应用名称)的写法,所以整个 dev 项目写作 dev/*。g 行有 g, <사용자>, <역할>(占位符依次为用户、角色)三个字段。

直接向策略提问

在 /root/ga-rbac/can-basic.txt 中写四行。每行有 <주체> <동작> <객체> <답>(占位符依次为主体、操作、对象、答案)四个字段,以空格分隔。要询问的四项是 alice get dev/web、alice sync dev/web、alice sync prod/web、bob sync dev/web,答案直接写 argocd admin settings rbac can <주체> <동작> applications <객체> --policy-file(占位符依次为主体、操作、对象)输出的 Yes 或 No。

命令的最后一行就是 Yes 或 No。退出码也会一并告知——Yes 为 0,No 为 1。想一想:bob 没有被绑定到任何角色。

字段不足的行会怎样暴露出来

在 /root/ga-rbac/broken.csv 中写一份故意出错的策略——去掉 p 行最后的 allow/deny 字段即可。把 argocd admin settings rbac validate --policy-file /root/ga-rbac/broken.csv 的输出连同标准错误一起保存到 /root/ga-rbac/broken.txt。该文件中必须包含说明策略无效的句子。

要同时保存输出和错误,使用 > 파일 2>&1(占位符为文件名)。策略有误时,这条命令会给出非 0 的退出码,因此在参考答案脚本里也要小心,别让它因失败而中断。

deny 与行的顺序无关,总是获胜

创建 /root/ga-rbac/deny.csv。role:oncall 可以对 prod/* 执行 sync,唯独 prod/payments 是 deny。把 deny 行写在 allow 行之前,并把 carol 绑定到该角色。然后在 /root/ga-rbac/deny.txt 中写两行——prod/web <답> 和 prod/payments <답>(占位符为答案)。

casbin 并不是采用首条匹配规则的方式,而是只要有一条 deny 命中就拒绝。所以调换顺序后结果也一样——请亲自确认。

对不属于任何角色的人,给他什么权限

把 /root/ga-rbac/argocd-rbac-cm.yaml 写成 ConfigMap 的样子。名称是 argocd-rbac-cm,命名空间是 argocd,data.policy.default 是 role:readonly,data.policy.csv 原样包含第 1 步的三行。这个文件同样可以直接传给 --policy-file——用不属于任何角色的 zoe 分别询问 get 和 sync,确认两者的差别。

policy.default 是用于没有命中策略的请求的角色。role:readonly 是 Argo CD 默认自带的内置角色,所以即使不写进 policy.csv 也存在。ConfigMap 的多行值用 | 块来写。

不存在的资源名称和操作,在提问阶段就会被拦下

用 rbac can 询问一个不存在的资源名称(workloads)和一个不存在的操作(deploy),把两次输出连同标准错误一起追加到 /root/ga-rbac/strict.txt。接着对同样的问题加上 --strict=false,把结果保存到 /root/ga-rbac/loose.txt。策略文件使用第 1 步的 policy.csv。

rbac can 默认是 strict——它会把资源和操作名称与 Argo CD 已知的列表比对,遇到不认识的名称就立即停下。这比把写错的策略部署出去之后才发现要好。加上 --strict=false 会跳过比对,直接判定。

创建只在项目内部生效的角色

在 kwok 集群的 argocd 命名空间中创建 AppProject ga-team-a(先保存为 /root/ga-rbac/appproject.yaml,再应用)。在 spec.roles 中放入名称为 deployer 的角色,并写入一行策略 p, proj:ga-team-a:deployer, applications, sync, ga-team-a/*, allow 和组 ga-team-a-oncall。把同样的策略行和 g, dana, proj:ga-team-a:deployer 也写到 /root/ga-rbac/project-role.csv 中,并用 rbac can 确认判定相同。

项目角色的主体名称格式是 proj:<프로젝트>:<역할>(占位符依次为项目、角色)。语法与全局 policy.csv 相同,所以可以用同一个工具检查——不同的是,这一行存在于 AppProject 内部,因此该项目的管理员可以直接修改。

先做好表,每次策略变化时都运行

在 /root/ga-rbac/matrix.tsv 中写至少六行,以制表符分隔——格式为 <주체>\t<동작>\t<자원>\t<객체>\t<기대>(占位符依次为主体、操作、资源、对象、期望值),期望值是 Yes 或 No。Yes 和 No 都必须至少出现一行。/root/ga-rbac/check-rbac.sh 逐行读取这张表,针对 /root/ga-rbac/argocd-rbac-cm.yaml 运行 rbac can,匹配则输出 OK …,不匹配则输出 MISMATCH …,只写到标准输出,只要有一行不匹配就必须以非 0 退出码结束。把它的输出保存到 /root/ga-rbac/matrix-result.txt。

表中的期望值以第 5 步的 ConfigMap 为准——alice 可以同步 dev,不属于任何角色的人借助 policy.default 只能读取。如果脚本自己去写文件,评分器再次运行时就会覆盖学员的产出文件。只输出到标准输出,重定向由人来做。