Aller au contenu
Conteneurs & Orchestration medium

Distribution Helm via OCI : publier des charts sur registries modernes

35 min de lecture

logo helm

Les registries OCI (Open Container Initiative) permettent de stocker des charts Helm au même endroit que vos images Docker. Un seul registry, une seule authentification, une gestion unifiée des artefacts. Depuis Helm 3.8+, le support OCI est stable et recommandé pour les environnements de production.


Comprendre d'où vient le modèle OCI explique pourquoi il s'est imposé. Pendant des années, publier un chart voulait dire héberger un index.yaml et des archives .tgz derrière un serveur web, avec un fichier d'index à régénérer et à republier à chaque version. Le tableau se lit de haut en bas comme une chronologie ; la colonne Limitations décrit à chaque fois le problème que la génération suivante a résolu.

GénérationMécanismeLimitations
Helm 2Repos HTTP (index.yaml + tarballs)Serveur web dédié, pas de sécurité native
Helm 3Repos HTTP améliorésToujours un index.yaml à maintenir
Helm 3.8+OCI registriesMême infra que les images, authentification intégrée

Le gain principal n'est pas technique mais opérationnel : vous supprimez une infrastructure. Plus de serveur web à maintenir, plus d'index à régénérer, plus d'authentification spécifique aux charts. Deux lignes méritent une lecture attentive. L'immutabilité est native parce qu'un tag OCI pointe vers un digest, donc vous pouvez référencer un chart de façon reproductible. La découverte, en revanche, est le point faible du modèle : helm search n'expose que le Artifact Hub et les dépôts HTTP ajoutés localement, il ne sait pas parcourir un registry OCI. C'est l'API ou l'interface du registry qui joue ce rôle.

AspectRepos HTTP classiquesOCI registries
InfrastructureServeur web dédié + index.yamlVotre registry d'images existant
AuthentificationBasic auth ou tokens customMême auth que vos images Docker
ImmutabilitéDépend de votre configNative (un tag = un digest)
SignatureFichier .prov séparéCosign/Notation intégrés
Découvertehelm search repoUI ou API du registry (helm search ne couvre pas OCI)

helm registry login écrit ses identifiants dans le même fichier que Docker, ~/.docker/config.json : si vous êtes déjà authentifié avec docker login sur le registry visé, Helm en profite sans manipulation supplémentaire. Choisissez l'onglet correspondant à votre plateforme. Dans tous les cas, préférez --password-stdin : un mot de passe passé en argument atterrit dans l'historique du shell et dans la table des processus.

Fenêtre de terminal
# Login avec username/password
helm registry login harbor.example.com
# Login avec robot account (CI/CD)
helm registry login harbor.example.com \
--username 'robot$myproject+ci' \
--password-stdin < /path/to/token

La publication se joue en quatre temps, et l'ordre a son importance : un chart poussé ne se retire pas facilement d'un registry d'entreprise. La version déclarée dans Chart.yaml est la seule source du tag OCI, il n'y a pas de paramètre --tag sur helm push. Oublier de l'incrémenter est l'erreur la plus fréquente : la commande échouera si le registry interdit l'écrasement, ou remplacera silencieusement le contenu s'il l'autorise.

  1. Vérifier le chart

    Avant de publier, validez la qualité :

    Fenêtre de terminal
    helm lint ./my-chart
    helm template ./my-chart > /dev/null # Vérifie le rendu
  2. Packager le chart

    Fenêtre de terminal
    helm package ./my-chart
    # Crée my-chart-1.2.3.tgz

    La version vient de Chart.yaml :

    Chart.yaml
    apiVersion: v2
    name: my-chart
    version: 1.2.3 # Version du chart
    appVersion: "2.0.0" # Version de l'application
  3. Pousser vers le registry

    Fenêtre de terminal
    helm push my-chart-1.2.3.tgz oci://harbor.example.com/myproject

    Résultat :

    Pushed: harbor.example.com/myproject/my-chart:1.2.3
    Digest: sha256:abc123...

    Notez le digest affiché : c'est lui qu'il faut consigner si vous voulez pouvoir redéployer exactement cette version plus tard.

  4. Vérifier la publication

    Fenêtre de terminal
    helm show chart oci://harbor.example.com/myproject/my-chart --version 1.2.3

