KubernetesネイティブのArgo Workflowsを試してみた

最近業務でEKSに構成されたArgo Workflowsを使ったので実態を理解するために軽くローカル上で動かしてみました。
Kubernetesも初心者なので少しでも理解に繋がればと思ったのがきっかけです。

## Argo Workflowsとは
Argo Workflowsは、Kubernetes上で並列ジョブをオーケストレーションするためのワークフローエンジンです。Argo WorkflowsはKubernetesのCRDとして実装されていてKubernetes上で動きます。バッチ実行などに向いているそう。

## 1.Kubernetes環境構築
ローカルにKubernetes環境を構築します。
気軽に試したいので`kind`を使用してKuberneteクラスタを作成
https://kubernetes.io/ja/docs/tasks/tools/#kind
```
$ kind create cluster

$ kubectl cluster-info --context kind-kind
Kubernetes control plane is running at https://127.0.0.1:49927
CoreDNS is running at https://127.0.0.1:49927/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
```
クラスタが構築されたか確認します。
```
$ kubectl get nodes -o wide
NAME                 STATUS   ROLES           AGE   VERSION   INTERNAL-IP   EXTERNAL-IP   OS-IMAGE                         KERNEL-VERSION        CONTAINER-RUNTIME
kind-control-plane   Ready    control-plane   32m   v1.32.0   172.18.0.2    <none>        Debian GNU/Linux 12 (bookworm)   5.15.49-linuxkit-pr   containerd://1.7.24
```
出来てますね。
```
$ docker ps
CONTAINER ID   IMAGE                  COMMAND                   CREATED          STATUS          PORTS                       NAMES
e42e9341dafc   kindest/node:v1.32.0   "/usr/local/bin/entr…"   35 minutes ago   Up 35 minutes   127.0.0.1:49927->6443/tcp   kind-control-plane
```
Kubernetesのノードが、dockerのコンテナで動いてます。
kindはDockerコンテナを「ノード」として使用して、ローカル Kubernetesクラスタを実行するみたい。

## 2.Argo Workflowsのインストール
Argo Workflows CLIもインストールしておきます。

https://github.com/argoproj/argo-workflows/releases/

次にKubernetesクラスタにArgo Workflowsをインストールし、マニフェストを適用します。
```
$ kubectl create ns argo
namespace/argo created

$ kubectl apply -n argo -f https://github.com/argoproj/argo-workflows/releases/download/v3.6.2/install.yaml
customresourcedefinition.apiextensions.k8s.io/clusterworkflowtemplates.argoproj.io created
.
.
.
```

## 3.argoジョブの実行
これでArgo Workflowsが動く準備は整ったはずなので、早速ジョブを実行してみます。
```
$ argo submit -n argo --watch https://raw.githubusercontent.com/argoproj/argo-workflows/main/examples/hello-world.yaml
```
結果表示
```
Name:                hello-world-vsmc4
Namespace:           argo
ServiceAccount:      unset (will run with the default ServiceAccount)
Status:              Error
Message:             Error (exit code 64): workflowtaskresults.argoproj.io is forbidden: User "system:serviceaccount:argo:default" cannot create resource "workflowtaskresults" in API group "argoproj.io" in the namespace "argo"
Conditions:          
 PodRunning          False
 Completed           True
Created:             Tue Dec 24 19:12:03 +0900 (10 seconds ago)
Started:             Tue Dec 24 19:12:03 +0900 (10 seconds ago)
Finished:            Tue Dec 24 19:12:13 +0900 (now)
Duration:            10 seconds
Progress:            0/1
ResourcesDuration:   0s*(1 cpu),4s*(100Mi memory)

STEP                  TEMPLATE     PODNAME            DURATION  MESSAGE
 ⚠ hello-world-vsmc4  hello-world  hello-world-vsmc4  4s        Error (exit code 64): workflowtaskresults.argoproj.io is forbidden: User "system:serviceaccount:argo:default" cannot create resource "workflowtaskresults" in API group "argoproj.io" in the namespace "argo"  

```

失敗しました。
Argo Workflowsには`Argo UI`というものがあり、ブラウザからも実行が可能です。
一旦Argo UIにアクセスしてそちらから実行してみます。
```
$ kubectl -n argo port-forward service/argo-server 2746:2746
```
https://localhost:2746 にアクセス

![スクリーンショット 2024-12-24 21.35.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947964/7f573720-64db-e11b-b4b6-926a8ab15d64.png)
Argo UIにもアクセスできません。どうやら認証が足りていないようです。
今回は動かすだけなので、認証を不要に設定します。

```
$ kubectl edit deployment argo-server -n argo
```
上記を実行するとvimが開くので`spec.containners.agrgs.sever`の下に以下を追加

```--auth-mode=server #(認証無し)```

再度アクセスしてみます。
![スクリーンショット 2024-12-24 19.08.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947964/200e57e5-7d1e-983f-19ce-04f5ec111f1c.png)
アクセスできました！

### Argo UIからジョブ実行
先ほどCLIから失敗したジョブをArgo UIからも実行してみます。(submitで実行できます)
![スクリーンショット 2024-12-24 21.33.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947964/9f9d89aa-cacd-04e8-ca08-df6d4ce51944.png)
やはり失敗します。

![スクリーンショット 2024-12-24 22.47.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947964/257f1ebf-bd8b-7d65-b896-da2fde97200f.png)
Argo Workflowsはエラー原因もしっかり表示してくれるので安心。
submit時にServiceAccountの指定を省略した場合にはKubernetesが提供している`default`のServiceAccountが使用されるらしく、`default`には十分な権限が無いのが原因のようですね。

https://argo-workflows.readthedocs.io/en/latest/service-accounts/


権限設定の方法はいくつかあるみたいですが、今回は以下で`default`に管理者権限を付与する方向で進めさせていただきました。
```
$ kubectl create rolebinding default-admin --clusterrole=admin --serviceaccount=argo:default -n argo 
```

## 4.結果

無事成功し、CLI・UIどちらからもジョブ実行できること確認できました！

![スクリーンショット 2024-12-24 21.33.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3947964/08d3065f-fbd9-04f0-3c26-031cd912fc02.png)

```
Name:                hello-world-7g66f
Namespace:           argo
ServiceAccount:      unset (will run with the default ServiceAccount)
Status:              Succeeded
Conditions:          
 PodRunning          False
 Completed           True
Created:             Tue Dec 24 21:27:53 +0900 (11 seconds ago)
Started:             Tue Dec 24 21:27:54 +0900 (10 seconds ago)
Finished:            Tue Dec 24 21:28:04 +0900 (now)
Duration:            10 seconds
Progress:            1/1
ResourcesDuration:   0s*(1 cpu),4s*(100Mi memory)

STEP                  TEMPLATE     PODNAME            DURATION  MESSAGE
 ✔ hello-world-7g66f  hello-world  hello-world-7g66f  4s 
```

## まとめ
<ul>
<li>すごい軽いお試し実行だけどやはり動くと嬉しい</li>
<li>
権限周りで結構ハマった。RBAC機能からRoleBindingして新たなServiceAccountの作成もできるみたい
</li>
<li>Argo CDというCDツールを使って自動でマニフェスト生成しクラスタに同期することもできるようで、EKSも含めまた使ってみたい</li>
</UL>