Repository navigation
Conversation
omiladi
force-pushed
the
chore/upgrade-argocd
branch
from
September 21, 2026 13:27
9a610a6 to
8dc5b54
Compare
omiladi
marked this pull request as ready for review
September 21, 2026 13:34
KepoParis
force-pushed
the
chore/upgrade-argocd
branch
from
October 7, 2026 12:56
8dc5b54 to
2c31c7e
Compare
Bumps the workload-cluster ArgoCD release from chart 8.5.6 (ArgoCD v3.1.7) to 10.7.2 (v3.5.2), a chain of minor releases within the same major line (3.x). argocdInfra is out of scope (not managed here). Reviewed against the official upgrade guides (3.1->3.2, 3.2->3.3, 3.3->3.4, 3.4->3.5): none of the breaking changes touch our config (RBAC policy.csv, oidc.config, resource.exclusions, OCI/Harbor repo auth). timeout.reconciliation default drops 180s->120s (not overridden here, more frequent reconciliation, non-breaking). Operational note for rollout: the ApplicationSet CRD now exceeds the client-side apply size limit (breaking change in 3.3), may need server-side apply with --force-conflicts on first sync since ArgoCD manages its own CRDs here when crds.install: true (argo_infra_ownership is false on this release).
…n 3.3 The repo-server carried a custom `helm-login` initContainer that copied the helm binary out of the Argo CD image, wrapped it in a bash script and mounted that wrapper over /usr/local/bin/helm. It was introduced in f62a90c (April 2025) to work around two Argo CD limitations, both of which are now fixed upstream. 1. The wrapper rewrote argv[3] of `helm registry login`. In Argo CD v3.1.7 (util/helm/cmd.go:79) RegistryLogin appended the full repository URL: args := []string{"registry", "login"} args = append(args, repo) With our `oci-dockerhub-creds` secret (url: registry-1.docker.io, name: bitnamicharts) that produced `helm registry login registry-1.docker.io/bitnamicharts`, which helm rejects because it wants a registry host, not a host+path. Argo CD 3.3 added getHelmRegistry(), whose own doc comment states the intent verbatim: "extracts the registry host from a Helm repository URL. This is because it is required for the `helm registry login` command to use the registry host rather than the full URL." Verified absent in v3.2.6, present in v3.3.9, v3.4.6 and v3.5.2. 2. The initContainer also ran an eager `helm registry login` into /helm-working-dir (HELM_CONFIG_HOME, shared with the repo-server) so that `helm dependency build` could authenticate for tenant charts depending on oci://registry-1.docker.io/bitnamicharts/*. Argo CD does this itself now: DependencyBuild() (util/helm/helm.go:80 in v3.5.2) walks every configured repository and calls RegistryLogin/RegistryLogout around the dependency build for each OCI repo that has a username and password. Keeping the shim across this bump would actively hurt. The chart moves to Argo CD v3.5.2, which bundles Helm 4.2.1, and 3.5 changed the invocation to `--password-stdin` plus a conditional `--plain-http`. Those calls would be funnelled through a bash wrapper written for the Helm 3 signature, expanding arguments through an unquoted ${args[@]}, with a copied binary shadowing the real one. That is new risk taken on to work around a bug that no longer exists. Docker Hub authentication is unchanged: it now flows solely through the `oci-dockerhub-creds` repo-creds secret, which is rendered unconditionally in repo-creds.yml.j2 and reads the same Vault dockerAccount path. Repo-server proxy variables are unaffected, they come from 10-proxy.j2 (repoServer.env: *extraEnvVars), not from the initContainer.
The `helm-login` initContainer removed in the previous commit was the only consumer of this Secret: it read username/password from it into HELM_USER and HELM_PASSWORD. With the shim gone nothing references it, in this role or in the generated gitops repositories. Leaving it in place would keep a second copy of the Docker Hub credentials sitting in the Argo CD namespace for no reason. The credentials are already available to Argo CD through `oci-dockerhub-creds` in repo-creds.yml.j2, which reads the very same Vault path (global/values#dockerAccount). Note for rollout: the Argo CD Applications that deploy this chart run with prune enabled, so the Secret is removed from the clusters on the first sync after this change.
argo-cd chart 10.0.0 flips global.networkPolicy.create from false to true. That is a sensible upstream default, but it is a network posture change that has nothing to do with the version bump, and it would land on every managed cluster in the same sync as four minor Argo CD releases. If a flow breaks we want to know whether it is the upgrade or the policies. Checked on the cpin-console-hp cluster: the dso-argocd namespace has no NetworkPolicy and no CiliumNetworkPolicy today, so this would go from unrestricted to filtered in one step. Pinned back to false here, with the flows to validate documented in the template so enabling it later is a small, reviewable change. Operators can still opt in per environment through dsc.argocd.values, which the combine role merges last. Rendered chart 10.7.2 with our values: 4 NetworkPolicies without this file, 0 with it.
KepoParis
force-pushed
the
chore/upgrade-argocd
branch
from
October 8, 2026 16:22
2c31c7e to
c487fd9
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Issues liées
Issues numéro : #1098
Quel est le comportement actuel ?
Le release Argo CD du cluster workload est sur le chart 8.5.6 (Argo CD v3.1.7).
Le repo-server embarque un initContainer maison
helm-loginqui remplace le binaire helm par un wrapper bash, et un Secrethelm-docker-registry-secretqui porte les credentials Docker Hub pour ce wrapper.Aucune NetworkPolicy n'existe dans le namespace Argo CD.
Quel est le nouveau comportement ?
Bump du chart Argo CD du cluster workload de 8.5.6 (v3.1.7) à 10.7.2 (v3.5.2), soit une chaîne de releases mineures au sein de la même ligne majeure (3.x).
argocdInfraest hors périmètre : il reste en 8.5.6 et sera traité séparément.Trois ajustements de nos templates accompagnent le bump, un par commit pour que la review se fasse commit par commit :
chore(upgrade-argocd)releases.yamlargocd.chartVersion8.5.6 → 10.7.2refactor(argocd)values/00-main.j2helm-loginrefactor(argocd)templates/helm-docker-registry-secret.yml.j2chore(argocd)values/10-networkpolicy.j2global.networkPolicy.createrepassé àfalseLe détail et la justification de chaque décision sont en fin de description.
Cette PR introduit-elle un breaking change ?
Pas pour la configuration de ce repo. Oui pour le rollout, sur un point précis.
1. Le Deployment haproxy de
redis-hadoit être recréé à la main. Le chart 9.1.0 ajoutecomponent: haproxyauselector.matchLabelsdu Deployment<release>-redis-ha-haproxy. Un selector de Deployment est immuable : le sync échouera surfield is immutabletant que l'ancien objet n'est pas supprimé. Procédure détaillée plus bas. Pas de coupure Redis : leServicehaproxy sélectionne surapp+releaseuniquement, sanscomponent, avant comme après — les anciens pods orphelins et les nouveaux servent le trafic en parallèle le temps de la bascule.2. La CRD
ApplicationSetdépasse la limite d'un apply client-side (1,03 Mo → 1,39 Mo, breaking change de la 3.3). Vérifié sur cluster : nos Applications synchronisent déjà avecServerSideApply=true, et la CRD en place ne porte aucune annotationlast-applied-configuration(0 octet, unique field manager :argocd-controller / Apply). Le cas est donc déjà couvert. En cas de 409 au premier sync, ajouter ponctuellementForce=true.3. Point d'attention hors breaking change : le défaut
timeout.reconciliationpasse de 180s à 120s, avec un jitter de 60s. Nous ne le surchargeons pas, donc nous héritons du nouveau défaut : environ 50 % de réconciliations en plus. Volontairement non figé dans cette PR — c'est un arbitrage de charge, voir la question ouverte en fin de description.Autres informations
Journal des décisions
Le bump lui-même
argo_app_versionn'est codé en dur nulle part :roles/gitops/rendering-apps-files/tasks/preliminary.ymlle dérive de la version de chart.Toutes les images qui s'appuient dessus suivent donc automatiquement le chart. C'est ce qui rend le point suivant nécessaire.
Suppression du shim
helm-login— la version longueLe repo-server portait un initContainer maison qui copiait le binaire helm hors de l'image Argo CD, l'enrobait d'un script bash, et montait ce wrapper par-dessus
/usr/local/bin/helm. Il a été introduit par f62a90c (avril 2025) et il n'était pas gratuit : il réglait deux vrais problèmes.Problème A —
helm registry loginrecevait un chemin au lieu d'un hôte. Argo CD v3.1.7,util/helm/cmd.go:79:Notre secret
oci-dockerhub-credsvauturl: registry-1.docker.io+name: bitnamicharts, ce qui produisaithelm registry login registry-1.docker.io/bitnamicharts. Helm refuse : il attend un hôte de registre, pas un hôte + chemin. Le wrapper interceptait exactement cette forme d'argv et la réécrivait en hôte nu.Problème B — les builds de dépendances n'avaient pas les credentials. L'initContainer faisait aussi un
helm registry loginanticipé dans/helm-working-dir(HELM_CONFIG_HOME, partagé avec le repo-server) pour quehelm dependency buildpuisse s'authentifier sur les charts tenants dépendant deoci://registry-1.docker.io/bitnamicharts/*.Les deux sont corrigés en amont aujourd'hui.
Problème A — Argo CD 3.3 a ajouté
getHelmRegistry(), dont le commentaire décrit mot pour mot ce que fait notre wrapper :Vérifié : absent en
v3.2.6, présent env3.3.9,v3.4.6,v3.5.2. En v3.5.2,RegistryLogindevient :Problème B —
DependencyBuild()(util/helm/helm.go:80, v3.5.2) parcourt tous les dépôts configurés et encadre le build de dépendances par unRegistryLogin/RegistryLogoutpour chaque dépôt OCI disposant d'un username et d'un password. Notreoci-dockerhub-credsremplit la condition.Et le conserver deviendrait nuisible. Le chart passe à Argo CD v3.5.2, qui embarque Helm 4.2.1. La 3.5 a aussi changé l'invocation :
--password-stdinau lieu de--password, plus un--plain-httpconditionnel. Ces appels transiteraient par un script bash écrit pour la signature Helm 3, avec une expansion d'arguments en${args[@]}non quoté et un binaire copié qui masque le vrai. C'est du risque nouveau, pris pour contourner un bug qui n'existe plus.Périmètre d'impact. L'authentification Docker Hub est inchangée : elle passe désormais uniquement par
oci-dockerhub-creds, rendu inconditionnellement dansrepo-creds.yml.j2, qui lit le même chemin VaultdockerAccount. Les variables de proxy du repo-server ne bougent pas : elles viennent de10-proxy.j2(repoServer.env: *extraEnvVars), jamais de l'initContainer.Suppression de
helm-docker-registry-secretL'initContainer en était le seul consommateur : il en lisait username/password vers
HELM_USER/HELM_PASSWORD. Le shim retiré, plus rien ne le référence — ni dans ce rôle, ni dans les repos gitops générés (vérifié par grep sur les deux). Le laisser maintiendrait une copie redondante des credentials Docker Hub dans le namespace Argo CD, alors qu'ils sont déjà exposés à Argo CD paroci-dockerhub-creds, qui lit le même chemin Vault.Note de rollout : les Applications qui déploient ce chart tournent avec
pruneactivé, le Secret disparaît donc des clusters au premier sync.Commit isolé volontairement, pour pouvoir le
revertseul si l'on préfère conserver le Secret.NetworkPolicies laissées désactivées
Le chart 10.0.0 bascule
global.networkPolicy.createdefalseàtrue. Le défaut amont est sain, mais c'est un changement de posture réseau sans rapport avec le bump de version, et il atterrirait sur tous les clusters gérés dans le même sync que quatre releases mineures d'Argo CD. Si un flux casse ensuite, on veut savoir laquelle des deux causes est en jeu.Constaté sur cluster : le namespace Argo CD n'a aujourd'hui aucune NetworkPolicy ni CiliumNetworkPolicy. On passerait donc de « tout ouvert » à « filtré » en une étape.
Repassé à
falsedans un10-networkpolicy.j2dédié, avec les flux à valider documentés en commentaire dans le template, pour que l'activation ultérieure soit un diff court et relisible. Un opérateur peut toujours l'activer par environnement viadsc.argocd.values, que le rôlecombinefusionne en dernier.Mesuré : le rendu du chart 10.7.2 avec nos values produit 4 NetworkPolicies sans ce fichier, 0 avec.
Pour mémoire, ce que le chart poserait si on l'activait : le
argocd-serverreste eningress: [{}]donc non restreint, les ports metrics restent scrapables depuis n'importe quel namespace, et le seul vrai resserrage porte sur le gRPC du repo-server, limité à server / application-controller / applicationset-controller.Revue des breaking changes amont (3.1 → 3.5)
Chacun confronté à ce que nous configurons réellement :
configs.paramsretirésapplicationsetcontroller.policypasse desyncà non défini, orsyncest le défaut du contrôleur lui-mêmeredis-haincompatible avec l'immuabiliténetworkPolicy.createàtrueServerSideApply=trueet aucune annotationlast-applied-configurationsur la CRD en placevMajor.Minor.PatchMissingdex.enabled: false, on attaque Keycloak en OIDC directinsecureOCIForceHttpnécessaireknown_hostsSSH pour les dépôts sans credentialssignatureKeysnulle partdestinationServiceAccountsconfiguréargocd-cm—timeout.reconciliation180s → 120s + jitter 60sÉtape manuelle au rollout : haproxy
redis-haPar cluster, une fois que le sync a échoué sur
field is immutable:Ne pas chercher à désactiver
ServerSideDiffsur l'Application au préalable, comme le suggère la note amont : l'annotation provient de l'ApplicationSet, elle-même pilotée en GitOps, donc tout patch est réécrit. L'orphelinage suffit.Vérifications effectuées
Servicehaproxy confirmé identique entre les deux versions — d'où l'absence de coupure.last-applied-configurationet field managers).getHelmRegistrybisectée surv3.2.6/v3.3.9/v3.4.6/v3.5.2.repoServerne porte plus quereplicas: 3.Ce que les relecteurs devraient regarder en premier
getHelmRegistry()(3.3+) et surDependencyBuild()qui fait lui-même le registry login. C'est de la lecture de code amont, pas une exécution : à valider sur un cluster de test en synchronisant un chart tenant qui tire une dépendanceoci://registry-1.docker.io/bitnamicharts/*, avant d'aller en production.timeout.reconciliationà 120s : on accepte la charge supplémentaire, ou on le refige à 180s dans00-main.j2?