Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Comprendre OCI : tag, digest, manifest, multi-arch et artefacts

Par mis à jour le

Améliorer cette page

Vous avez remarqué que docker pull nginx:1.25 ne télécharge pas toujours les mêmes layers ? Deux causes principales :

  1. Plateforme différente (AMD64 vs ARM64) → layers différentes (images multi-arch)
  2. Tag mutable → l'image a été rebuild/republishée

Pour comprendre ces comportements, il faut connaître le standard OCI (Open Container Initiative). Ce guide vous explique les concepts clés : tags, digests, manifests, multi-arch et artefacts.

  • OCI : le standard ouvert qui définit le format des images et registries
  • Tag vs Digest : pourquoi un tag peut changer, pas un digest
  • Manifest : le fichier JSON qui décrit une image
  • Multi-arch : comment une seule référence sert plusieurs architectures
  • Artefacts OCI : stocker des Helm charts, SBOM, signatures dans un registry

L'Open Container Initiative (OCI) est une organisation qui définit les standards ouverts pour les conteneurs :

SpécificationCe qu'elle définit
OCI ImageFormat des images (layers, config, manifest)
OCI RuntimeComment exécuter un conteneur (runc)
OCI DistributionAPI des registries (push, pull, list)

Pourquoi c'est important ? Grâce à l'OCI, une image buildée avec Docker fonctionne avec Podman, containerd, CRI-O. Un registry comme Harbor, Quay ou GHCR parle le même langage que Docker Hub.

Une image OCI est composée de 3 types d'objets, tous identifiés par leur digest (hash SHA256). C'est un système content-addressable : le contenu détermine l'identifiant, pas l'inverse.

Dans le schéma, suivez les flèches depuis le tag : il pointe vers le manifest, qui référence à son tour la config et chaque layer par leur digest.

Dans un registry OCI, le tag nginx:1.25 pointe vers le manifest, qui référence par leur digest la config (ENV, CMD, USER, EXPOSE) et les layers (base, application) ; chaque objet est identifié par son SHA256.OCI RegistryTagnginx:1.25digest = sha256:…hash du manifest, immuableManifestmediaType, config, layersConfigsha256:aaa…LayersContent-addressable :chaque objet est identifié par son SHA256Layer 1sha256:bbb… (base)Layer 2sha256:ccc… (app)Layer Nsha256:ddd…config: sha256:aaalayers: sha256:bbb, sha256:ccc
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %
ObjetContenuIdentifiant
ManifestRéférence vers config + layerssha256:xxx...
ConfigMétadonnées (env, cmd, user, ports)sha256:yyy...
LayersFichiers de chaque couche (tar.gz)sha256:zzz...

Le digest d'une image = le hash SHA256 de son manifest. Si le manifest change (même légèrement), le digest change.

Contrairement aux URLs classiques (location-addressable), OCI utilise un adressage par contenu :

ApprocheExempleCaractéristique
Location-addressablehttps://example.com/image.tarMême URL, contenu peut changer
Content-addressablesha256:abc123...Même hash = même contenu garanti

Avantages du content-addressable :

  • Déduplication : layers identiques partagés entre images
  • Vérification : intégrité vérifiable par recalcul du hash
  • Immutabilité : un digest référence toujours le même contenu

Un tag est un nom lisible qui pointe vers un manifest. Le même tag peut pointer vers des manifests différents au fil du temps.

Fenêtre de terminal
# Aujourd'hui
nginx:1.25 → sha256:abc123...
# Demain (après un rebuild)
nginx:1.25 → sha256:def456... # Différent !

C'est comme un signet : il pointe vers une page, mais vous pouvez le déplacer.

Un digest est le hash SHA256 du manifest. Il identifie une version exacte de l'image, de manière permanente.

Fenêtre de terminal
# Toujours la même image, pour toujours
nginx@sha256:6926dd802f40e5e7257fded83e0d8030039642e4e10c4a98a6478e9c6fe06153

C'est comme une empreinte digitale : elle ne change jamais pour une personne donnée.

ContexteUtiliserExemple
Développement localTagnginx:1.25
CI/CD (publication)Tag versionné + capturer digestmon-app:1.2.3 → sha256:abc...
Production (deploy)Digestmon-app@sha256:abc...
Audit / complianceDigestTraçabilité exacte
Dockerfile FROMTag ou digest selon criticitéFROM alpine:3.19 ou FROM alpine@sha256:...

Règle d'or : en production, pinnez par digest, pas par tag. Un tag versionné comme v1.2.3 n'est pas pour autant immuable : il peut être republié, sauf si le registry l'interdit par une politique.

Le workflow recommandé pour garantir la traçabilité :

Fenêtre de terminal
# 1. Build et push avec un tag
docker buildx build --tag ghcr.io/mon-org/mon-app:v1.2.3 --push .
# 2. Capturer le digest depuis le registry
DIGEST=$(crane digest ghcr.io/mon-org/mon-app:v1.2.3)
echo "Built: ghcr.io/mon-org/mon-app@${DIGEST}" >> release-metadata.txt
# 3. Déployer par digest (immuable)
kubectl set image deployment/mon-app \
app=ghcr.io/mon-org/mon-app@${DIGEST}

Ce pattern sépare publication (tag pour les humains) et déploiement (digest pour la reproductibilité).

Le manifest est un fichier JSON qui décrit une image. Il contient :

  • Le digest de la config (métadonnées)
  • La liste des layers avec leurs digests et tailles
  • Le media type (format)
{
"schemaVersion": 2,
"mediaType": "application/vnd.oci.image.manifest.v1+json",
"config": {
"mediaType": "application/vnd.oci.image.config.v1+json",
"digest": "sha256:aaa...",
"size": 1234
},
"layers": [
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:bbb...",
"size": 5678
},
{
"mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
"digest": "sha256:ccc...",
"size": 9012
}
]
}

Les registries supportent deux formats de manifests. En pratique, la plupart des outils gèrent les deux de manière transparente.

FormatMedia type manifestUsage
Docker v2application/vnd.docker.distribution.manifest.v2+jsonLegacy, Docker Hub historique
OCIapplication/vnd.oci.image.manifest.v1+jsonStandard actuel, recommandé

Voir le manifest d'une image :

Fenêtre de terminal
# Avec crane
crane manifest nginx:1.25 | jq .
# Avec skopeo
skopeo inspect --raw docker://nginx:1.25 | jq .

Multi-arch : une référence, plusieurs architectures

Section intitulée « Multi-arch : une référence, plusieurs architectures »

Comment docker pull nginx télécharge-t-il la bonne version pour votre CPU (AMD64 ou ARM64) ? Grâce au manifest list (ou OCI image index).

Un manifest list est un manifest spécial qui contient des références vers plusieurs manifests, un par architecture.

Le schéma suit un docker pull : le client lit la manifest list, retient le manifest de sa plateforme (les autres restent en pointillés), puis télécharge les layers correspondants.

Résolution multi-architecture : le client linux/amd64 demande nginx:1.25, reçoit la manifest list, choisit le manifest amd64 parmi amd64, arm64 et arm/v7, télécharge ses layers et obtient l'image locale ; docker buildx crée la manifest list.① GET② choix de la plateforme③ pull④ image localecrée la manifest listClientlinux/amd64Manifest listnginx:1.25Manifest amd64layers spécifiquesManifest arm64layers spécifiquesManifest arm/v7layers spécifiquesLayers amd64layer1.tar.gz, layer2.tar.gzImage localeprête à lancerdocker buildx build--platform …
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Quand vous faites docker pull nginx:1.25 :

  1. Docker télécharge le manifest list
  2. Il identifie votre architecture (ex: linux/amd64)
  3. Il télécharge le manifest spécifique à votre architecture
  4. Il télécharge les layers correspondants
Fenêtre de terminal
# Créer un builder multi-plateforme
docker buildx create --name multi-arch --driver docker-container --use
# Builder et pusher pour AMD64 + ARM64
docker buildx build \
--platform linux/amd64,linux/arm64 \
--tag mon-registry/mon-app:v1.0 \
--push .
# Vérifier les architectures disponibles
docker manifest inspect mon-registry/mon-app:v1.0
Fenêtre de terminal
# Avec docker manifest
docker manifest inspect nginx:1.25
# Avec crane
crane manifest nginx:1.25 | jq '.manifests[] | {platform, digest}'
# Résultat
{
"platform": { "architecture": "amd64", "os": "linux" },
"digest": "sha256:amd123..."
}
{
"platform": { "architecture": "arm64", "os": "linux" },
"digest": "sha256:arm123..."
}

Les registries OCI peuvent stocker d'autres types d'artefacts que des images de conteneurs :

ArtefactCas d'usageOutil
Helm chartsPackages Kuberneteshelm push
SBOMListe des composants logicielsORAS, Syft
SignaturesAttestation d'origineCosign, Notation
PoliciesRègles OPA/RegoConftest
WASM modulesWebAssemblyORAS

Depuis mars 2024, les specs OCI 1.1 permettent d'associer des artefacts à une image via le champ subject. Cela résout un problème majeur : comment savoir quels SBOM, signatures et attestations sont liés à une image ?

