👻

Argo Workflowのアーカイブについて考察してみた

2024/12/11に公開

はじめに

D2Cでエンジニアをしている、閃(セン)と申します。

今年アドカレの2日目です。

私の所属するチームでは、Argo Workflowを展開していて、より活用するための改善を行なっている最中です。Argo Workflowのアーカイブ機能を実装する際に、アーカイブについて考察してみました。考察した内容と実装の流れについて説明していきたいと思います。

Argo Workflowとカスタムリソース

Argo Workflowについて簡単に説明していきたいです。Argo Workflowは、Kubernetes上で動作するオープンソースのワークフローエンジンです。コンテナ化されたタスクを順序立てて実行するためのプラットフォームを提供し、特にデータパイプライン、機械学習モデルのトレーニング、CI/CDプロセスなどに利用されます。

ArgoはKubernetesネイティブであり、YAMLファイルまたはコードベースで「Workflow」というKubernetesカスタムリソースを定義できます。CRD(CustomResourceDefinition)で定義されているため、外部ストレージサービスを利用しなくてもクラスタ内で独立して動作することができます。この仕組みにより、実行履歴や実行ログの管理が次のように行われます:

  • 実行履歴の保存

    実行履歴は Workflow スタムリソースとして Kubernetes クラスタの etcd に保存されます。これにより、ArgoWorkflow は追加の外部データベースに依存せずともワークフローの状態や履歴を管理できます。

  • 実行ログの保存

    実行中に発生するログデータは Pod 内部に保存され、kubectl logs コマンドを使用してアクセスできます。この方法はシンプルで、ArgoWorkflow の基本的な運用には十分です。

ただし、上記のようにすべてのデータが Kubernetes クラスタ内に保存される場合、以下のような課題が発生する可能性があります:

  • Pod が削除されると、その中に保存されている実行ログを参照できなくなります。そのため、Pod のライフサイクルに注意を払う必要があります。
  • クラスタ内で管理するデータ量が増大すると、etcd にかかるストレージ負荷が高まり、最終的に Kubernetes クラスタ全体のパフォーマンスや安定性に悪影響を及ぼす可能性があります。

これらの課題に対処するため、ArgoWorkflow はアーカイブ機能を提供しています。この機能を活用することで、履歴データを外部ストレージに移行し、etcd にかかるストレージ負担を軽減することが可能です。

Argo Workflowアーカイブ機能

Argo Workflowが提供しているアーカイブ機能についてまとめてみます。前述のように、実行データは実行履歴と実行ログがありまして、それぞれ保存されています。アーカイブ機能もそれぞれ提供されています。

  • Workflowの実行履歴

    実行履歴は Postgres や MySQL などの外部データベースに保存されます。これにより、etcd のストレージ消費を削減し、効率的なデータ管理が可能になります。

  • Pod の実行ログ

    Pod に関連するログデータは S3 ストレージに保存されます。ログはデータ量が多くなる傾向があるため、Postgres などのリレーショナルデータベースに直接保存する代わりに、S3 を利用することでスケーラブルなログ管理を実現します。

アーカイブ機能を利用するためには、以下の外部ストレージサービスが必要です:

  • Postgres(または MySQL):アーカイブされたワークフローの履歴を保存します。
  • MinIO(または S3 互換ストレージ):S3 ストレージを提供し、ワークフローで生成されるアーティファクトやアーカイブされた Pod ログを保存します。

実行履歴アーカイブを実装してみる

アーカイブ機能を利用するには、まず外部データベース をセットアップする必要があります。本来、データベースをマネージドサービスに任せるケースが多いと思われます、特に商用環境です。今回は逆にクラウドネイティブで検証してみたいと思います。以下は、Helm を使用して簡単に Postgres をデプロイする実装です。

valueは下記のようにシンプルに設定してます。

primary:
  persistence:
    enabled: true
    existingClaim:  argo-workflow-postgresql-pvc
  resources:
    requests:
      memory: 512Mi
      cpu: 250m
    limits:
      memory: 1Gi
      cpu: 500m
      
auth:
  postgresPassword: argopostgrespw #暗号化する必要があります、ここで省略
  username: argoadmin
  password: argopw
  database: argodb

永続化ボリュームは下記のように実装しております。まずはPVCを設定します。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: argo-workflow-postgresql-pv
  labels:
    efsname: argo-workflow-db
spec:
  capacity:
    storage: 1000Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: fs-xxxxxxxxx.efs.ap-northeast-1.amazonaws.com
    path: "/"

