argocd_image_updater

30 décembre 2021

Si vous êtes un adepte de GitOps, vous avez probablement déjà entendu parler d'ArgoCD. C'est un outil formidable qui vous offre un delivery continu pour votre infrastructure Kubernetes si vous utilisez un outil de templating tel que Helm. En plus de cela, il est assez facile à mettre en place. La société qui le développe créée également un ensemble d'autres outils pour compléter son utilisation et pousser le paradigme GitOps un peu plus loin. Cet article se concentre sur l'un d'entre eux, ArgoCD Image Updater, qui met à jour les versions de vos conteneurs pour vous !

 

Si vous travaillez déjà avec ArgoCD et souhaitez rendre votre infrastructure encore plus centrée sur les développeurs. Ou même si vous êtes simplement un aficionado de GitOps qui veut en savoir plus sur ArgoCD Image Updater, comment le configurer et quels sont les inconvénients et les compromis de ce nouvel outil, vous êtes au bon endroit.

Surcharge des paramètres d'ArgoCD

ArgoCD fournit un moyen de surcharger les paramètres d'une application. Cela donne à l'utilisateur un moyen de déterminer dynamiquement les valeurs de ces paramètres, par exemple une version d'image, sans avoir besoin de modifier les manifestes de déploiement. Cela peut fonctionner de deux façons :

  • Vous pouvez commiter un .argocd-source.yaml dans le dossier de l'application ArgoCD.
  • Vous pouvez commiter un .argocd-source-<argocd-app-name>.yaml directement dans le dossier de manifestes qui est surveillé par votre application ArgoCD.

Notez qu'ArgoCD appliquera d'abord le dernier puis le premier. Ainsi, si vous modifiez les paramètres de la même application dans les deux fichiers, ce sont ceux du fichier .argocd-source-<argocd-app-name>.yaml qui seront déployés.

On pourrait se demander ce que cela a à voir avec Image Updater ? C'est simple : il surveille les registres des conteneurs, lorsqu'une nouvelle version est disponible, il soumet un fichier de surcharge dans votre repository. Voici un exemple de modèle de ce fichier si vous utilisez Helm :

helm:
 parameters:
 - name: <parameter-to-override>
 value: <new-parameter-value>
 forcestring: true

Maintenant que nous avons compris ce que fait ArgoCD Image Updater, nous allons nous plonger dans son installation et sa configuration.

⚠ N.B : Il y a actuellement un issue avec le système d'override. Normalement, vous pouvez spécifier les paramètres Helm à l'intérieur de l'application ArgoCD elle-même. Mais lorsque vous avez un fichier .argocd-source-<argocd-app-name>.yaml, ces paramètres ne sont pas pris en compte.

 

Comment installer et configurer ArgoCD Image Updater

Manifeste d'installation

Utilisez le manifeste d'installation pour déployer Image Updater avec une application ArgoCD. Mon conseil est de le séparer en plus petits manifestes pour le rendre plus lisible et modifiable pour les configurations à venir.

Git credentials

Tout d'abord, ArgoCD Image Updater doit avoir accès à votre repository d’infrastructure. Si vous utilisez un repository privé, vous avez déjà configuré les accès pour ArgoCD. Par défaut, Image Updater utilisera ces accès. La seule chose que vous devez faire est d'ajouter l'accès en écriture à la clé ssh ou au compte que vous utilisez déjà.

Si vous utilisez un repository public, vous n'avez probablement donné qu'un lien HTTPS dans vos applications ArgoCD, mais vous n'avez pas donné de credentials associés à ce lien. Mon conseil serait d'utiliser un personal access token. Vous pouvez en créer un pour Github, Gitlab ou BitBucket. Votre secret devrait ressembler à ceci :

apiVersion: v1
 kind: Secret
 metadata:
 name: <your-secret-name>
 type: Opaque
 stringData:
 username: <your-username>
 password: <your-private-access-token>

