virli/tutorial/docker-internals/runc.md

151 lines
4.0 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\newpage
`runc`
======
`runc` est le programme qui est responsable de la création effective du
conteneur : c'est lui qui va mettre en place toute la machinerie, les points de
montages ou volumes, ... Attention, son rôle reste limité à la mise en place de
l'environnement conteneurisé, ce n'est pas lui qui télécharge l'image, ni fait
l'assemblage des couches de système de fichiers, entre autres.
Aujourd'hui, le lancement de conteneur est faite avec `runc`, mais il est
parfaitement possible d'utiliser n'importe quel autre programme à sa place, à
partir du moment où il expose la même interface à Docker et qu'il accepte les
*bundle* OCI.
Pour appréhender l'utilisation de `runc` sans l'aide de Docker, nous allons
essayer de lancer un shell `alpine` avec un volume dans notre home.
## Prérequis
Vous devriez avoir le binaire `runc` ou `docker-runc`. Si ce n'est pas le cas,
vous pouvez télécharger la dernière version :
<https://github.com/opencontainers/runc/releases>. La 1.0.0-rc92 est Ok.
## Extraction du rootfs
À l'aide du script d'extraction de registre réalisé dans le TP 3, extrayons le
rootfs d'alpine : `library/alpine` dans le registre Docker.
Si vous n'avez pas eu le temps de terminer le script d'extraction, vous pouvez
utiliser :
<div lang="en-US">
```bash
docker image save alpine | tar xv -C rootfs
```
</div>
## Modèle de configuration
L'écriture complète d'un fichier `config.json` pour `runc` est plutôt
fastidieux et répétitif, nous allons donc gagner du temps et utiliser la
commande suivante, qui nous créera un modèle que nous adapterons un peu :
<div lang="en-US">
```bash
runc spec
```
</div>
Pour savoir à quoi correspondent tous ces éléments, vous pouvez consulter :
<https://github.com/opencontainers/runtime-spec/blob/master/config.md>
Nous verrons dans les prochains TP, plus en détails tout ce qui porte sur les
*namespaces*, rassurez-vous, il n'y a que très peu de champs à modifier
aujourd'hui.
## Test brut
Voici comment nous pouvons tester le fonctionnement de notre *bundle* :
<div lang="en-US">
```
42sh$ ls
rootfs/ config.json
42sh# runc run --bundle . virli1
/ # _
```
</div>
Quelques informations sont disponibles, mais il ne faut pas s'attendre à
retrouver tout l'écosystème de `docker` ; ici il n'y a pas de gestion des
journaux, etc. :
<div lang="en-US">
```bash
42sh# runc list
ID PID STATUS BUNDLE CREATED OWNER
virli1 12345 running /tmp/work/runctest 2012-12-12T12:12:12.123456789Z root
42sh# runc state virli1
...
```
</div>
## Attacher notre `home`
Dans le modèle de `config.json`, il y a déjà de nombreux systèmes de fichiers
qui sont montés. Nous pouvons les filtrer avec :
<div lang="en-US">
```bash
42sh$ jq .mounts config.json
```
```json
[
{
"destination": "/proc",
"type": "proc",
"source": "proc"
},
[...]
```
</div>
Pour avoir notre équivalent du `-v /home:/home` de `docker`, il va donc falloir
ajouter un élément à cette liste, demandant de *bind* :
<div lang="en-US">
```json
{
"destination": "/home",
"type": "none",
"source": "/home",
"options": [
"bind",
"ro"
]
}
```
</div>
## Exercice {-}
À vous maintenant d'éditer votre `config.json`, pour lancer le service youp0m.
Dans un premier temps, assurez-vous de pouvoir télécharger et d'assembler
rapidement les couches du conteneur.
À partir du fichier `config.json` fourni, adaptez la ligne de commande à lancer
et le dossier courant par défaut (`cwd`). Pensez également à faire un volume
entre un dossier de votre home (ou temporaire, peu importe), afin de pouvoir
stocker les photos (dossier `/srv/images`)[^chmod].
[^chmod]: faites attention aux droits du dossier que vous partagez. Le plus
simple pour l'instant serait d'attribuer les permissions `0777` à la
source, temporairement.
Pour ce TP, considérez que vous avez réussi si vous voyez s'afficher :
> `Ready, listening on :8080`
Il faudra attendre les TP suivants pour avoir du réseau dans notre conteneur.