All checks were successful
continuous-integration/drone/push Build is passing
129 lines
5.2 KiB
Markdown
129 lines
5.2 KiB
Markdown
\newpage
|
||
|
||
Open Container Initiative
|
||
=========================
|
||
|
||
Formée en juin 2015, l'Open Container Initiative (OCI) a pour but d'établir le
|
||
standard commun aux programmes de contenerisation, afin d'éviter une
|
||
fragmentation de l'écosystème.
|
||
|
||
## Spécifications
|
||
|
||
Trois spécifications ont été écrites :
|
||
|
||
- [`runtime-spec`](https://github.com/opencontainers/runtime-spec/blob/master/spec.md#platforms): définit les paramètres du démarrage d'un conteneur ;
|
||
- [`image-spec`](https://github.com/opencontainers/image-spec/blob/master/spec.md): définit la construction, le transport et la préparation des images ;
|
||
- [`distribution-spec`](https://github.com/opencontainers/distribution-spec/blob/master/spec.md): définit la manière dont sont partagées et récupérées les images.
|
||
|
||
|
||
### `runtime-spec`
|
||
|
||
`runc` est l'implémentation de cette spécification ; elle a été extraite de
|
||
`docker`, puis donnée par Docker Inc. à l'OCI.
|
||
|
||
Pour démarrer un conteneur, la spécification indique qu'il est nécessaire
|
||
d'avoir un fichier de configuration `config.json` ainsi qu'un dossier où l'on
|
||
peut trouver la racine de notre conteneur.
|
||
|
||
Le plus gros de la spécification concerne le format de ce fichier de
|
||
configuration : il contient en effet l'ensemble des paramètres avec lesquels il
|
||
faudra créer le conteneur : tant d'un point de vue isolement (on peut par
|
||
exemple choisir de quel *namespace* on souhaite se dissocier, ou le(s)quel(s)
|
||
rejoindre), quelles *capabilities* resteront disponibles, quels nouveaux points
|
||
de montages, ... Voir [la
|
||
suite](https://github.com/opencontainers/runtime-spec/blob/master/config.md).
|
||
|
||
Aujourd'hui, `docker` utilise `runc` pour l'étape de lancement du conteneur,
|
||
après avoir téléchargé l'image puis mis en place l'empilement de couches dans
|
||
un répertoire prédéterminé. `docker` ne lance donc plus de conteneur à
|
||
proprement parler, il fait seulement en sorte d'atteindre l'état voulu par
|
||
cette spécification, avant de passer la main à `runc`.
|
||
|
||
::::: {.question}
|
||
|
||
##### Si `docker` fait appel à un programme externe pour lancer effectivement nos conteneurs, c'est que l'on peut changer cette implémentation ? {-}
|
||
|
||
<!-- https://ops.tips/blog/run-docker-with-forked-runc/ -->
|
||
|
||
Oui ! Et il n'y a même pas besoin de faire beaucoup d'efforts, car c'est une
|
||
possibilité qui est offerte au travers d'une option du daemon Docker. Le
|
||
binaire doit simplement avoir la même interface de ligne de commande que `runc`
|
||
(les arguments `create` et `start`, nous les verrons plus tard).
|
||
|
||
Pour l'ajouter, il convient de passer l'option suivante au daemon Docker lors
|
||
de son lancement (dans le fichier de service `systemd`, ou d'`init`) :
|
||
|
||
<div lang="en-US">
|
||
```sh
|
||
/usr/bin/dockerd [...] --add-runtime=my-runtime=/usr/local/bin/my-runtime
|
||
```
|
||
</div>
|
||
|
||
Ou bien en passant par le fichier de configuration `/etc/docker/daemon.json` :
|
||
|
||
<div lang="en-US">
|
||
```json
|
||
{
|
||
"runtimes": {
|
||
"my-runtime": {
|
||
"path": "/usr/local/bin/my-runtime",
|
||
"runtimeArgs": []
|
||
}
|
||
}
|
||
}
|
||
```
|
||
</div>
|
||
|
||
Pour chaque nouveau conteneur lancé, il sera alors possible de préciser le *runtime* à utiliser grâce à l'option `--runtime` :
|
||
|
||
<div lang="en-US">
|
||
```sh
|
||
docker container run [...] --runtime=my-runtime nginx:alpine
|
||
```
|
||
</div>
|
||
|
||
:::::
|
||
|
||
|
||
### `image-spec`
|
||
|
||
Une image OCI est composée d'un manifest, d'une série de couches de systèmes de
|
||
fichiers, d'une configuration ainsi que d'un index d'image optionnel.
|
||
|
||
Le
|
||
[manifest](https://github.com/opencontainers/image-spec/blob/master/manifest.md)
|
||
est toujours le point d'entrée d'une image : il référence l'emplacement où
|
||
trouver les différents éléments : configuration et couches. Lorsqu'une même
|
||
image a des variations en fonction de l'architecture du processeur, du système
|
||
d'exploitation, ... dans ce cas [l'index
|
||
d'image](https://github.com/opencontainers/image-spec/blob/master/image-index.md)
|
||
est utilisé pour sélectionner le bon manifest correspondant au système.
|
||
|
||
Le format des [couches de système de
|
||
fichiers](https://github.com/opencontainers/image-spec/blob/master/layer.md)
|
||
sont spécifiées : il est nécessaire de passer par des formats standards (comme
|
||
les tarballs), contenant éventuellement des fichiers et dossiers spéciaux
|
||
représentant les modifications ou les suppressions éventuelles de la couche.
|
||
|
||
La
|
||
[configuration](https://github.com/opencontainers/image-spec/blob/master/config.md)
|
||
contient l'ensemble des métadonnées qui serviront par exemple à construire le
|
||
`config.json` attendu par `runc` lorsqu'il faudra lancer l'image (c'est
|
||
là-dedans que finissent toutes les métadonnées que l'on inscrit dans nos
|
||
`Dockerfile` : `CMD`, `VOLUME`, `PORT`, ...). On y retrouve également l'ordre
|
||
des couches du système de fichiers, ainsi que l'historique de l'image.
|
||
|
||
|
||
### `distribution-spec`
|
||
|
||
Enfin, cette spécification fédère la notion de *registre* et la manière dont
|
||
les clients vont interagir avec : il s'agit d'une API REST au dessus du
|
||
protocole HTTP.
|
||
|
||
Cela permet de récupérer des images, mais aussi d'en envoyer, en gérant
|
||
éventuellement la manière de s'authentifier.
|
||
|
||
\
|
||
|
||
Nous allons voir plus en détails, dans les chapitres suivantes, ce que l'on
|
||
peut tirer de ces spécifications, en décortiquant des usages précis.
|