Nous verrons plus tard comment Image Updater peut utiliser ce secret.

Credentials du registre des image

Si vous n'utilisez que des images auxquelles vous pouvez accéder publiquement, vous pouvez sauter cette partie. Sinon, ce qui suit pourrait devenir très pratique !

En effet, si vos pods Kubernetes utilisent une image de conteneur stockée dans un registre privé, ArgoCD Image Updater va avoir besoin d'un accès en lecture à celui-ci afin de pouvoir lister les différents tags de votre image. Mais, au moment de la rédaction de cet article, Image Updater n'utilise aucun SDK pour se connecter à ces registres. Par exemple, si vous stockez vos images dans un registre de cloud public, la mise en place d'un compte de service n'est pas suffisante ! Image Updater nous donne plusieurs façons de configurer les credentials (je vais vous le montrer dans un instant) mais vous devez vous rappeler que vous ne pouvez utiliser que l'authentification par nom d'utilisateur et mot de passe. 

Voici à quoi devrait ressembler votre secret :

apiVersion: v1
 kind: Secret
 metadata:
 name: <secret-name>
 type: Opaque
 stringData:
 <your-key>: <username>:<password>

Ensuite, dans la configmap d'Image Updater, vous devez ajouter la configuration du registre. Voici à quoi cela pourrait ressembler pour un registre GCP :

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
 data:
 registries.conf: |
 registries:
 - name: Google Container Registry
 prefix: eu.gcr.io
 api_url: https://eu.gcr.io
 ping: no
 credentials: secret:<secret-namespace>/<secret-name>#<you-key>

💡 Conseil de pro : si vous voulez utiliser un compte de service cloud pour vous connecter à votre registre, mais qu'il a seulement un fichier de configuration JSON (pas de nom d'utilisateur ni de mot de passe), alors vous pouvez utiliser _json_key comme nom d'utilisateur et toute la configuration JSON comme mot de passe (ne pas mettre entre guillemets !).

⚠ Attention : dans la documentation vous trouverez la possibilité d'ajouter un tagsortmode je vous déconseille fortement de l'utiliser car cela peut faire buguer la mise à jour, selon la stratégie de mise à jour que vous utiliserez.

Configuration de l'application avec les credentials

Maintenant que ArgoCD Image Updater est configuré, nous pouvons nous plonger dans son activation pour une application donnée. Tout ce que vous avez à faire est d'ajouter quelques annotations à votre application ArgoCD. Voici les annotations de base :

annotations:
 argocd-image-updater.argoproj.io/write-back-method:
 git:secret:<secret-namespace>/<your-secret-name>
 argocd-image-updater.argoproj.io/image-list: <alias>=<registry-url>

La première annotation indique à ArgoCD d'être déclaratif, c'est à dire qu'il va commiter un fichier de surcharge. Par défaut, la valeur de l'annotation est argocd qui est le mode impératif, c'est-à-dire qu'il va appeler l'API ArgoCD pour faire une mise à jour. Que ce soit pour un usage personnel ou professionnel, je préfère le mode déclaratif afin que mon repository soit ma seule source de vérité pour l'état de mon cluster.

La deuxième annotation indique à image updater quelle image et dans quel registre il doit surveiller les mises à jour, et lui donne un alias (qui deviendra utile assez tôt).
Le secret-namespace et you-secret-name ici sont des références au secret que vous avez créé dans la partie de configuration des credentials Git plus tôt.

💡 N.B : si vous n'avez pas configuré de credentials spécifiques pour Image Updater et que vous utilisez celles d'ArgoCD, vous devez utiliser les options suivantes

annotations:
 argocd-image-updater.argoproj.io/write-back-method: git
 argocd-image-updater.argoproj.io/image-list: <alias>=<registry-url>

Stratégie de mise à jour et tags autorisés

Image updater vous donne la possibilité de mettre à jour les tags en suivant différentes stratégies. Les trois que je trouve les plus utiles sont latest, semver et digest.

