🙆‍♀️

EKS&ECR環境にArgoCD Image Updaterをインストールして使う

2023/07/20に公開

ArgoCD Image Updaterとは

  • ArgoCD上で管理しているリソースのイメージのみが更新された場合にもデプロイをしてくれる
  • 通常マニフェストファイルが変更された場合、それを検知しデプロイする流れだが、イメージのみの場合は反応できないため。GithubActionsなどを使って、イメージタグを書き換えるようなものを自作する必要があった
  • helm or kustomizeでのみ利用可能な模様
  • 特に理由がなければ、ArgoCDが動作しているクラスタのNamespaceにデプロイしてあげるのが良い

構成

  • EKS version1.27
  • ArgoCDと同一クラスタでImage Updaterをインストール

導入手順

マニフェストインストール

kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

kustomizeにする

kustomization.yaml

  • https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yamlが元となるマニフェストファイル
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: argocd

resources:
- https://raw.githubusercontent.com/argoproj-labs/argocd-image-updater/stable/manifests/install.yaml

patches:
  - path: argocd-image-updater/configmap.yaml # ConfigMap
  - path: argocd-image-updater/deployment.yaml # Deployment
  - path: argocd-image-updater/rbac.yaml # ServiceAccount

argocd-image-updater/rbac.yaml

  • ここで指定しているRoleの権限
apiVersion: v1
kind: ServiceAccount
metadata:
  name: argocd-image-updater
  annotations:
    eks.amazonaws.com/role-arn: arn:aws:iam::111111111111:role/argocd-image-updater

Roleの権限

指定するポリシー

AmazonEC2ContainerRegistryFullAccess

信頼されたエンティティ

クラスタのID、namespace、serviceaccount名などを正しく指定する。
ミスっていた場合、資格情報エラーになるはずなので、その時はここをもう一度チェック。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Federated": "arn:aws:iam::1111111111111:oidc-provider/oidc.eks.ap-northeast-1.amazonaws.com/id/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringEquals": {
                    "oidc.eks.ap-northeast-1.amazonaws.com/id/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA:sub": "system:serviceaccount:argocd:argocd-image-updater"
                }
            }
        }
    ]
}

argocd-image-updater/configmap.yaml

  • ECRは実は標準サポートされていないため、トークン取得処理を自身で書いてあげる必要がある
  • ConfigMapなので、シェルスクリプトを生成するのみ
apiVersion: v1
kind: ConfigMap
metadata:
  name: argocd-image-updater-config
data:
  log.level: debug
  ecr-login.sh: |
    #!/bin/sh
    aws ecr --region ap-northeast-1 get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d
  registries.conf: |
    registries:
      - name: ECR
        api_url: https://111111111111.dkr.ecr.ap-northeast-1.amazonaws.com
        prefix: 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com
        credentials: ext:/app/scripts/ecr-login.sh
        credsexpire: 10h

argocd-image-updater/deployment.yaml

  • ConfigMapで作ったシェルスクリプトをマウントする設定
apiVersion: apps/v1
kind: Deployment
metadata:
  name: argocd-image-updater
spec:
  template:
    spec:
      containers:
        - name: argocd-image-updater
          volumeMounts:
            - name: ecr-login-script
              mountPath: /app/scripts
      volumes:
        - name: ecr-login-script
          configMap:
            defaultMode: 0755
            items:
              - key: ecr-login.sh
                path: ecr-login.sh
            name: argocd-image-updater-config
            optional: true

デプロイ

kustomize build | kubectl apply -f -

image updaterを利用したい側の設定

  • annotationに必要なパラメータを追加していく
  • write-back-methodは、argocd or gitを選ぶ。
    • argocdの場合は、gitリポジトリ上のマニフェストファイルを直接いじらずに、ArgoCDの中でImageタグを書き換えてくれる
    • gitの場合は、github上のimageタグも書き換えてくれる
    • 最終的には、GitOpsの本流に乗っ取り、gitにするのがよさそう
    • 開発環境などとりあえず最新をデプロイしたいとかであればargocdが良さそう??
  • image-listは、利用するイメージのリストを定義する。この場合、apiというイメージ名のエイリアスを定義している
  • api.update-strategyは、最新を取得するためにどの方法で取得するかという設定
    • latestはlatestタグを最新とみなす
    • デフォルトはsemver
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: app
  namespace: argocd
  annotations:
    argocd-image-updater.argoproj.io/write-back-method: argocd
    argocd-image-updater.argoproj.io/image-list: api=111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/nr-telema/prd/api
    argocd-image-updater.argoproj.io/api.update-strategy: latest

上記マニフェストをデプロイして、argocd上で確認できるマニフェストのイメージタグがlatestイメージのハッシュ値に変わっていればOK

テストコマンド

コンテナレジストリを指定して実際にImagePullできるかを簡易的に確認することができる。

https://argocd-image-updater.readthedocs.io/en/stable/install/testing/

kubectl exec -it argocd-image-updater-7d649f9bdf-xdk4h -- argocd-image-updater test nginx
kubectl exec -it argocd-image-updater-74fb9f4b58-c4gvn -- argocd-image-updater test 111111111111.dkr.ecr.ap-northeast-1.amazonaws.com/nr-telema/prd/api --update-strategy latest --credentials ext:/app/scripts/ecr-login.sh --registries-conf-path /app/config/registries.conf

--update-strategyを指定しない場合は、semverで適用されるので、タグをx.x.xの形式で付与していない場合は、認識されないので注意。

トラシュー

資格情報があってない場合

serviceaccountでマッピングしているRoleの信頼関係が怪しいかもしれない
Condition.StringEqualで指定しているリソースのNameSpaceなどが正しいかチェック

ログ

FATA[0000] could not set registry credentials: invalid script output, must be single line with syntax <username>:<password>

コンテナにexecでログインして、自身の情報をGETできるかを見ると切り分けできそう

aws sts get-caller-identity

annotationを正しく指定しているはずなのに、Argocd Image Updaterが最新イメージを検知しない

kubectl logsでログを見ても、検知される様子は一向にない。
その場合、Namespaceをargocdにインストールしていないかもしれないのでチェック。
クラスタと同一 Namespaceにインストールしないと、やり取りができないというか、その場合はおそらくNamespace付きのFQDNを ArgoCD APIサーバとして登録してあげる必要があると思われる。

参考

https://argocd-image-updater.readthedocs.io/en/stable/install/installation/
https://techblog.zozo.com/entry/measure-argocd-image-updater
https://techstep.hatenablog.com/entry/2022/12/03/111824

Discussion