Enchaîner les trois étapes avec && garantit qu'un lint en échec arrête tout avant le push. C'est la forme à reprendre dans un job de CI. Attention au joker my-chart-*.tgz de la dernière ligne : s'il reste une archive d'une version précédente dans le répertoire, helm push recevra plusieurs fichiers. Faites le ménage ou nommez explicitement l'archive attendue.

Fenêtre de terminal
# Lint → Package → Push
helm lint ./my-chart && \
helm package ./my-chart && \
helm push my-chart-*.tgz oci://harbor.example.com/myproject

Une référence oci:// s'utilise partout où Helm attend un chart, sans avoir ajouté le moindre dépôt au préalable. Précisez toujours --version : sans elle, Helm résout la version la plus récente publiée, et votre déploiement dépendra de ce que quelqu'un aura poussé entre-temps.

Fenêtre de terminal
# Installer depuis OCI
helm install my-release oci://harbor.example.com/myproject/my-chart \
--version 1.2.3 \
-n my-namespace \
--create-namespace

Séparer le téléchargement de l'installation devient nécessaire dans deux situations : les environnements où le cluster n'a pas accès au registry, et les chaînes qui vérifient la signature du chart avant de l'appliquer. L'archive récupérée est le fichier exact publié, ce qui permet de calculer son empreinte et de la comparer à celle attendue.

Fenêtre de terminal
# Télécharger le chart
helm pull oci://harbor.example.com/myproject/my-chart --version 1.2.3
# Installer depuis le tarball local
helm install my-release ./my-chart-1.2.3.tgz -n my-namespace

Ces trois commandes ne téléchargent que les métadonnées et n'installent rien. Elles répondent aux trois questions à se poser devant un chart inconnu : quelle version d'application embarque-t-il, quelles valeurs sont modifiables, et quelles sont les instructions de l'auteur. Sur un chart tiers, helm show values est le minimum à lire avant tout déploiement.

Fenêtre de terminal
# Voir les métadonnées
helm show chart oci://harbor.example.com/myproject/my-chart --version 1.2.3
# Voir les values par défaut
helm show values oci://harbor.example.com/myproject/my-chart --version 1.2.3
# Voir le README
helm show readme oci://harbor.example.com/myproject/my-chart --version 1.2.3

La structure d'une référence OCI reprend celle d'une image de conteneur, à ceci près que la partie projet peut contenir plusieurs niveaux selon le registry. Le tableau montre deux formes valides : Harbor impose un projet à un seul niveau, GHCR accepte un chemin imbriqué sous l'organisation. Vérifiez cette contrainte avant de figer une convention d'équipe, elle n'est pas la même partout.

oci://<registry>/<project>/<chart-name>:<version>
ExempleRegistryProjectChartVersion
oci://harbor.example.com/platform/nginxharbor.example.complatformnginx(latest)
oci://ghcr.io/myorg/charts/api:2.1.0ghcr.iomyorg/chartsapi2.1.0

La version du chart suit le versionnage sémantique, avec une subtilité que ce tableau met en évidence : les métadonnées de build (ce qui suit le +) ne font pas partie de l'identité de la version et disparaissent du tag OCI. Deux builds 1.2.3+build.456 et 1.2.3+build.457 produiraient donc le même tag et s'écraseraient. Si vous générez un chart par exécution de pipeline, incluez le numéro de build dans la partie pre-release, après un tiret.

SituationVersion chartTag OCI
Release stable1.2.31.2.3
Pre-release1.2.3-rc.11.2.3-rc.1
Branche feature0.0.0-feature-xyzfeature-xyz
CI automatique1.2.3+build.4561.2.3

Un tag reste une étiquette déplaçable ; un digest est calculé sur le contenu et ne peut donc pas désigner autre chose. Référencer un chart par digest garantit que le déploiement de demain applique exactement les manifestes d'aujourd'hui, même si quelqu'un republie le tag entre-temps. C'est la forme à privilégier dans un dépôt GitOps. Le digest s'obtient dans la sortie de helm push, ou avec helm show chart qui affiche la ligne Digest: avant les métadonnées.