latest peut être un peu contre-intuitif. En effet, elle n'utilise pas le tag commun latest d'une image conteneur, elle met à jour le tag avec la date de création la plus récente. Mais vous pourriez vouloir mettre à jour uniquement lorsque des tags particuliers sont poussées. C'est pourquoi vous avez une option allow-tags qui vous permet de définir une regexp de tags autorisés. Pour mettre en place cette stratégie, voici les annotations que vous devez ajouter à votre application ArgoCD :

argocd-image-updater.argoproj.io/<alias>.update-strategy: latest
 argocd-image-updater.argoproj.io/<alias>.allow-tags: regexp:<expression>

N.B. C'est cette stratégie de mise à jour qui n'est pas compatible avec le tagsortmode de la configuration du registre.

semver, comme son nom l'indique, permet de mettre à jour les tags en suivant la convention du même nom. Évidemment, vous n'avez pas besoin de allow-tags pour celle-ci. Il s'agit de la stratégie de mise à jour par défaut, il n'est donc pas obligatoire de la spécifier. Mais ! 💡 Si vous voulez autoriser uniquement certains types de mises à jour, par exemple autoriser les mises à jour de patchs, mais pas les changements de version mineurs ou majeurs, vous pouvez utiliser l'annotation de cette façon (si vous voulez rester en 1.6) :

argocd-image-updater.argoproj.io/<alias>.update-strategy: semver:1.6.x

Il en va de même si vous souhaitez également autoriser les changements de version mineurs :

argocd-image-updater.argoproj.io/<alias>.update-strategy: semver:1.x.x

digest est la stratégie que vous pouvez utiliser pour suivre un tag mouvant. Avec cette configuration, Image Updater vérifiera si le tag est sur une nouvelle image en comparant leur digest, qui est unique. Le tag que vous souhaitez suivre doit être spécifiée dans l'annotation image-list.

argocd-image-updater.argoproj.io/image-list: <alias>=<registry-url>:<tag-to-follow>
argocd-image-updater.argoproj.io/<alias>.update-strategy: digest
argocd-image-updater.argoproj.io/<alias>.allow-tags: regexp:<expression>

Comme je l'ai déjà dit, ce ne sont pas les seules stratégies de mise à jour existantes. Il en existe aussi une qui vous permet de mettre à jour le tag avec la dernière entrée d'une liste donnée triée par ordre alphabétique, mais je ne la trouve pas très pratique.


Les charts parapluie de Helm

La configuration que je viens de vous expliquer fonctionnera parfaitement si votre chart Helm et vos values sont directement dans le même repository que votre configuration ArgoCD. Mais si vous utilisez des charts parapluie ou OTS, cela ne sera pas suffisant. Pourquoi ? Parce que le paramètre que vous voulez remplacer n'est pas image.tag mais <chart-name>.image.tag, où chart-name est le nom dans les dépendances de votre chart parapluie. Pour ce faire, Image Updater nous fournit deux autres annotations que vous pouvez configurer comme suit :

argocd-image-updater.argoproj.io/<alias>.helm.image-name: <chat-name>.image.name
 argocd-image-updater.argoproj.io/<alias>.helm.image-tag: <chat-name>.image.tag

Une fois que tout est prêt, ArgoCD Image updater pourra faire ce type de commits dans votre repository, et ArgoCD fera le reste :

ArgoCD_image_updater

💡 N.B. vous pouvez également changer le nom d'utilisateur et l'e-mail d'Image Updater dans sa configuration.

Si vous utilisez la stratégie digest, vous pouvez changer ces annotations en :

argocd-image-updater.argoproj.io/<alias>.helm.image-name: <chat-name>.image.name
argocd-image-updater.argoproj.io/<alias>.helm.image-tag: <chat-name>.image.shasum

En effet, avec cette stratégie, Image Updater ne commit pas un tag, mais le sha 256 de votre image, qui ressemble à ceci :

