Skip to content

ArgoCD Image Updater: Подключение к приватному Amazon ECR (Elastic Container Registry)

Утилита ArgoCD Image Updater необходима для автоматического обновления версии docker image в Helm Chart’е при использовании ArgoCD. Настройка данной утилиты усложнена несколькими факторами — достаточно скудной документацией — много чего нет, и отсутствием нативной поддержки Amazon ECR (Elastic Container Registry)

Скажу сразу, что больше времени потратил на изучение ишью на GitHub, ну штож

Производим установку Argo CD Image Updater в тот же namespace где установлен ArgoCD (в моем случае это argocd)

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

После, создаем ConfigMap с настройками подключения к нашему репозиторию

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    app.kubernetes.io/name: argocd-image-updater-config
    app.kubernetes.io/part-of: argocd-image-updater
  name: argocd-image-updater-config
  namespace: argocd
data:
  argocd.plaintext: "true"
  log.level: debug
  registries.conf: |
    registries:
    - name: ECR 000000000.dkr.ecr.us-east-2.amazonaws.com
      api_url: https://000000000.dkr.ecr.us-east-2.amazonaws.com
      prefix: 000000000.dkr.ecr.us-east-2.amazonaws.com
      ping: no
      tagsortmode: none
      credsexpire: 1h
      credentials: secret:argocd/aws-ecr-creds#creds

Хочу обратить внимание на то, что нам в обязательном порядке нужно поставить tagsortmode: none , если мы укажем иные правила сортировки, такие как latest-first или latest-last мы не сможем получить все метаданные. Поле credentials можно оставить таким, ниже будет приведен пример CronJob для обновления токена, для доступа к Private Registry ECR

Собственно, одна из основных проблем заключается в том, что время жизни токена составляет всего 12 часов для Amazon ECR, и ручками его обновлять не комильфо. Как вариант, можно еще попробовать утилиты (на medium встречал парочку), но они основаны на том же принципе.

Пример CronJob для обновления токена, добавляем в namespace argocd


apiVersion: v1
kind: ServiceAccount
metadata:
  name: ecr-secret-udpater
  namespace: argocd
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: ecr-secret-udpater
  namespace: argocd
rules:
  - apiGroups: ["*"]
    resources: ["secrets"]
    verbs: ["list", "update", "delete", "create"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ecr-secret-udpater
  namespace: argocd
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: ecr-secret-udpater
subjects:
  - kind: ServiceAccount
    name: ecr-secret-udpater
---
apiVersion: v1
kind: Secret
metadata:
  annotations:
    description: this secret is dynamically updated by the k8s CronJob ecr-secret-update. store ECR registry user/token
  name: aws-ecr-creds
stringData:
  creds: will_be_set_by_the_job
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: ecr-secret-update
spec:
  failedJobsHistoryLimit: 3
  successfulJobsHistoryLimit: 3
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - args:
                - -c
                - kubectl -n argocd create secret generic aws-ecr-creds --from-literal=creds=AWS:$(cat /store/token) --dry-run=client -o yaml | kubectl replace -f -
              command:
                - sh
              image: bitnami/kubectl:1.20.9
              name: kubectl
              volumeMounts:
                - mountPath: /store
                  name: store
          initContainers:
            - args:
                - -c
                - aws ecr get-login-password --region us-east-2 > /store/token
              command:
                - sh
              image: amazon/aws-cli:2.2.20
              name: get-login-password
              volumeMounts:
                - mountPath: /store
                  name: store
          restartPolicy: OnFailure
          serviceAccountName: ecr-secret-udpater
          volumes:
            - emptyDir:
                medium: Memory
              name: store
      ttlSecondsAfterFinished: 100
  schedule: '0 */3 * * *'

Хочу обратить внимание на то, что в джобе выше нужно изменить на свое — регион, время обновления, параметры failedJobsHistoryLimit и successfulJobsHistoryLimit.
Особое внимание хочу обратить на команду


...
                - kubectl -n argocd create secret generic aws-ecr-creds --from-literal=creds=AWS:$(cat /store/token) --dry-run=client -o yaml | kubectl replace -f -

тут нужно указать namespace (у меня это argocd) где будет обновляться секрет, я пару дней не мог понять почему не обновляется токен, тока не пришло озарение и пара выпитых чашек кофе.

Далее нам нужно добавить аннотации к Application от ArgoCD. Пример ниже

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: some-app-name
  namespace: argocd
  annotations:
    #-- shared
    argocd-image-updater.argoproj.io/image-list: nginx=000000000.dkr.ecr.us-east-2.amazonaws.com/removed_path/nginx
    argocd-image-updater.argoproj.io/write-back-method: git:secret:argocd/creds-12345566777
    argocd-image-updater.argoproj.io/git-branch: feature/dev-argo-rollouts
    #--  nginx
    argocd-image-updater.argoproj.io/nginx.update-strategy: latest
    argocd-image-updater.argoproj.io/nginx.helm.image-name: nginx_node.nginxContainer.registry.image
    argocd-image-updater.argoproj.io/nginx.helm.image-tag: nginx_node.nginxContainer.registry.tag
    argocd-image-updater.argoproj.io/nginx.allow-tags: 'regexp:^[a-z0-9]+$'
    argocd-image-updater.argoproj.io/nginx.ignore-tags: "latest"
...

Чуть опишу эти параметры:
argocd-image-updater.argoproj.io/image-list — указываем ссылку на registry, где nginx= является алиасом на registry

argocd-image-updater.argoproj.io/write-back-method: — указывает на то, что обновления будут декларативные с записью в git репозиторий, также указывается «ссылка» на секрет с доступами к github, который создается ArgoCD

argocd-image-updater.argoproj.io/git-branch: — указываем в какой ветке репозитория с Helm Chart’ом будет создаваться файл .argocd-source-{project_name}.yaml с номером тега контейнера

Далее аннотации содержат алиас который я использовал

argocd-image-updater.argoproj.io/nginx.update-strategy:  — забираем последнюю версию

argocd-image-updater.argoproj.io/nginx.helm.image-name: 
и
argocd-image-updater.argoproj.io/nginx.helm.image-tag — ссылка на параметры тега и пути к образу в Helm Chart’e, если указать одной строкой image_path:tag отрабатывать не будет, поэтому нужно разбить на две переменные, если указано просто одной строкой

argocd-image-updater.argoproj.io/nginx.allow-tags: ‘regexp:^[a-z0-9]+$‘— с помощью регулярки выбираем теги которые нам будут интересны. Редактировать под свой проект. У нас указано так, чтобы можно было выбрать имейдж по sha

argocd-image-updater.argoproj.io/nginx.ignore-tags: “latest” — блокируем выборку данного тега, иначе будет проставлять только его.

Если все будет успешно, утилита будет проверять каждые 2 минуты проверять наличие новых версий

Дисклеймер: все что описано, собиралось по кусочкам из issues github проекта, т. к. в доке много нет. Поэтому могу быть в чем-то неправ, с радостью выслушаю правки и советы.

Published inArgoCD

One Comment

  1. Петровичь Петровичь

    Спасибо за велосипед, очень пригодился)

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *