docker-internals: tuto ready

This commit is contained in:
nemunaire 2018-11-15 23:38:25 +01:00
parent 5291bd365e
commit de21be218a
7 changed files with 395 additions and 26 deletions

View file

@ -1,37 +1,131 @@
\newpage
https://ops.tips/blog/run-docker-with-forked-runc/
`runc`
======
`runc` est le programme qui est responsable de la création effective du conteneur : c'est lui qui va mettre en place les *namespaces*, les *capabilities*, 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.
`runc` est le programme qui est responsable de la création effective du
conteneur : c'est lui qui va mettre en place les *namespaces*, les
*capabilities*, 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.
Si vous n'avez pas eu le temps de terminer l'exercice précédent, vous pouvez utiliser `docker export | tar -C rootfs xv`.
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.
On va essayer de lancer un shell `alpine` avec un volume dans notre home :)
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.
D'abord on extraie l'image avec le script précédent, puis on crée le fichier de conf qui va bien.
Aujourd'hui, la création de conteneur est faite avec `runc`, mais il est parfaitement possible d'utiliser n'importe quel autre programme, à la place de `runc`, à partir du moment où il expose la même interface à Docker et qu'il accepte les bundle OCI.
## Prérequis
https://github.com/opencontainers/runtime-spec/blob/master/config.md
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-rc5 est Ok.
https://hackernoon.com/docker-containerd-standalone-runtimes-heres-what-you-should-know-b834ef155426
## Extraction du rootfs
À l'aide du script réalisé dans la partie précédentes, extrayons le rootfs
d'alpine : `library/alpine` dans le registre Docker.
Si vous n'avez pas eu le temps de terminer l'exercice précédent, vous pouvez
utiliser `docker image save alpine | tar xv -C rootfs`.
## 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">
```shell
runc spec
```
</div>
Pour savoir à quoi correspondent tous ces éléments, vous pouvez consulter :
<https://github.com/opencontainers/runtime-spec/blob/master/config.md>
## Test brut
Voici comment nous pouvons tester le fonctionnement de notre *bundle* :
<div lang="en-US">
```shell
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">
```shell
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">
```shell
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
Réaliser un `config.json` qui permette de lancer le conteneur `nemunaire/fic-admin`.
## Exercice
Serez-vous capable d'écrire un fichier `config.json` permettant d'obtenir le
même résultat que votre projet de moulette ?
Serez-vous capable de continuer l'édition de votre `config.json` afin d'obtenir
les mêmes restrictions que votre projet de moulette ?
* CGroups : 1GB RAM, 100 PID, ...
* strict minimum de capabilities ;
* volume étudiant pour correction ;
* filtres `seccomp` ;
* carte réseau `veth` ;
* ...