次にPVCが使用するPVを設定します、Storage Classを使用することも可能です。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: argo-workflow-postgresql-pv
  labels:
    efsname: argo-workflow-db
spec:
  capacity:
    storage: 1000Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: fs-xxxxxxxxx.efs.ap-northeast-1.amazonaws.com
    path: "/"

永続化のために、今回はAWS EFSを使用しましたが、他にもEBSなどが考えられます。

EFSでうまくファイル権限を設定するために、volumePermissionsをPostgresに追記します。まとめると下記となります。

primary:
  persistence:
    enabled: true
    existingClaim:  argo-workflow-postgresql-pvc
  resources:
    requests:
      memory: 512Mi
      cpu: 250m
    limits:
      memory: 1Gi
      cpu: 500m
      
auth:
  postgresPassword: argopostgrespw #暗号化する必要があります、ここで省略
  username: argoadmin
  password: argopw
  database: argodb
  
volumePermissions:
  enabled: true
  resources:
    requests:
      memory: 64Mi
      cpu: 50m
    limits:
      memory: 128Mi
      cpu: 100m
  image:
    registry: docker.io
    repository: bitnami/os-shell
    tag: latest

データベースの設定が完了した後に、Argo側のControllerに設定を追加します。

controller:
  persistence:
    archive: true
    postgresql:
      host: argo-workflow-postgresql.argo.svc.cluster.local
      port: 5432
      database: argodb
      tableName: argo_workflows
      userNameSecret:
        name: argo-workflow-postgresql-secret
        key: username
      passwordSecret:
        name: argo-workflow-postgresql-secret
        key: password

ここでSecretが必要となります、AWS Secrets Managerの利用も可能ですが、今回はKubernetes Secretを利用します。

apiVersion: v1
kind: Secret
metadata:
  name: argo-workflow-postgresql-secret
type: Opaque
stringData:
  username: argoadmin
  password: argopw

最後にHelmfileに整理します。

repositories:
  - name: argo
    url: https://argoproj.github.io/argo-helm
  - name: bitnami
    url: https://charts.bitnami.com/bitnami

releases:
  - name: argo
    namespace: argo
    chart: argo/argo-workflows
    needs:
      - argo-workflow-postgresql
    values:
      - nameOverride: argo
      - images:
          tag: v3.5.10
      - argo/values.yaml
  - name: argo-workflow-postgresql
    namespace: argo
    chart: bitnami/postgresql
    version: 16.2.3
    needs:
      - argo-workflow-postgresql-pv
      - argo-workflow-postgresql-secret
    values:
      - image:
          tag: 16.6.0-debian-12-r1
      - postgresql/values.yaml
  - name: argo-workflow-postgresql-secret
    namespace: argo
    chart: "./postgresql-secret" #Yaml保管ディレクトリ
  - name: argo-workflow-postgresql-pv
    namespace: argo
    chart: "./persistent-volume" #Yaml保管ディレクトリ

デプロイの後にargo serverとcontrollerを再起動する必要があります。Workflowが保存されたかどうかを確認してみましょう。

kubectl run postgresql-dev-client \
  --rm \
  --tty -i \
  --restart='Never' \
  --namespace argo \
  --image docker.io/bitnami/postgresql:16.6.0-debian-12-r1 \
  --env="PGPASSWORD=$POSTGRES_PASSWORD" \
  -- /bin/bash -c 'psql --host argo-workflow-postgresql -U argoadmin -d argodb -p 5432'

テーブルが作成されて、workflowが保存されたことが確認できました。

argodb=> \dt
                      List of relations
 Schema |              Name              | Type  |   Owner   
--------+--------------------------------+-------+-----------
 public | argo_archived_workflows        | table | argoadmin
 public | argo_archived_workflows_labels | table | argoadmin
 public | argo_workflows                 | table | argoadmin
 public | schema_history                 | table | argoadmin
(4 rows)

argodb=> select name,phase from argo_archived_workflows;
            name            |   phase   
----------------------------+-----------
 sample-cron-workflow-vw9hm | Succeeded
 sample-cron-workflow-tl5fh | Succeeded
(2 rows)

Argo UIで確認してみましょう、ARCHIVEDがTureになっていることが確認できました。

まとめ

今回はArgo Workflowのアーカイブ機能について考察してみました。アーカイブの必要性と実行履歴の実装を整理しました。大量のワークフローやログデータを管理する必要がある場合は、アーカイブ機能を活用することでシステム全体の安定性とスケーラビリティを確保することが推奨されます。

そして実行ログの実装が残っていますが、また次のタイミングにしましょう。

D2C m-tech

Discussion