# Argo Workflow 中的 RBAC

众所周知，Argo Workflow 的整个工作机制，都是深度依赖于 Kubernetes 的。要让 Argo Workflow 顺畅运行，完成任务，RBAC 是不可缺少的一环。接下来的内容大概算是个笔记，记录了最初接触 Argo Workflow 时，可能会面对的一些 RBAC 相关问题以及其解决方法。

## 第一关：Console

这里我们选择官方 Release 页面中的标准部署方式，部署最新的 v3.5.11 版本。

```bash
$ kubectl create namespace argo
namespace/argo created
$ kubectl ns argo
Context "orbstack" modified.
Active namespace is "argo".
$ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.5.11/install.yaml

customresourcedefinition.apiextensions.k8s.io/clusterworkflowtemplates.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/cronworkflows.argoproj.io created
customresourcedefinition.apiextensions.k8s.io/workflowartifactgctasks.argoproj.io created
...
```

等所有 Pod 启动成功之后，就可以用端口转发方式访问 Console 了：

```bash
$ kubectl port-forward argo-server-67f8d8f6d4-s48jx 8888:2746
Forwarding from 127.0.0.1:8888 -> 2746
Forwarding from [::1]:8888 -> 2746
```

浏览器打开 `http://localhost:8888` 就可以看到 Argo Workflow 的 Console 了。首先欢迎我们的是登录页面。这上面一个明晃晃的输入框，要求输入 Token，官方文档明确给出了[解决方法](https://argo-workflows.readthedocs.io/en/latest/access-token/)：

```bash
$ kubectl create role jenkins --verb=list,update --resource=workflows.argoproj.io
...
$ kubectl create sa jenkins
...
```

然后接下来创建对应的 `Rolebinding`，为 SA 授权，最后创建 Secret，用于承载 SA 的 Token。

> 这里要吐槽，Argo 你这浓眉大眼的家伙，跟 Jenkins 是啥关系？

步骤还是有点烦，这里总结成一个 RBAC 文件：

```yaml
piVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
    name: argo-operator
rules:
- apiGroups:
  - argoproj.io
  resources:
  - workflows
  verbs:
  - list
  - update
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: argo-operator
  namespace: argo
---
apiVersion: v1
kind: Secret
type: kuhbernetes.io/service-account-token
metadata:
  name: argo-operator.service-account-token
  annotations:
    kubernetes.io/service-account.name: argo-operator
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: argo-operator-binding
  namespace: argo
subjects:
- kind: ServiceAccount
  name: argo-operator
  namespace: argo
roleRef:
  kind: ClusterRole
  name: argo-operator
  apiGroup: rbac.authorization.k8s.io
```

完成创建和授权之后，获取 Token：

```bash
$ ARGO_TOKEN="Bearer $(kubectl get secret argo-operator.service-account-token -o=jsonpath='{.data.token}' | base64 --decode)"
$ echo $ARGO_TOKEN
Bearer eyJhbGciOiJSUzI1NiIsI...
```

将上述 Token 输入到浏览器中登录，就进入了 Argo Workflow 的控制台了。然后你会发现更多的无权访问。逐个调整之后，上面的 ClusterRole 授权对象需要增加如下内容：

* workflowtemplates
    
* clusterworkflowtemplates
    
* cronworkflows
    
* eventsources
    
* sensors
    
* workfloweventbindings
    
* workflowtaskresults
    

> 如果要在 Console 上进行提交，那么 verbs 也需要进行扩充，例如 `*`。

## 第二关：Hello world

控制台的 `Workflows` 菜单中，有一个 `Submit New Workflow` 按钮，点击之后出现的页面里，在链接 `Edit using full workflow options` 中提供了一个工作流的示例，直接提交运行，大概会出现这样的错误信息：`Error (exit code 1): pods "fantastic-rhino" is forbidden: User "system:serviceaccount:argo:default" cannot patch resource "pods" in API group "" in the namespace "argo"`，看来又缺权限了，再来一套 RBAC：

```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
    name: argo-executor
rules:
- apiGroups:
  - ""
  resources:
  - pods
  verbs:
  - 'patch'
  - 'watch'
  - 'list'
  - 'get'
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: argo-executor
  namespace: argo
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: argo-executor.service-account-token
  annotations:
    kubernetes.io/service-account.name: argo-executor
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: argo-executor-binding
  namespace: argo
subjects:
- kind: ServiceAccount
  name: argo-executor
  namespace: argo
roleRef:
  kind: ClusterRole
  name: argo-executor
  apiGroup: rbac.authorization.k8s.io
```

提交之后，