Dans le schéma, chaque artefact (signature, SBOM, attestation, rapport de vulnérabilités) pointe vers l'image par son champ subject, et la Referrers API les liste tous à partir du digest de l'image.

La Referrers API (OCI 1.1) retrouve, à partir du digest d'une image, les artefacts qui la visent par leur champ subject : signature Cosign, SBOM, attestation de provenance SLSA et rapport de vulnérabilités.subjectsubjectsubjectsubjectImagemyapp:v1.0sha256:abc123…SignatureCosignSBOMSPDX / CycloneDXAttestationprovenance SLSARapport de vulnérabilitésTrivy / GrypeReferrers APIGET /v2/‹name›/referrers/‹digest›liste tous les artefacts liés
Source · SVG
Échap pour fermer, + et − pour zoomer, défilement pour se déplacer. 100 %

Fonctionnement :

  1. L'artefact (signature, SBOM...) contient un champ subject avec le digest de l'image cible
  2. Le registry indexe automatiquement cette relation
  3. L'API GET /v2/<name>/referrers/<digest> retourne tous les artefacts liés
Fenêtre de terminal
# Lister les artefacts liés à une image (avec ORAS)
oras discover ghcr.io/mon-org/mon-app:v1.0
# Résultat typique
ghcr.io/mon-org/mon-app@sha256:abc123
├── application/vnd.dev.cosign.simplesigning.v1+json (signature)
├── application/spdx+json (SBOM)
└── application/vnd.in-toto+json (attestation SLSA)

ORAS (OCI Registry As Storage) est un outil et une spécification pour pousser/puller n'importe quel fichier vers un registry OCI.

Fenêtre de terminal
# Pousser un fichier quelconque
oras push ghcr.io/mon-org/configs:v1 config.yaml:application/yaml
# Puller le fichier
oras pull ghcr.io/mon-org/configs:v1
# Pousser un SBOM généré par Syft, lié à une image (OCI 1.1)
syft nginx:1.25 -o spdx-json > sbom.json
oras push ghcr.io/mon-org/sboms:nginx-1.25 \
--artifact-type application/spdx+json \
--subject ghcr.io/mon-org/nginx@sha256:abc... \
sbom.json:application/spdx+json

Pourquoi c'est utile ?

  • Un seul système pour stocker images, configs, SBOM, signatures
  • Même authentification que pour les images
  • Même réplication entre registries
  • Associer un SBOM ou une signature à une image via son digest
OutilForcesInstallation
craneLéger, rapide, API Go réutilisablego install github.com/google/go-containerregistry/cmd/crane@latest
skopeoCopie entre registries, air-gapPackage système (apt, dnf)
regctlNettoyage de tags, garbage collectiongo install github.com/regclient/regclient/cmd/regctl@latest
orasArtefacts génériques, Referrers APIgo install oras.land/oras/cmd/oras@latest
Fenêtre de terminal
# Copier une image entre registries (sans Docker daemon)
skopeo copy docker://nginx:1.25 docker://mon-registry/nginx:1.25
# Supprimer un tag (attention : irréversible)
crane delete mon-registry/mon-app:old-tag
# Explorer les layers d'une image
crane export nginx:1.25 - | tar -tvf - | head -20

Chaque outil du tableau a son guide : ORAS pour manipuler des artefacts OCI, Skopeo pour inspecter et copier des images sans daemon, et Crane, la CLI de Google pour manipuler des images OCI. La stratégie de tags, le cache, le multi-arch et la promotion d'une image d'un environnement à l'autre sont traités dans CI/CD d'images. Maintenant que le format OCI est clair, la supply chain des images (SBOM, scan, signature) en tire les bases DevSecOps pour des images de confiance.

  1. OCI = standard ouvert pour images et registries (interopérabilité Docker/Podman/containerd)
  2. Tag = alias mutable vers un manifest (peut changer) → développement
  3. Digest = hash SHA256 immutable du manifest → production, audit
  4. Content-addressable = l'identifiant est le hash du contenu → déduplication, vérification
  5. Manifest = JSON qui liste config + layers avec leurs digests
  6. Manifest list = index multi-arch qui pointe vers un manifest par architecture
  7. OCI 1.1 (mars 2024) = Referrers API pour lier signatures, SBOM, attestations aux images
  8. ORAS = stocker n'importe quel artefact (SBOM, signatures, configs) dans un registry OCI
  9. Outils : crane (léger), skopeo (copie), regctl (nettoyage), oras (artefacts)

Vérifions que vous avez assimilé les concepts OCI essentiels : tags vs digests, manifests, multi-arch et artefacts.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

7 questions
5 min.
80% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn