もうずっといなかぐらし

かたいなかのブログ

ArgoCD Image Updaterの新機能でイメージ更新用のPRの作成を自動化する

こんにちは、かたいなかです。

Kubernetes内のリソースを管理する際、Argo CDでのGitOpsは優れたGUIを備えていることなどから魅力的です。最近ではArgo CD Image Updaterというコンポーネントもあるため、Kubernetesでデプロイしたアプリケーションのイメージの更新まで自動で行えるようになっています。

今回はそんなArgo CD Image Updaterのv0.12.0から入った機能で、PRによるアプリケーションのイメージの更新が簡単に自動化できるようになっていたため、実際に動かして検証していきます。

目次

Argo CD, Argo CD Image Updaterとは

Argo CDは、GitOpsでKubernetes内の設定を管理するためのツールです。使いやすいGUIを備えていることも特徴の一つです。

Argo CD Image Updaterは、ArgoCDで管理されているアプリケーションのDockerイメージのリポジトリを監視し、新しいイメージを検出した際にイメージの更新を行うことができます。

この2つを組み合わせることでGitOpsでKubernetes内のリソースを管理しながらイメージの更新を自動化できます。

個人的に使いづらかった点

Argo CD Image Updaterによる変更はデフォルトではArgoCDのApplicationで指定しているリポジトリおよびブランチに書き込まれます。

Image Updaterによるコミット後のイメージの変更の同期は自動にできる(spec.syncPolicy.automated)のですが、その場合デプロイのタイミングの微妙な制御が行いづらくなります。今関わっている案件ではリリースのタイミングをスクラムイベント等に合わせて調整したいため、特に本番への自動デプロイは採用しづらいという問題がありました。

その場合、手動でSyncするという案が考えられるのですが、ArgoCDの権限上、手動Syncを行えるユーザは任意のバージョンへのロールバックも行えるため、本番環境を悪意を持って壊すこともできてしまう状態になってしまいます。そのため、業務委託の方が多い今の環境では採用しづらいです。

また、イメージの変更がリモートブランチへの直接コミットにより行われるため、ロールバックを行う際のRevert作業がGitHub上で完結しないという問題もありました。

新機能

そんな中、ArgoCD Image Updaterのv0.12.0で、ソースブランチに直接コミットさせるのではなく、新しいブランチにイメージの変更をコミットさせる機能が導入されました

この機能でArgoCD Image Updaterでイメージの変更のブランチの作成までを行い、GitHub Actionsでブランチ作成を契機にPRの作成を行うことで、イメージの更新のためのPRの作成が自動化できるようになります。

これにより、新しいイメージのデプロイをPRのマージでいつでも実行できるようにしつつ、ロールバック作業もPRをRevertするだけで行えるようになります。

実際にやってみた

実際にArgoCD Image UpdaterをGitHub Actionsと組み合わせてPRの作成を自動化していきます。

以下の図のようなフローを組んでいきます。

f:id:katainaka0503:20220224010407p:plain

検証した環境

  • Mac OS 12.2
  • Minikube 1.25.1
  • docker desktop 4.4.2
  • Argo CD 2.2.5
  • Argo CD Image Updater 0.12.0

Argo CDのインストール

まずは、こちらのドキュメントに従い、Argo CDおよびArgo CD Image Updaterをインストールします

https://argo-cd.readthedocs.io/en/stable/getting_started https://argocd-image-updater.readthedocs.io/en/latest/install/start/

また、GitHubに接続するためのクレデンシャルの設定もしておきます

argocd repo add https://github.com/${ORGANIZATION_NAME}/${REPOSITORY_NAME} --username ${USERNAME} --password ${PASSWORD} --port-forward --port-forward-namespace argocd

必要に応じてここでDockerリポジトリへの接続の設定をしておくと良いでしょう。今回はパブリックリポジトリのイメージを使用するのでここでは設定しません。

書き込みブランチを指定する機能を試す

ここまででArgoCD Image Updaterの準備ができたので以下のようなApplicationを作成して書き込みブランチを指定する機能を試していきます。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: test-service
  namespace: argocd
  annotation:
    argocd-image-updater.argoproj.io/image-list: some/image[:<version_constraint>]
    argocd-image-updater.argoproj.io/write-back-method: git
    argocd-image-updater.argoproj.io/git-branch: :image-updater{{range .Images}}-{{.Name}}-{{.NewTag}}{{end}}
spec:
  destination:
    namespace: test-service
    server: https://kubernetes.default.svc
  source:
    repoURL: https://github.com/katainaka0503/argocd-image-update-test.git
    targetRevision: main
    path: test-service
  syncPolicy:
    automated:
      prune: true

ポイントはargocd-image-updater.argoproj.io/git-branchアノテーションの値に :が含まれていることです。 値の:で区切られた左側は新しいブランチのチェックアウト元のブランチになります。そして、右側は新しいブランチの名前のテンプレートを指定します。

このApplicationを作成した状態で、新しいDockerイメージをpushすると、以下の画像のようにGitHub上にイメージ更新のコミットを含んだ新しいブランチが作成されます。

f:id:katainaka0503:20220224004502p:plain

GitHub Actionsと組み合わせてみる

ArgoCDによってイメージ更新用の新しいブランチの作成まで行えるようになったので、もう少し工夫してGitHub ActionsでPRの作成まで自動化します。

以下のようなファイルでGitHub Actionsのワークフローを作成します。

name: create-pr-for-image-updater

on:
  push:
    branches:
      - 'image-updater-**'

jobs:
  create-pr:
    runs-on: ubuntu-latest
    steps:
      - name: Create Pull Request
        uses: actions/github-script@v6
        with:
          script: |
            const { repo, owner } = context.repo;
            const result = await github.rest.pulls.create({
              title: '[Image Updater] イメージの更新',
              owner,
              repo,
              head: '${{ github.ref_name }}',
              base: 'main',
              body: 'Dockerイメージを更新します'
            });

この設定がmainブランチにある状態で再度ArgoCD Image Updaterにイメージ更新ブランチを作成させると、PRが自動で作成されます。

f:id:katainaka0503:20220224004630p:plain

実運用ではPR作成処理実行時に古いブランチを削除したりするとよいでしょう。

また、複数の環境用に複数のブランチを使うフローになっている場合はブランチ名等にPRの対象のブランチ名を含ませるようにすると柔軟に対応できそうです。

さらには自動マージ等も併用することでステージング環境へのデプロイはレビュー不要にすることもできます。

まとめ

ArgoCD Image Updaterの新機能を使うことでイメージの更新のPRの作成までを自動化することができました。イメージの更新がPRベースなため、スクラムイベント等のデプロイを行いたいタイミングに合わせてデプロイできます。また、GitHubのApprove関連の設定により誰がデプロイを行えるかを設定できるようになりました。さらには、ロールバックが必要になった際のRevertもGitHub上の操作で完結します。

今回の機能はかゆいところに手が届く機能で個人的にもとても嬉しい機能です。この機能がリリースされたらArgoCDを使っている環境では試してみる価値があるのではないでしょうか?

余談: Fluxでは

Argo CD + Argo CD Image Updaterの機能を提供する他のツールとしてFluxというツールがあります。FluxではPRの作成までGitHub Actionsに頼らず行うことができるようです。

https://fluxcd.io/docs/use-cases/gh-actions-auto-pr/

今回のリポジトリ

参考

編集履歴

  • ArgoCD Image Updater 0.12.0リリースに伴い、リリース前の機能を使うためのセットアップ手順を削除しました。