今回はArgoCD Image Updaterを使ってみます。
ArgoCD Image Updaterとは
ArgoCD Image Updaterは、コンテナレジストリを定期的にチェックし、新しいイメージが配置されていれば、KubernetesのマニフェストファイルやArgoCD Applicationを自動的に更新する機能を提供します。名称の通りArgoCDと一緒に使うことが前提で、ArgoCD Image Updaterがマニフェストを書き換えると、ArgoCDがそれを検知し、自動的にリソースの更新を行うような構成が可能となります。
ArgoCDはソースコードリポジトリ上のマニフェストファイルとクラスター上のリソース定義との差分を検知して、リソースの更新を行います。そのため、アプリケーションを更新するには、何らかの方法でマニフェストファイルの修正を行い、Podの再作成を行わなければなりません。
これまではCIの処理の中でマニフェストファイルの修正を行ったり、手動でファイルを修正することが多かったですが、ArgoCD Image Updaterを導入することでこの処理をカスタマイズする手間が省けると見込めます。
なお、ArgoCD Image Updaterと同じような機能を提供するプロダクトとしては、 Fluxが有名かと思います。Fluxにはイメージタグを自動更新する機能が最初から組み込まれており、 ImageRepository
などのカスタムリソースを使うことで実現できます。
イメージ更新のプロセス
ArgoCD Image Updaterがどのようにイメージの更新を検知・更新するかは、ドキュメントに記載されています。
- Kubernetes APIかArgoCD APIを使い、現在ArgoCD Applicationがクラスター上に存在するかをスキャンします。どちらのAPIを利用するかは ArgoCD Image Updaterをインストールする方法によります。
- 見つかったApplicationの中に
argocd-image-updater.argoproj.io/image-list
というAnnotationが存在するかをチェックします。このAnnotationは、ArgoCD Image Updaterがチェックする対象のコンテナイメージレジストリを指定するもので、ArgoCD Image Updaterを使用する場合は必須の設定です。 - Annotationに設定されているイメージが、実際にApplicationによってデプロイされているかをチェックします。
- 指定したイメージが実際にデプロイされていれば、それをアップデート対象のイメージとして、対象のコンテナレジストリにアクセスします。そして、Applicationのファイルで指定する設定に従い、新しいバージョンのイメージがレジストリ中に存在するかをチェックします。
- 新しいバージョンのイメージがあれば、設定に従いイメージタグを更新します。更新方法は後述する2種類が存在します。
※参考リンク:
前提条件
前提として、ArgoCD Image Updaterは現在開発中のステータスにあるプロダクトです。そのため、将来破壊的な変更が入る可能性が高いとのことです。
また、利用するにあたり、現時点でいくつかの制限事項が存在します。
- 更新対象となるイメージは、ArgoCD Applicationが管理するリソースのみが対象となる
- 更新対象となるイメージは、Kustomize/Helmでマニフェストを管理するものだけが対象となる。Helmの場合はパラメータを使ってイメージタグを指定する必要がある。
- コンテナイメージリポジトリへのアクセスに使う秘匿情報は、ArgoCD Image Updaterと同じクラスター上に存在しなければならない
- ArgoCDから実行するロールバックには対応しておらず、ロールバック中のApplicationも更新しようとする (ArgoCDはそのようなApplicationの自動Syncを無効化する)。
※参考リンク:
- ArgoCD Image Updater - Overview
- ArgoCD Image Updater - Updating container images: Rollback and image updates
ArgoCD Image Updaterを使ってみる
ここから実際にArgoCD Image Updaterを使ってみます。
事前準備
ArgoCD Image Updaterをデプロイする前に、EKSクラスター上にArgoCDをデプロイし、そこからGitHubリポジトリと同期した状態を作ります。
今回は事前に以下のリソースを用意しました。アプリケーションを修正してGitHubにPushするとCIが起動し、ECRに新しいイメージがPushされるようにします。また、GitHubリポジトリをprivateにしているため、ArgoCDがリポジトリにアクセスするよう、Kubernetes Secret
リソースを用意しています。
- Kubernetesクラスター
Amazon EKS
:ver 1.21
ArgoCD
:ver 2.5.1
- コンテナレジストリ
Amazon ECR
- ソースコードリポジトリ
詳細は書かないですが、使用したファイルの一部は以下に載せます。
GitHubリポジトリ中のディレクトリ構成
. ├── .github │ └── workflows │ └── docker-build-push.yaml ├── README.md ├── app │ ├── Dockerfile │ └── main.go ├── application.yaml └── manifest ├── base │ ├── deployment.yaml │ └── kustomization.yaml └── overlays └── dev └── kustomization.yaml
.github/workflows/docker-build-push.yaml
name: Dockerfile build and push to ECR on: push: branches: - main paths: - 'app/*' - '.github/workflows/docker-build-push.yaml' workflow_dispatch: permissions: id-token: write contents: read env: IAM_ROLE_ARN: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-role ECR_REGION: ap-northeast-1 ECR_REGISTRY: ${{ secrets.AWS_ACCOUNT_ID }}.dkr.ecr.ap-northeast-1.amazonaws.com ECR_REPOSITORY: argocd-image-updater-test jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v1 with: aws-region: ${{ env.ECR_REGION }} role-to-assume: ${{ env.IAM_ROLE_ARN}} - name: Login to ECR id: login-ecr uses: aws-actions/amazon-ecr-login@v1 - name: Create Image Tag id: image-tag run: | SHA=${{ github.sha }} TAG=$(TZ=UTC-9 date '+%Y%m%d')-${SHA:0:7} echo "DOCKER_TAG=$TAG" >> $GITHUB_ENV - name: build and push to ECR id: build-image uses: docker/build-push-action@v2 with: push: true file: app/Dockerfile tags: ${{ env.ECR_REGISTRY }}/${{ env.ECR_REPOSITORY }}:${{ env.DOCKER_TAG }}
application.yaml
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: app namespace: argocd spec: project: default source: repoURL: https://github.com/fy0323/argocd-image-updater-test.git targetRevision: main path: manifest/overlays/dev/ destination: server: https://kubernetes.default.svc namespace: default
manifest/base/deployment.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: sample-app labels: app: sample spec: replicas: 1 selector: matchLabels: app: sample template: metadata: labels: app: sample spec: containers: - name: app image: <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221112-540daf5 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: sample-app spec: selector: app: sample ports: - protocol: TCP name: http port: 80 targetPort: 8080
manifest/base/kustomization.yaml
resources: - deployment.yaml
manifest/overlays/dev/kustomization.yaml
resources: - ../../base commonLabels: env: develop
ArgoCD Image Updater導入前のアプリケーションは、以下のような文字列を出力します。以降のイメージ更新では、この文字列を修正して比較します。
$ kubectl run nginx --image nginx $ kubectl exec -it nginx -- curl http://sample-app <html><body>Hello, Argocd Image Updater</body></html>
ArgoCD Image Updaterの導入
ここから上記構成にArgoCD Image Updaterを導入します。また、ArgoCD Image UpdaterがECRを使うために追加が必要な設定もあるので、そちらも併せて設定します。
ArgoCD Image Updaterは複数のコンテナイメージリポジトリで動作することが確認されていますが、現時点でAmazon ECRはドキュメントには記載されていません。ただ、GitHub issueには設定方法が紹介されていたり、すでに本番環境で導入されている例もあるため、それらを参考にしています。
※参考:
インストール用ファイルの用意
ArgoCD Image Updaterのインストール用のファイルはGitHubに配置されています。今回はこのファイルを一部修正する必要があるため、事前に手元に用意しておきます。
IRSAの用意
ArgoCD Image Updaterがコンテナイメージの検索や更新の検知をするには、ターゲットのコンテナレジストリにアクセスする必要があります。ArgoCD Image UpdaterにECRへのアクセス権を付与するには、Image Updater Podの動作するNodeか、Pod自体にIAMポリシーを付与する必要があります。セキュリティのことを考慮すると後者のほうが望ましいため、今回はIRSA (IAM Role for Service Account) を利用します。
IRSAの設定は今回AWSマネージドコンソールから行いました(手順はこちらなどを参照してください)。ArgoCD Image Updaterが必要な権限はECRに対する読み取り権限だけなので、今回は AmazonEC2ContainerRegistryReadOnly
というAWSのマネージドポリシーを付与したロールを用意しました。
また、ArgoCD Image UpdaterのService AccountがIAMロールを利用するため、マニフェストファイルを修正します。
apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: argocd-image-updater app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater # 以降を追加 annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS account id>:role/role-for-ecr-access
argocd-image-updater-config
ConfigMapの修正
ECRへのアクセスを行うには、IAMの権限を所有していることに加え、アクセス用の認証トークンを使用する必要があります。このトークンは12時間ごとに無効になるため、定期的にトークンを取得する必要があります。
認証トークンを定期的に取得するにはCronJobを使う方法もありますが、今回は argocd-image-updater-config
にスクリプトを仕込む方法にしました。
argocd-image-updater-config
はArgoCD Image Updaterのインストール時に合わせて作成されるConfigMapで、アクセス先のコンテナレジストリの情報やGitHubへのコミットメッセージなどの設定を定義するファイルです。このファイルに以下のような設定を追加します。
apiVersion: v1 kind: ConfigMap metadata: name: argocd-image-updater-config namespace: argocd # 以降を設定 data: registries.conf: | registries: - name: ECR api_url: https://<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com prefix: <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com credentials: ext:/app/scripts/ecr-login.sh credsexpire: 10h ecr-login.sh: | #!/bin/sh aws ecr --region ap-northeast-1 get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d
また、上記ConfigMapで取得した認証トークンをPodから利用するため、 argocd-image-updater
Deploymentにも修正をします。
apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: argocd-image-updater app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater spec: (一部抜粋) # 以降を追加 volumeMounts: - mountPath: /app/scripts name: ecr-login-script volumes: - configMap: defaultMode: 0755 items: - key: ecr-login.sh path: ecr-login.sh name: argocd-image-updater-config optional: true name: ecr-login-script
最終的にArgoCD Image Updaterのデプロイに使用したマニフェストファイルは以下の通りです。
argocd-image-updater-manifest.yaml
apiVersion: v1 kind: ServiceAccount metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: argocd-image-updater app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS account id>:role/role-for-ecr-access --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: argocd-image-updater app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater rules: - apiGroups: - "" resources: - secrets - configmaps verbs: - get - list - watch - apiGroups: - argoproj.io resources: - applications verbs: - get - list - update - patch - apiGroups: - "" resources: - events verbs: - create --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: argocd-image-updater app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: argocd-image-updater subjects: - kind: ServiceAccount name: argocd-image-updater --- apiVersion: v1 kind: ConfigMap metadata: name: argocd-image-updater-config namespace: argocd data: registries.conf: | registries: - name: ECR api_url: https://<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com prefix: <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com credentials: ext:/app/scripts/ecr-login.sh credsexpire: 10h ecr-login.sh: | #!/bin/sh aws ecr --region ap-northeast-1 get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d --- apiVersion: v1 kind: ConfigMap metadata: labels: app.kubernetes.io/name: argocd-image-updater-ssh-config app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater-ssh-config --- apiVersion: v1 kind: Secret metadata: labels: app.kubernetes.io/name: argocd-image-updater-secret app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater-secret --- apiVersion: apps/v1 kind: Deployment metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: argocd-image-updater app.kubernetes.io/part-of: argocd-image-updater name: argocd-image-updater spec: selector: matchLabels: app.kubernetes.io/name: argocd-image-updater strategy: type: Recreate template: metadata: labels: app.kubernetes.io/name: argocd-image-updater spec: containers: - command: - /usr/local/bin/argocd-image-updater - run env: - name: APPLICATIONS_API valueFrom: configMapKeyRef: key: applications_api name: argocd-image-updater-config optional: true - name: ARGOCD_GRPC_WEB valueFrom: configMapKeyRef: key: argocd.grpc_web name: argocd-image-updater-config optional: true - name: ARGOCD_SERVER valueFrom: configMapKeyRef: key: argocd.server_addr name: argocd-image-updater-config optional: true - name: ARGOCD_INSECURE valueFrom: configMapKeyRef: key: argocd.insecure name: argocd-image-updater-config optional: true - name: ARGOCD_PLAINTEXT valueFrom: configMapKeyRef: key: argocd.plaintext name: argocd-image-updater-config optional: true - name: ARGOCD_TOKEN valueFrom: secretKeyRef: key: argocd.token name: argocd-image-updater-secret optional: true - name: IMAGE_UPDATER_LOGLEVEL valueFrom: configMapKeyRef: key: log.level name: argocd-image-updater-config optional: true - name: GIT_COMMIT_USER valueFrom: configMapKeyRef: key: git.user name: argocd-image-updater-config optional: true - name: GIT_COMMIT_EMAIL valueFrom: configMapKeyRef: key: git.email name: argocd-image-updater-config optional: true - name: IMAGE_UPDATER_KUBE_EVENTS valueFrom: configMapKeyRef: key: kube.events name: argocd-image-updater-config optional: true image: quay.io/argoprojlabs/argocd-image-updater:latest imagePullPolicy: Always livenessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 3 periodSeconds: 30 name: argocd-image-updater ports: - containerPort: 8080 readinessProbe: httpGet: path: /healthz port: 8080 initialDelaySeconds: 3 periodSeconds: 30 volumeMounts: - mountPath: /app/config name: image-updater-conf - mountPath: /app/config/ssh name: ssh-known-hosts - mountPath: /app/.ssh name: ssh-config - mountPath: /app/scripts name: ecr-login-script serviceAccountName: argocd-image-updater volumes: - configMap: items: - key: registries.conf path: registries.conf - key: git.commit-message-template path: commit.template name: argocd-image-updater-config optional: true name: image-updater-conf - configMap: name: argocd-ssh-known-hosts-cm optional: true name: ssh-known-hosts - configMap: name: argocd-image-updater-ssh-config optional: true name: ssh-config - configMap: defaultMode: 0755 items: - key: ecr-login.sh path: ecr-login.sh name: argocd-image-updater-config optional: true name: ecr-login-script
ArgoCD Image Updaterのデプロイ
上記修正を行ったマニフェストファイルをデプロイします。
$ kubectl apply -n argocd -f argocd-image-updater-manifest.yaml serviceaccount/argocd-image-updater created role.rbac.authorization.k8s.io/argocd-image-updater created rolebinding.rbac.authorization.k8s.io/argocd-image-updater created configmap/argocd-image-updater-config created configmap/argocd-image-updater-ssh-config created secret/argocd-image-updater-secret created deployment.apps/argocd-image-updater created
導入後の動作確認
ArgoCD Image Updaterをデプロイ後、作成したPodからECRにアクセスし、コンテナイメージを検索できるかを確認します。ArgoCD Image UpdaterはCLIも用意されており、作成したPodからコマンドを実行することで、簡易的な動作確認をとることができます。
$ kubectl exec -it argocd-image-updater-ddbf7df64-prgk6 -n argocd -- argocd-image-updater test <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test --credentials ext:/app/scripts/ecr-login.sh --registries-conf-path /app/config/registries.conf DEBU[0000] Creating in-cluster Kubernetes client INFO[0000] retrieving information about image image_alias= image_name=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test registry_url=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com DEBU[0000] rate limiting is disabled prefix=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com registry="https://<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com" INFO[0000] Loaded 1 registry configurations from /app/config/registries.conf INFO[0000] /app/scripts/ecr-login.sh dir= execID=2d322 INFO[0003] /app/scripts/ecr-login.sh dir= execID=d8ba2 INFO[0004] Fetching available tags and metadata from registry application=test image_alias= image_name=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test registry_url=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com INFO[0004] Found 3 tags in registry application=test image_alias= image_name=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test registry_url=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com DEBU[0004] found 3 from 3 tags eligible for consideration image=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test INFO[0004] latest image according to constraint is <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221112-5cd2a03 application=test image_alias= image_name=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test registry_url=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com
※参考リンク:
ArgoCD Image Updaterの動作確認
ここからArgoCD Image Updaterを使ってコンテイメージの更新を行います。
コンテナイメージの更新方法
ArgoCD Image Updaterによるイメージの更新方法は大きく2つあり、動作中の Application
リソースに直接編集を加える ( write-back-method: argocd
) か、GitHubリポジトリに向けてイメージを修正するコミットを作成する ( write-back-method: git
) かになります。
※参考リンク:
write-back-method: argocd
argocd
による更新は、ArgoCD APIを通してパラメータの上書きを行います。デフォルトではこちらの方法が設定されます。
この方法はArgoCD Web UIやCLIによってアプリケーションを更新する場合に適している方法です。Image Updaterによる変更はマニフェストファイル等には保存されず、既存のApplicationを削除し再作成した場合、Image Updaterによる更新は反映されません。
こちらの方法では、ソースコードリポジトリに定義されたマニフェストとは異なる定義のアプリケーションが動作することになるため、GitOpsの原則からは外れた使い方となりますが、プロジェクトによってはこちらを採用するケースもあるようです。
write-back-method: git
git
による更新は、パラメータの上書きのためにgitを利用します。この方法を有効にすると、ターゲットブランチ配下で .argocd-source-<appName>.yaml
というファイルが作成され、更新するイメージの名称が更新されます。これにより、Image Updaterによるパラメータの上書きがgitに保存され、Gitopsの原則に従う形で更新することが可能となります。
動作確認: argocd
まずは argocd
のほうを試します。事前に以下のようにApplicationファイルを修正します。
apiVersion: argoproj.io/v1alpha1 kind: Application metadata: name: app namespace: argocd # 以下のannotationsを追加 annotations: argocd-image-updater.argoproj.io/write-back-method: argocd argocd-image-updater.argoproj.io/image-list: app=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test argocd-image-updater.argoproj.io/app.update-strategy: latest spec: project: default source: repoURL: https://github.com/fy0323/argocd-image-updater-test.git targetRevision: main path: manifest/overlays/dev/ destination: server: https://kubernetes.default.svc namespace: default
metadata.annotations
に追加した項目について補足です。
argocd-image-updater.argoproj.io/write-back-method
: Updaterによるイメージの上書き方法を指定します。argocd / git
のいずれかを指定可能です。argocd-image-updater.argoproj.io/image-list
: ターゲットとなるコンテナレジストリを指定します。ここではコンテナレジストリ名のエイリアスを設定することができます。今回はapp
という名称でエイリアスを設定します。argocd-image-updater.argoproj.io/app.update-strategy
: アップデートの対象とするコンテナイメージをどう特定するか定義します。これはimage-list
で設定したレジストリに対して設定し、semver / latest / digest
などの方法を指定できます。今回はレジストリ内で作成された最新バージョンのイメージを対象とするlatest
を指定してます。
※参考リンク:
上記マニフェストファイルをデプロイします。
$ kubectl apply -f argocd-image-updater-test/application.yaml
application.argoproj.io/app configured
この状態でアプリケーションのほうを修正し、新しいコンテナイメージを作成します。しばらくすると、Applicationの状態が OutOfSync
となり、差分ができていることが確認できます。
$ argocd app list NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET app https://kubernetes.default.svc default default OutOfSync Healthy <none> <none> https://github.com/fy0323/argocd-image-updater-test.git manifest/overlays/dev/ main
ここからSyncをしてPodを更新すると、アプリケーションに修正内容が反映されたことが確認できます。
$ argocd app sync app TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE 2022-11-15T16:58:00+09:00 Service default sample-app Synced Healthy 2022-11-15T16:58:00+09:00 apps Deployment default sample-app OutOfSync Healthy 2022-11-15T16:58:00+09:00 apps Deployment default sample-app OutOfSync Healthy deployment.apps/sample-app configured 2022-11-15T16:58:00+09:00 Service default sample-app Synced Healthy service/sample-app unchanged 2022-11-15T16:58:00+09:00 apps Deployment default sample-app Synced Progressing deployment.apps/sample-app configured (以降割愛) $ kubectl exec -it nginx -- curl http://sample-app <html><body>Hello, Argocd Image Updater 20221115-01</body></html>
参考: イメージタグ更新時のArgoCD Image Updaterログ
$ kubectl logs -n argocd argocd-image-updater-ddbf7df64-prgk6 -f (一部抜粋) time="2022-11-15T07:54:51Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update" time="2022-11-15T07:54:51Z" level=warning msg="\"latest\" strategy has been renamed to \"newest-build\". Please switch to the new convention as support for the old naming convention will be removed in future versions." image_alias=app image_name=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test registry_url=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com time="2022-11-15T07:54:51Z" level=info msg="Setting new image to <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-a1fbb26" alias=app application=app image_name=argocd-image-updater-test image_tag=20221115-5938771 registry=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com time="2022-11-15T07:54:51Z" level=info msg="Successfully updated image '<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-5938771' to '<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-a1fbb26', but pending spec update (dry run=false)" alias=app application=app image_name=argocd-image-updater-test image_tag=20221115-5938771 registry=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com time="2022-11-15T07:54:51Z" level=info msg="Committing 1 parameter update(s) for application app" application=app time="2022-11-15T07:54:52Z" level=info msg="Successfully updated the live application spec" application=app time="2022-11-15T07:54:52Z" level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0"
動作確認: git
続いて git
のほうも試します。今回はApplicationマニフェストの argocd-image-updater.argoproj.io/write-back-method
の修正を行い、再度デプロイします。
$ kubectl apply -f argocd-image-updater-test/application.yaml application.argoproj.io/app configured $ kubectl describe app -n argocd app Name: app Namespace: argocd Labels: <none> Annotations: argocd-image-updater.argoproj.io/app.update-strategy: latest argocd-image-updater.argoproj.io/image-list: app=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test argocd-image-updater.argoproj.io/write-back-method: git API Version: argoproj.io/v1alpha1 Kind: Application (以下割愛)
この状態でアプリケーションのほうを修正し、新しいコンテナイメージを作成します。しばらくすると、GitHubのほうに新しいファイルが作られていることが確認できます。
$ git pull origin main $ ls -la manifest/overlays/dev/ total 0 drwxr-xr-x 1 testadm testadm 4096 Nov 15 17:33 . drwxr-xr-x 1 testadm testadm 4096 Nov 12 10:08 .. -rw-r--r-- 1 testadm testadm 118 Nov 15 17:33 .argocd-source-app.yaml # 新規追加されたファイル -rw-r--r-- 1 testadm testadm 52 Nov 12 10:08 kustomization.yaml $ cat .argocd-source-app.yaml kustomize: images: - <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-7f8b2c9
またApplicationの状態も OutOfSync
となり、差分ができていることが確認できます。これをSyncすることで、アプリケーションへの修正が反映されたことが確認できます。
$ argocd app list NAME CLUSTER NAMESPACE PROJECT STATUS HEALTH SYNCPOLICY CONDITIONS REPO PATH TARGET app https://kubernetes.default.svc default default OutOfSync Healthy <none> <none> https://github.com/fy0323/argocd-image-updater-test.git manifest/overlays/dev/ main $ argocd app sync app TIMESTAMP GROUP KIND NAMESPACE NAME STATUS HEALTH HOOK MESSAGE 2022-11-15T17:12:27+09:00 Service default sample-app Synced Healthy 2022-11-15T17:12:27+09:00 apps Deployment default sample-app OutOfSync Healthy 2022-11-15T17:12:27+09:00 Service default sample-app Synced Healthy service/sample-app unchanged 2022-11-15T17:12:27+09:00 apps Deployment default sample-app OutOfSync Healthy deployment.apps/sample-app configured 2022-11-15T17:12:27+09:00 apps Deployment default sample-app Synced Progressing deployment.apps/sample-app configured (以降割愛) $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx 1/1 Running 0 65m sample-app-74b49d7856-ln75h 1/1 Running 0 30s $ kubectl exec -it nginx -- curl http://sample-app <html><body>Hello, Argocd Image Updater 20221115-02</body></html>
なお、 git
方式の場合、以降はイメージタグは .argocd-source-app.yaml
を参照します。そのため、git
方式でImage Updaterを有効にすると、 例えば手動でマニフェストファイル (今回なら deployment.yaml
) のイメージタグを更新しても、起動するPodには反映されません。
参考: イメージタグ更新時のArgoCD Image Updaterログ
$ kubectl logs -n argocd argocd-image-updater-ddbf7df64-prgk6 -f (一部抜粋) time="2022-11-15T08:06:52Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update" time="2022-11-15T08:06:52Z" level=warning msg="\"latest\" strategy has been renamed to \"newest-build\". Please switch to the new convention as support for the old naming convention will be removed in future versions." image_alias=app image_name=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test registry_url=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com time="2022-11-15T08:06:53Z" level=info msg="Setting new image to <AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-7f8b2c9" alias=app application=app image_name=argocd-image-updater-test image_tag=20221115-a1fbb26 registry=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com time="2022-11-15T08:06:53Z" level=info msg="Successfully updated image '<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-a1fbb26' to '<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com/argocd-image-updater-test:20221115-7f8b2c9', but pending spec update (dry run=false)" alias=app application=app image_name=argocd-image-updater-test image_tag=20221115-a1fbb26 registry=<AWS account id>.dkr.ecr.ap-northeast-1.amazonaws.com time="2022-11-15T08:06:53Z" level=info msg="Committing 1 parameter update(s) for application app" application=app time="2022-11-15T08:06:53Z" level=info msg="Starting configmap/secret informers" time="2022-11-15T08:06:53Z" level=info msg="Configmap/secret informer synced" time="2022-11-15T08:06:53Z" level=info msg="Initializing https://github.com/fy0323/argocd-image-updater-test.git to /tmp/git-app2064956039" time="2022-11-15T08:06:53Z" level=info msg="rm -rf /tmp/git-app2064956039" dir= execID=839c5 time="2022-11-15T08:06:53Z" level=info msg="secrets informer cancelled" time="2022-11-15T08:06:53Z" level=info msg="configmap informer cancelled" time="2022-11-15T08:06:53Z" level=info msg=Trace args="[rm -rf /tmp/git-app2064956039]" dir= operation_name="exec rm" time_ms=2.52375 time="2022-11-15T08:06:53Z" level=info msg="git fetch origin --tags --force" dir=/tmp/git-app2064956039 execID=1bda6 time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git fetch origin --tags --force]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=926.411977 time="2022-11-15T08:06:54Z" level=info msg="git config user.name argocd-image-updater" dir=/tmp/git-app2064956039 execID=82001 time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git config user.name argocd-image-updater]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=5.418636 time="2022-11-15T08:06:54Z" level=info msg="git config user.email noreply@argoproj.io" dir=/tmp/git-app2064956039 execID=87e8b time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git config user.email noreply@argoproj.io]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=5.845921 time="2022-11-15T08:06:54Z" level=info msg="git checkout --force main" dir=/tmp/git-app2064956039 execID=29d9f time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git checkout --force main]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=10.429219 time="2022-11-15T08:06:54Z" level=info msg="git clean -fdx" dir=/tmp/git-app2064956039 execID=434ff time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git clean -fdx]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=6.051158 time="2022-11-15T08:06:54Z" level=info msg="git add /tmp/git-app2064956039/manifest/overlays/dev/.argocd-source-app.yaml" dir=/tmp/git-app2064956039 execID=b8197 time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git add /tmp/git-app2064956039/manifest/overlays/dev/.argocd-source-app.yaml]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=11.407465 time="2022-11-15T08:06:54Z" level=info msg="git commit -a -F /tmp/image-updater-commit-msg2947554435" dir=/tmp/git-app2064956039 execID=07c3b time="2022-11-15T08:06:54Z" level=info msg=Trace args="[git commit -a -F /tmp/image-updater-commit-msg2947554435]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=32.495799 time="2022-11-15T08:06:54Z" level=info msg="git push origin main" dir=/tmp/git-app2064956039 execID=068e8 time="2022-11-15T08:06:55Z" level=info msg=Trace args="[git push origin main]" dir=/tmp/git-app2064956039 operation_name="exec git" time_ms=1042.2358430000002 time="2022-11-15T08:06:55Z" level=info msg="Successfully updated the live application spec" application=app time="2022-11-15T08:06:55Z" level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0"