virli/tutorial/docker-internals/registry.md

199 lines
5.4 KiB
Markdown
Raw Normal View History

2020-09-14 13:46:13 +00:00
\newpage
Registres d'images
==================
Regardons d'un peu plus près les registres d'images OCI. Ce sont eux qui
distribuent les images OCI et permettent à Docker de récupérer très facilement
de nouveaux services.
Dans les sections à venir, nous allons essayer de récupérer la configuration et
les couches de quelques images courantes (Debian, Ubuntu, `hello-world`, ...) :
dans un premier temps en nous préoccupant simplement de la couche la plus basse
(le système de baase). Puis nous verrons dans le chapitre suivant comment gérer
les autres couches.
## Authentification
L'authentification est facultative et est laissée à l'appréciation du
fournisseur de service. Étant donné que nous allons utiliser le [Docker
Hub](https://hub.docker.com/), le registre par défaut de `docker`, nous allons
2022-10-18 14:40:31 +00:00
devoir nous plier à son mécanisme d'authentification : chaque requête au
2020-09-14 13:46:13 +00:00
registre doit être effectuée avec un jeton, que l'on obtient en s'authentifiant
auprès d'un service dédié. Ce service peut délivrer un jeton sans authentifier
2022-02-24 19:43:43 +00:00
l'interlocuteur, en restant anonyme ; dans ce cas, on ne pourra accéder qu'aux
images publiques. Ça tombe bien, c'est ce qui nous intéresse !
2022-02-24 19:43:43 +00:00
Il n'en reste pas moins que le jeton est forgé pour un service donné (ici
`registry.docker.io`) et avec un objectif bien cerné (pour nous, on souhaite
récupérer le contenu du dépôt[^quiddepot] `hello-world` : <span
lang="en-US">`repository:hello-world:pull`</span>). Ce qui nous donne :
[^quiddepot]: Dans un registre, les fichiers qui composent l'image forment un
dépôt (*repository*).
<div lang="en-US">
```
2022-05-04 09:18:16 +00:00
42sh$ curl "https://auth.docker.io/token?service=registry.docker.io&" \
2020-09-14 13:46:13 +00:00
"scope=repository:library/hello-world:pull" | jq .
2018-11-15 22:38:25 +00:00
```
```json
{
"token": "lUWXBCZzg2TGNUdmMy...daVZxGTj0eh",
"access_token": "eyJhbGciOiJSUzI1NiIsI...N5q469M3ZkL_HA",
"expires_in": 300,
"issued_at": "2012-12-12T12:12:12.123456789Z"
}
```
</div>
C'est le `token` qu'il faudra fournir lors de nos prochaines requêtes au
registre.
2021-09-23 00:55:18 +00:00
Avec `jq`, on peut l'extraire grâce à :
<div lang="en-US">
2022-11-15 21:34:03 +00:00
```
| jq -r .token
```
</div>
2022-02-24 19:43:43 +00:00
::::: {.warning}
Le token expire ! Pensez à le renouveler régulièrement.
:::::
2020-09-14 13:46:13 +00:00
En cas d'erreur inexplicable, vous pouvez ajouter un `-v` à la ligne de
commande `curl`, afin d'afficher les en-têtes. Prêtez une attention toute
particulière à `Www-Authenticate`.
## Lecture de l'index d'images
Une fois en possession de notre jeton, nous pouvons maintenant demander l'index
2021-09-23 00:55:18 +00:00
d'images à notre registre :
<div lang="en-US">
```bash
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: application/vnd.docker.distribution.manifest.list.v2+json" \
"https://registry-1.docker.io/v2/library/hello-world/manifests/latest" | jq .
```
</div>
Parmi la liste des *manifests* retournés, nous devons récupérer le `digest`
correspondant au système qui correspond à votre architecture et notre
système. Dans tout l'écosystème OCI, les `digest` servent à la fois de chemin
d'accès et de somme de contrôle.
2022-10-18 14:40:31 +00:00
## Lecture du *manifest*
2022-10-18 14:40:31 +00:00
Demandons maintenant le *manifest* correspondant à notre matériel et à notre
2021-09-23 00:55:18 +00:00
système d'exploitation :
<div lang="en-US">
```bash
curl -s \
-H "Authorization: Bearer ${TOKEN}" \
-H "Accept: ${MEDIATYPE}" \
2022-05-04 09:18:16 +00:00
"https://registry-1.docker.io/v2/library/hello-world/manifests/
${MNFST_DGST}"
```
</div>
2022-10-18 14:40:31 +00:00
Nous voici donc maintenant avec le *manifest* de notre image. Nous pouvons
constater qu'il n'a bien qu'une seule couche. Ouf, ça va simplifier les
choses !
## Récupération de la configuration et de la première couche
Les deux éléments que l'on cherche maintenant à récupérer vont se trouver dans
le répertoire `blobs` de notre dépôt. Il ne s'agira plus de *manifest*, mais
bien des fichiers définitifs.
Récupérons la configuration de l'image comme ceci :
<div lang="en-US">
```bash
curl -s --location \
-H "Authorization: Bearer ${TOKEN}" \
2022-05-04 09:18:16 +00:00
"https://registry-1.docker.io/v2/library/hello-world/blobs/${CNF_DIGEST}"
```
</div>
Remarquez l'usage de l'option `--location` de `curl` : si les *manifests* sont
toujours stockés par le registre lui-même, les *blobs* peuvent être délégués à
un autre service, par exemple dans le cloud, chez Amazon S3, un CDN, etc. Sans
l'option `--location`, notre `curl` va retourner une redirection vers une autre
adresse, celle qui contient effectivement la configuration. Il en sera de même
pour les fichiers stockant les couches.\
Enfin d'autre part, armé du `digest` de notre couche, il ne nous reste plus
qu'à la demander gentiment :
<div lang="en-US">
```bash
wget --header "Authorization: Bearer ${TOKEN}" \
2022-05-04 09:18:16 +00:00
"https://registry-1.docker.io/v2/library/hello-world/blobs/${LAYER_DGST}"
```
</div>
## Extraction
2022-10-18 14:40:31 +00:00
Le type indiqué par le *manifest* pour cette couche était :
2022-02-24 19:43:43 +00:00
application/vnd.docker.image.rootfs.diff.tar.gzip
Il s'agit donc d'une tarball compressée au format gzip :
<div lang="en-US">
```bash
mkdir rootfs
tar xzf ${DL_LAYER} -C rootfs
```
</div>
2022-11-16 19:22:54 +00:00
Et voilà, nous avons extrait notre première image, nous devrions pouvoir entrer
dedans :
<div lang="en-US">
2022-11-15 21:34:03 +00:00
```
42sh# chroot rootfs /hello
Hello from Docker!
[...]
```
</div>
::::: {.exercice}
2022-10-18 14:40:31 +00:00
#### Assemblage {-}
2021-09-23 00:55:18 +00:00
Réalisez un script pour automatiser l'ensemble de ces étapes :
<div lang="en-US">
2022-11-15 21:34:03 +00:00
```
42sh$ cd $(mktemp -d)
2018-11-15 22:38:25 +00:00
2022-10-24 09:23:53 +00:00
42sh$ ./registry_play library/hello-world:latest
2018-11-15 22:38:25 +00:00
42sh$ find
.
./rootfs
./rootfs/hello
2018-11-15 22:38:25 +00:00
42sh# chroot rootfs /hello
Hello from Docker!
[...]
```
</div>
2020-09-14 13:46:13 +00:00
:::::