Closed8

【EKS】argocd image updaterでlatestイメージを更新する

not75743not75743

流れ

  • 簡単なgolang apiをECRへプッシュする
  • argocd管理のapi用manifestで↑を指定してデプロイ出来ることを確認
  • argocd image updaterをクラスタへ入れる
  • api用のmanifestにimage updater用のannotationを加え、イメージの変更を検知できるか確認
    • helmにもした
not75743not75743

簡単なgolang apiをECRへプッシュする

これは普通にpushするだけ
apiは最小限で

package main

import (
	"fmt"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, World!")
	})

	fmt.Println("Starting server at port 8080...")
	http.ListenAndServe(":8080", nil)
}

workflowsはこんな感じ

name: build test image

on:
  push:
    branches:
      - main
  workflow_dispatch:

jobs:
  push:
    runs-on: ubuntu-latest
    permissions:
      id-token: write
      contents: read
    steps:
      - uses: actions/checkout@v4
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - uses: aws-actions/configure-aws-credentials@v4
        env:
          AWS_REGION: ap-northeast-1
        with:
          role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
          aws-region: ${{ env.AWS_REGION }}
      - name: Login to Amazon ECR Private
        id: login-ecr
        uses: aws-actions/amazon-ecr-login@v2
      - name: docker build and push ECR
        uses: docker/build-push-action@v5
        env:
          ECR_REPO: <repo>
        with:
          platforms: linux/amd64
          file: ./testapp/Dockerfile
          push: true
          tags: ${{ steps.login-ecr.outputs.registry }}/${{ env.ECR_REPO }}:latest
          provenance: false
not75743not75743

argocd管理のapi用manifestで↑を指定してデプロイ出来ることを確認

deployment/service/ingressを作ってデプロイ出来ることを確認する

argocd app

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: testapp
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io/background
spec:
  project: default
  sources:
    - repoURL: <github repo>
      targetRevision: main
      path: testapp
  destination:
    server: https://kubernetes.default.svc
    namespace: default
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=true

deployment/service

apiVersion: apps/v1
kind: Deployment
metadata:
  name: testapp
  labels:
    app: testapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: testapp
  template:
    metadata:
      labels:
        app: testapp
    spec:
      containers:
      - name: testapp
        image: <repo>:latest
        ports:
        - containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: testapp
  labels:
    app: testapp
spec:
  selector:
    app: testapp
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP
  type: ClusterIP

ingress(aws loadbalancer controller)

ドメインは例示、ALBは使い回すため既にあるものを指定

ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: testapp-ingress
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/load-balancer-name: <hoge>
    alb.ingress.kubernetes.io/group.name:  <hoge>
    alb.ingress.kubernetes.io/group.order: " <hoge>"
    alb.ingress.kubernetes.io/healthcheck-path:  <hoge>
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
    alb.ingress.kubernetes.io/inbound-cidrs: <hoge>
    external-dns.alpha.kubernetes.io/hostname: "testapp.example.com"
spec:
  ingressClassName: alb
  rules:
  - host: testapp.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: testapp
            port:
              number: 80

確認

## replica 2でrunningであること
$ k get pod -n default
NAME                       READY   STATUS    RESTARTS   AGE
testapp-755667d49f-dbnmt   1/1     Running   0          12m
testapp-755667d49f-xmmrw   1/1     Running   0          12m

## httpリクエスト投げてアクセスできること
$ curl https://testapp.example.com
Hello, World!
not75743not75743

argocd image updaterをクラスタへ入れる

argocd appはこんな感じで

argocd
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: argocd-image-updater
  namespace: argocd
  finalizers:
    - resources-finalizer.argocd.argoproj.io/background
spec:
  project: default
  sources:
    - repoURL: https://argoproj.github.io/argo-helm
      chart: argocd-image-updater
      targetRevision: 0.12.1
      helm:
        releaseName: argocd-image-updater
        valueFiles:
        - $repo/.argocd/values/argocd-image-updater.values.yaml
    - repoURL: <values repo>
      targetRevision: main
      ref: repo
  destination:
    server: https://kubernetes.default.svc
    namespace: argocd
  syncPolicy:
    automated:
      prune: true
      selfHeal: true
    syncOptions:
    - CreateNamespace=false

valuesはこう

authScripts:
  enabled: true
  scripts:
    ecr-login.sh: |
      #!bin/sh
      aws ecr --region ap-northeast-1 get-authorization-token --output text --query 'authorizationData[].authorizationToken' | base64 -d

config:
  registries:
  - name: ECR
    api_url: https://<ecr registry endpoint>
    prefix: <ecr registry endpoint>
    ping: yes
    insecure: no
    credentials: ext:/scripts/ecr-login.sh
    credsexpire: 10h
not75743not75743

argocd管理のapi用manifestにannotation追加、helmチャート化してdeploymentとvaluesも修正

latest用の参考
参考1: https://argocd-image-updater.readthedocs.io/en/stable/configuration/images/#tracking-an-images-latest-tag
参考2: https://www.cncf.io/blog/2024/11/05/mastering-argo-cd-image-updater-with-helm-a-complete-configuration-guide/

こんな感じ。

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: testapp
  namespace: argocd
  annotations:
    argocd-image-updater.argoproj.io/image-list: "<repo>:latest"
    argocd-image-updater.argoproj.io/testapp.update-strategy: "digest"
    argocd-image-updater.argoproj.io/testapp.helm.image-name: "image.repository"
    argocd-image-updater.argoproj.io/testapp.helm.image-tag: "image.tag"
    argocd-image-updater.argoproj.io/pull-policy: Always
    argocd-image-updater.argoproj.io/write-back-method: argocd
...

values.yamlもいじる

image:
  repository: "<repo>tag: "latest"
  pullPolicy: "Always"

deploymentは

apiVersion: apps/v1
kind: Deployment
metadata:
  name: testapp
  labels:
    app: testapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: testapp
  template:
    metadata:
      labels:
        app: testapp
    spec:
      containers:
      - name: testapp
        image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
        imagePullPolicy: "{{ .Values.image.pullPolicy }}"
        ports:
        - containerPort: 8080

ディレクトリ構成

testapp/
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── ingress.yaml
│   └── service.yaml
└── values.yaml
not75743not75743

動作確認

2分おきにこのようなメッセージが出力され(ポーリング間隔の様子)

time="2025-04-20T05:35:28Z" level=info msg="Starting image update cycle, considering 1 annotated application(s) for update"
time="2025-04-20T05:35:29Z" level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=0 errors=0"

イメージ更新してこんなログが出ればOK。
images=updatedがカウントされる

time="2025-04-20T05:39:29Z" level=info msg="Successfully updated the live application spec" application=testapp
time="2025-04-20T05:39:29Z" level=info msg="Processing results: applications=1 images_considered=1 images_skipped=0 images_updated=1 errors=0"
このスクラップは4ヶ月前にクローズされました