value: sha256:9884d406f6750a16e70a4cf7275d1e4caa4bf4320dddd17ef0b0e381a1f2bae0

Pour extraire une image avec sa somme sha 256 et non son tag, vous devez utiliser<image-url>@sha256:<something-here> and not <image-url>:<something-here>.
Et vous devez gérer cette différence dans votre chart comme suit :

image: "{{ .Values.image.repository }}{{- if .Values.image.shasum }}@{{ .Values.image.shasum }}{{- else }}:{{ .Values.image.tag | default .Chart.AppVersion }}{{- end }}"


Comment contourner Image Updater

Si vous utilisez Helm pour créer vos propres charts, cette partie peut vous intéresser. L'un des problèmes d’'Image Updater est que vous ne pourrez pas sélectionner manuellement un tag pour vos pods tant qu'il est activé pour votre application ArgoCD. Et supprimer et ajouter des annotations en permanence n'est pas une solution. C'est pourquoi j'ai trouvé utile d'ajouter une option d'OverrideTag dans mes Charts. Pour implémenter ceci dans vos modèles de pods, vous pouvez faire :

image: "{{ .Values.image.repository }}{{- if .Values.image.overrideTag }}:{{ .Values.image.overrideTag }}{{- else if .Values.image.shasum }}@{{ .Values.image.shasum }}{{- else }}:{{ .Values.image.tag | default .Chart.AppVersion }}{{- end }}"

N.B. Ici je donne la version qui gère aussi l'utilisation de la stratégie digest. Si vous n'en avez pas besoin, je vous laisse modifier cette ligne en conséquence

Ensuite, dans vos values, si vous ne spécifiez pas overrideTag, le tag sera utilisé, et Image Updater fera son travail. Sinon, si vous spécifiez overrideTag, sa valeur sera utilisée, et Image Updater ne pourra rien y faire.

Mon opinion après plusieurs mois d’utilisation

ArgoCD image updater est un outil utile qui a ses avantages, mais aussi ses inconvénients.

D'un côté :

  • Image updater est vraiment facile à mettre en place.
  • Il permet de créer une architecture plus conviviale pour les développeurs : ArgoCD est vraiment simple à utiliser, les développeurs pouvaient pratiquement gérer leur environnement. En ajoutant Image Updater, ils n'ont même pas à gérer les changements de version de l'environnement.
  • Ses multiples stratégies de mise à jour vous permettent de vous adapter à presque tous les systèmes de tagging que vous pouvez avoir.

D'un autre côté :

  • Pour l'instant, la documentation manque de clarté et peut être source de confusion.
  • Je ne recommanderais pas son utilisation pour un environnement de production. En effet, si vous avez un bug de version et que vous voulez rétrograder vos déploiements, vous devez utiliser l'overrideTag que je vous ai montré, ce qui est pratique mais un peu bricolé…
  • L'utilisation de la stratégie digest rend l'interface ArgoCD moins conviviale car elle affiche la somme sha de votre image à la place de son tag.
  • La stratégie digest doit faire 3 appels à votre API de registre de conteneur par image. Vous pourriez finir par atteindre le quota de ce nombre d’appels.
  • Image Updater fonctionne avec un cycle de vie. A intervalles réguliers (2 minutes par défaut), il recherchera les mises à jour de vos images. Mais vous ne pouvez pas déclencher cette mise à jour manuellement dans des pipelines CI/CD par exemple.

 

Bien que très utile, Image Updater est encore un outil jeune qui va évoluer rapidement, et il n'est actuellement pas adapté à tous les usages. J'espère que ce post vous a montré à quel point il est facile de configurer ArgoCD Image Updater pour votre infrastructure. 😄

La GitOps est de plus en plus utilisé. Même si son écosystème n'est pas encore mature, la société Argo fait du bon travail ! Et si vous voulez être mis à jour sur leurs derniers outils, je vous recommande de suivre notre blog 😉