Fenêtre de terminal
# Référencer par digest (immuable)
helm install my-release oci://harbor.example.com/myproject/my-chart@sha256:abc123...

Tous les registries conformes à la distribution spec de l'OCI acceptent les charts, il n'y a donc pas de compatibilité à vérifier au sens strict. Ce qui diffère, c'est le format du chemin imposé par chacun et la façon dont l'interface présente les artefacts qui ne sont pas des images. La colonne « URL format » est celle que vous recopierez : une erreur de niveau de chemin produit un denied bien plus souvent qu'un vrai problème de droits.

RegistryURL formatNotes
Harboroci://harbor.example.com/projectGratuit, self-hosted, UI native pour charts
GHCRoci://ghcr.io/owner/repoIntégré à GitHub, gratuit pour public
ECRoci://123456.dkr.ecr.region.amazonaws.comAWS natif, IAM intégré
ACRoci://myregistry.azurecr.ioAzure natif
GCR/Artifact Registryoci://region-docker.pkg.dev/project/repoGoogle Cloud
Docker Huboci://registry-1.docker.io/userLimites de pull sur free tier

Les messages renvoyés par les registries sont volontairement peu bavards, pour ne pas révéler l'existence d'un dépôt à un utilisateur non autorisé. C'est pourquoi manifest unknown et denied désignent souvent la même situation vue de deux côtés : soit la référence est fausse, soit vous n'avez pas le droit de la voir. Vérifiez le chemin complet avant de demander des droits supplémentaires.

ErreurCause probableSolution
unauthorizedToken expiré ou permissions insuffisanteshelm registry logout puis login
manifest unknownChart ou version inexistantVérifier le nom et la version
denied: requested access...Pas de permission pushVérifier les droits sur le projet
Error: scheme "oci" not supportedHelm < 3.8Mettre à jour Helm

Ce lab enchaîne le cycle complet sur un chart jetable, pour vous éviter de découvrir les erreurs d'authentification sur un chart de production. Prévoyez un jeton avec la portée write:packages côté GitHub et un cluster de test accessible : la dernière étape installe réellement le chart. Le nettoyage final n'est pas optionnel, le namespace créé resterait sinon dans votre cluster.

Objectif : Packager un chart, le publier sur GHCR (ou Harbor local), puis l'installer depuis oci://.

  1. Préparer le chart

    Fenêtre de terminal
    # Utiliser un chart existant ou en créer un
    helm create my-lab-chart
    cd my-lab-chart
    # Modifier la version dans Chart.yaml
    sed -i 's/version: .*/version: 0.1.0/' Chart.yaml
  2. Se connecter au registry

    Fenêtre de terminal
    # GHCR
    echo $GITHUB_TOKEN | helm registry login ghcr.io -u $GITHUB_USERNAME --password-stdin
  3. Packager et publier

    Fenêtre de terminal
    cd ..
    helm package my-lab-chart
    helm push my-lab-chart-0.1.0.tgz oci://ghcr.io/$GITHUB_USERNAME/charts
  4. Vérifier et installer

    Fenêtre de terminal
    # Vérifier
    helm show chart oci://ghcr.io/$GITHUB_USERNAME/charts/my-lab-chart --version 0.1.0
    # Installer
    helm install test-release oci://ghcr.io/$GITHUB_USERNAME/charts/my-lab-chart \
    --version 0.1.0 \
    -n oci-lab \
    --create-namespace
  5. Nettoyer

    Fenêtre de terminal
    helm uninstall test-release -n oci-lab
    kubectl delete namespace oci-lab

Critères de réussite :

  • Chart packagé (.tgz créé)
  • Push vers registry OCI réussi
  • helm show chart oci://... affiche les métadonnées
  • Installation depuis oci:// fonctionnelle

  • OCI = standard ouvert pour stocker charts et images au même endroit
  • helm registry login = authentification (même credentials que Docker)
  • helm push = publier un chart packagé
  • helm pull / helm install oci:// = consommer depuis OCI
  • Immutabilité : ne jamais écraser un tag en production
  • Digests : utilisez @sha256:... pour la reproductibilité absolue

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn