Tuto: fix mistakes and oversights

This commit is contained in:
nemunaire 2014-11-30 22:48:17 +01:00
parent e1aa9bd4c9
commit ef6e81877e
2 changed files with 141 additions and 120 deletions

View File

@ -22,13 +22,16 @@ commencer. Vous n'êtes pas forcément tenu de réaliser les étapes dans l'ordr
* N'oubliez pas de consulter avant toutes choses les `man` très fournis des * N'oubliez pas de consulter avant toutes choses les `man` très fournis des
commandes que vous utiliserez ; en particulier tous les `lxc-*`, commandes que vous utiliserez ; en particulier tous les `lxc-*`,
`capabilities(7)`, ... `capabilities(7)`, ...
* Vous pouvez utiliser ou vous inspirer des images présentes sur le Hub Docker.
* Ne passez pas trop de temps sur l'interface, l'architecture des containers
est bien plus intéressante.
## Modalités de rendu ## Modalités de rendu
L'heure du rendu est fixé au dimanche 30 novembre 2014 à 11h42 CET. L'heure du rendu est fixé au dimanche 30 novembre 2014 à 11h42 CET.
Il est attendu que vous rendiez à virli@nemunai.re une tarball contenant un ou Il est attendu que vous rendiez, à <virli@nemunai.re>, une tarball contenant un
plusieurs `Dockerfile` permettant d'obtenir l'interface de contrôle des ou plusieurs `Dockerfile` permettant d'obtenir l'interface de contrôle des
conteneurs, accompagnés d'un script automatisant le déploiement de la solution conteneurs, accompagnés d'un script automatisant le déploiement de la solution
sur une nouvelle machine (voir la section 2.2 pour les modalités de ce script). sur une nouvelle machine (voir la section 2.2 pour les modalités de ce script).

View File

@ -54,23 +54,54 @@ la configuration de votre noyau en utilisant la commande `lxc-checkconfig`.
### Par le gestionnaire de paquets ### Par le gestionnaire de paquets
Sous Debian et ses dérivés (Ubuntu, Mint, ...) le paquet et la commande ont été Sous Debian et ses dérivés (Ubuntu, Mint, ...) le paquet et la commande ont été
nommés `docker.io`. nommés `docker.io`. Vous pouvez vous créer un alias `alias docker=docker.io`.
Sous les autres distribution, `docker` correspond a priori bien à la solution Sous les autres distribution, `docker` correspond a priori bien à la solution
de virtualisation légère que l'on va utiliser. de virtualisation légère que l'on va utiliser.
### Manuellement ### Manuellement
L'équipe en charge de Docker met à disposition un script pour L'équipe en charge de Docker met à disposition un script pour installer Docker
installer Docker sur n'importe quel système : sur n'importe quel système :
```sh ```sh
curl -sSL https://get.docker.com/ | sh curl -sSL https://get.docker.com/ | sh
``` ```
### Vérifier la bonne marche de l'installation
Vous devriez maintenant être capable de lancer la commande suivante :
```
docker version
```
Une sortie similaire au bloc suivant devrait apparaître sur votre écran :
```
Client version: 1.3.2
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 39fa2fa
OS/Arch (client): linux/amd64
Server version: 1.3.2
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 39fa2fa
```
Si vous avez cette erreur : `dial unix /var/run/docker.sock: permission
denied.`, ajoutez votre utilisateur au groupe `docker` et **relancer votre
session** :
```
sudo gpasswd -a $USER docker
```
## LXC ## LXC
Votre distribution fourni sans doute un paquet `lxc`. Votre distribution fournit sans doute un paquet `lxc`.
# Docker # Docker
@ -260,7 +291,7 @@ dossier ne contenant que votre fichier `Dockerfile`, placez-vous
dedans, puis utilisez la commande `build` : dedans, puis utilisez la commande `build` :
``` ```
docker build -name=my_editor . docker build --tag=my_editor .
``` ```
Une fois la construction de l'image terminée, vous pouvez la lancer et Une fois la construction de l'image terminée, vous pouvez la lancer et
@ -270,7 +301,7 @@ constater l'existence de notre éditeur favori :
docker run -it my_editor /bin/bash docker run -it my_editor /bin/bash
``` ```
Consultez https://docs.docker.com/reference/builder/ pour la liste Consultez <https://docs.docker.com/reference/builder/> pour la liste
complète des instructions reconnues. complète des instructions reconnues.
@ -296,7 +327,7 @@ redirection de port aléatoire sur la machine hôte vers votre
conteneur : conteneur :
``` ```
docker build -name=my_webserver . docker build --tag=my_webserver .
docker run -it -P my_webserver /bin/bash docker run -it -P my_webserver /bin/bash
service nginx start service nginx start
``` ```
@ -305,7 +336,7 @@ Dans un autre terminal, lancer un `docker ps` et consulter la colonne
*PORTS* pour connaître le port choisit par Docker pour effectuer la *PORTS* pour connaître le port choisit par Docker pour effectuer la
redirection. redirection.
Rendez-vous ensuite dans votre navigateur sur http://localhost:49153/. Rendez-vous ensuite dans votre navigateur sur <http://localhost:49153/>.
À vous de jouer : utilisez l'instruction `COPY` pour afficher votre À vous de jouer : utilisez l'instruction `COPY` pour afficher votre
propre `index.html` remplaçant celui installé de base par nginx. propre `index.html` remplaçant celui installé de base par nginx.
@ -321,7 +352,7 @@ CMD nginx -g "daemon off;"
``` ```
``` ```
docker build -name=my_nginx . docker build --tag=my_nginx .
docker run -d -P my_nginx docker run -d -P my_nginx
``` ```
@ -359,36 +390,34 @@ Vous constaterez que le répertoire `/var/log/nginx` est partagé entre
`romantic_archimedes` et le dernier conteneur lancé. `romantic_archimedes` et le dernier conteneur lancé.
\newline \newline
Le concept principal de Docker est de concevoir des conteneurs Le concept principal de Docker est de concevoir des conteneurs applicatifs : on
applicatifs : on va préférer assigner un unique rôle à un conteneur va préférer assigner un unique rôle à un conteneur (donc géralement on ne va
(donc géralement on ne va lancer qu'une seule application par lancer qu'une seule application par conteneur) et concevoir un service complet
conteneur) et concevoir un service complet en créant un groupe de en créant un groupe de conteneur, partageant des données entre-eux par des
conteneur, partageant des données entre-eux par des volumes. volumes.
Une lecture intéressante sur ce sujet est sans doute cet article de Une lecture intéressante sur ce sujet est sans doute [cet article de Michael
Michael Crosby: http://crosbymichael.com/advanced-docker-volumes.html Crosby](http://crosbymichael.com/advanced-docker-volumes.html).
### Data Volume Container ### Data Volume Container
Dans de nombreuses situation, il est intéressant de séparer les Dans de nombreuses situation, il est intéressant de séparer les données de
données de l'application, et donc d'avoir un conteneur exécutant l'application, et donc d'avoir un conteneur exécutant l'application et un
l'application et un second stockant les données. second stockant les données.
Cela est particulièrement utile dans le cas d'une base de données : on Cela est particulièrement utile dans le cas d'une base de données : on veut
veut pouvoir mettre à jour le conteneur exécutant le serveur, sans pouvoir mettre à jour le conteneur exécutant le serveur, sans pour autant
pour autant perdre les données. perdre les données.
L'idée derrière le concept de `Data Volume Container` est de partager L'idée derrière le concept de `Data Volume Container` est de partager un volume
un volume avec un conteneur dont le seul rôle est de stocker les avec un conteneur dont le seul rôle est de stocker les données.
données.
Il est parfaitement possible de partager un volume avec un conteneur Il est parfaitement possible de partager un volume avec un conteneur qui n'est
qui n'est plus lancé. En effet, tant que vous n'avez pas demandé plus lancé. En effet, tant que vous n'avez pas demandé explicitement à un
explicitement à un conteneur d'être supprimé, il est préservé dans un conteneur d'être supprimé, il est préservé dans un coin en attendant des jours
coin en attendant des jours meilleurs. meilleurs.
Voici comment on pourrait lancer un conteneur exécutant une base de Voici comment on pourrait lancer un conteneur exécutant une base de données :
données :
``` ```
docker run -v /var/lib/mysql --name dbdata busybox docker run -v /var/lib/mysql --name dbdata busybox
@ -396,39 +425,36 @@ docker run --volume-from dbdata -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql
``` ```
Le premier conteneur, sans commande passée, va s'arrêter dès son Le premier conteneur, sans commande passée, va s'arrêter dès son
lancement. Busybox est l'une des plus petites images possédant tous lancement. Busybox est l'une des plus petites images possédant tous les outils
les outils de base (il est possible d'obtenir un shell en cas de de base (il est possible d'obtenir un shell en cas de besoin). Il expose un
besoin). Il expose un volume qui sera utiliser comme stockage volume qui sera utiliser comme stockage persistant.
persistant.
Le second conteneur va lancer le serveur MySQL et utiliser le Le second conteneur va lancer le serveur MySQL et utiliser le répertoire
répertoire partagé pour stocker les données. partagé pour stocker les données.
Lorsqu'il y aura besoin de mettre à jour le conteneur MySQL, les Lorsqu'il y aura besoin de mettre à jour le conteneur MySQL, les données ne
données ne seront pas perdues (et s'il y avait besoin de migrer les seront pas perdues (et s'il y avait besoin de migrer les données entre les deux
données entre les deux versions des conteneurs, un conteneur versions des conteneurs, un conteneur intermédiaire pourrait parfaitement s'en
intermédiaire pourrait parfaitement s'en charger). charger).
Cela facile également les sauvegardes, qui peuvent s'exécuter dans un Cela facile également les sauvegardes, qui peuvent s'exécuter dans un conteneur
conteneur distinct, dédié à la tâche de sauvegarde. distinct, dédié à la tâche de sauvegarde.
## Lier les conteneurs ## Lier les conteneurs
En plus de vouloir partager des répertoires entre deux conteneurs, il En plus de vouloir partager des répertoires entre deux conteneurs, il est
est souvent nécessaire de partager des ports. souvent nécessaire de partager des ports.
Pour automatiser le partage d'informations sur les IP et ports Pour automatiser le partage d'informations sur les IP et ports exposés, la
exposés, la commande `run` possède l'option `--link` qui permet de commande `run` possède l'option `--link` qui permet de définir dans les
définir dans les variables d'environnement du conteneur que l'on va variables d'environnement du conteneur que l'on va lancer.
lancer.
Le détail des variables ajoutées dans cette situation est disponible Le détail des variables ajoutées dans cette situation est disponible
ici : https://docs.docker.com/userguide/dockerlinks/#environment-variables [ici](https://docs.docker.com/userguide/dockerlinks/#environment-variables).
On utiliser généralement cette liaison pour fournir au conteneur On utiliser généralement cette liaison pour fournir au conteneur hébergeant un
hébergeant un site web dynamique l'IP et le port où trouver la base de site web dynamique l'IP et le port où trouver la base de données :
données :
``` ```
docker run -e MYSQL_ROOT_PASSWORD=mysecretpassword -d --name db1 mysql docker run -e MYSQL_ROOT_PASSWORD=mysecretpassword -d --name db1 mysql
@ -437,45 +463,43 @@ docker run --link db1 my_nginx
### Ambasador ### Ambasador
Afin d'abstraire le plus possible l'infrastructure sous-jacente et Afin d'abstraire le plus possible l'infrastructure sous-jacente et d'autoriser
d'autoriser les migrations de conteneurs, on utilise le modèle les migrations de conteneurs, on utilise le modèle *ambassador*.
*ambassador*.
On lancera systématiquement un conteneur entre deux conteneurs que On lancera systématiquement un conteneur entre deux conteneurs que l'on veut
l'on veut lier : l'ambassadeur. Celui-ci s'occupera de router lier : l'ambassadeur. Celui-ci s'occupera de router correctement le trafic. En
correctement le trafic. En cas de changement de route (si l'un des cas de changement de route (si l'un des conteneurs change de machine hôte par
conteneurs change de machine hôte par exemple), on a simplement à exemple), on a simplement à redémarrer l'ambassadeur plutôt que le conteneur
redémarrer l'ambassadeur plutôt que le conteneur principal. principal.
La documentation officielle pour ce modèle est disponible à La documentation officielle pour ce modèle est disponible
https://docs.docker.com/articles/ambassador_pattern_linking/ (ici)[https://docs.docker.com/articles/ambassador_pattern_linking/].
# LXC # LXC
Contrairement à Docker, l'utilisation de LXC est beaucoup plus proche Contrairement à Docker, l'utilisation de LXC est beaucoup plus proche de
de l'administration système classique, car l'approche est beaucoup l'administration système classique, car l'approche est beaucoup plus bas
plus bas niveau. niveau.
## Lancer un conteneur ## Lancer un conteneur
Avec le paquet LXC que vous avez installé, vous avez également Avec le paquet LXC que vous avez installé, vous avez également récupéré un
récupéré un certain nombre de modèles de système (souvent installés certain nombre de modèles de système (souvent installés dans le dossier
dans le dossier `/usr/share/lxc/templates/`). `/usr/share/lxc/templates/`).
La méthode la plus simple pour lancer un conteneur LXC est d'utiliser La méthode la plus simple pour lancer un conteneur LXC est d'utiliser l'un de
l'un de ces modèles qui va installer tout un environnement pour ces modèles qui va installer tout un environnement pour vous. On utilise pour
vous. On utilise pour cela la commande `lxc-create` : cela la commande `lxc-create` :
``` ```
lxc-create --name toto_first --template ubuntu lxc-create --name toto_first --template ubuntu
``` ```
Ce modèle va créer un dossier dans `/var/lib/lxc/` portant le nom que Ce modèle va créer un dossier dans `/var/lib/lxc/` portant le nom que vous avez
vous avez précisé. Ce dossier va contenir la configuration LXC du précisé. Ce dossier va contenir la configuration LXC du conteneur, la table des
conteneur, la table des partitions s'il y a besoin de faire des partitions s'il y a besoin de faire des montages particuliers et enfin le
montages particuliers et enfin le dossier `rootfs` contenant le dossier `rootfs` contenant le système en lui-même.
système en lui-même.
On peut maintenant démarrer le conteneur : On peut maintenant démarrer le conteneur :
@ -484,54 +508,48 @@ lxc-start --name toto_first
``` ```
À la différence de Docker qui va ne lancer que l'application (ou les À la différence de Docker qui va ne lancer que l'application (ou les
applications listées dans la ligne de commande) dans son applications listées dans la ligne de commande) dans son environnement, LXC va
environnement, LXC va appeler `/sbin/init` et démarrer tous les appeler `/sbin/init` et démarrer tous les services que l'on peut s'attendre à
services que l'on peut s'attendre à trouver dans n'importe quelle trouver dans n'importe quelle machine virtuelle plus classique (la seule
machine virtuelle plus classique (la seule différence réside donc dans différence réside donc dans le fait que le noyau est partagé avec l'hôte).
le fait que le noyau est partagé avec l'hôte).
Généralement on lance `lxc-start` avec l'option `--daemon`, puis on Généralement on lance `lxc-start` avec l'option `--daemon`, puis on utilise
utilise `lxc-console` qui permet de se détacher de la console via le `lxc-console` qui permet de se détacher de la console via le binding `^A+q`.
binding `^A+q`.
Connectez-vous, lancez quelques commandes puis éteignez la machine Connectez-vous, lancez quelques commandes puis éteignez la machine avec `sudo
avec `sudo poweroff` ou dans un autre terminal via `lxc-stop --name poweroff` ou dans un autre terminal via `lxc-stop --name toto_first`.
toto_first`.
## Persistance des données ## Persistance des données
Contrairement à Docker, lorsque vous arrêtez un conteneur, les Contrairement à Docker, lorsque vous arrêtez un conteneur, les modifications
modifications apportées sont conservées. Si vous appelez à nouveau apportées sont conservées. Si vous appelez à nouveau `lxc-start --name
`lxc-start --name toto_first`, vous constaterez que votre historique toto_first`, vous constaterez que votre historique contient les dernières
contient les dernières commandes que vous avez tapé et si vous avez commandes que vous avez tapé et si vous avez apporté d'autres modifications sur
apporté d'autres modifications sur le système, celles-ci sont toujours le système, celles-ci sont toujours visibles.
visibles.
## Le réseau ## Le réseau
Le modèle ubuntu que vous avez utilisé initialise un fichier de Le modèle ubuntu que vous avez utilisé initialise un fichier de configuration
configuration sans paramètres pour le réseau. Vous n'avez donc pas sans paramètres pour le réseau. Vous n'avez donc pas d'interface dans le
d'interface dans le conteneur pour le connecter au réseau. conteneur pour le connecter au réseau.
Un excellent article détaillant les différents types de réseau est Un excellent article détaillant les différents types de réseau est accessible
accessible à : (ici)[https://blog.flameeyes.eu/2010/09/linux-containers-and-networking].
https://blog.flameeyes.eu/2010/09/linux-containers-and-networking
N'ayant qu'une seule interface physique sur la machine et n'ayant pas N'ayant qu'une seule interface physique sur la machine et n'ayant pas accès à
accès à la configuration des VLAN de la pièce, il ne nous reste que la configuration des VLAN de la pièce, il ne nous reste que deux méthodes pour
deux méthodes pour obtenir du réseau dans nos conteneurs : Virtual obtenir du réseau dans nos conteneurs : Virtual Ethernet ou MACVLAN.
Ethernet ou MACVLAN.
### Virtual Ethernet ### Virtual Ethernet
Virtual Ethernet est la configuration la plus simple. On met en place un pont Virtual Ethernet est la configuration la plus simple. On met en place un pont
sur la machine hôte, puis on crée une interface `veth` par conteneur sur la machine hôte, puis on crée une interface `veth` par conteneur que l'on
que l'on veut lancer. On n'oubliera pas d'ajouter ces interfaces au pont. veut lancer. On n'oubliera pas d'ajouter ces interfaces au pont.
Voici un extrait de configuration correspondant au paramétrage d'une Voici un extrait de configuration correspondant au paramétrage d'une interface
interface `eth0` pour un conteneur donné : `eth0` pour un conteneur donné :
``` ```
lxc.network.type = veth lxc.network.type = veth
@ -539,15 +557,15 @@ lxc.network.flags = up
lxc.network.link = br0 lxc.network.link = br0
``` ```
Cette technique a pour inconvénient de laisser au noyau le soin de Cette technique a pour inconvénient de laisser au noyau le soin de router les
router les paquets selon leur adresse IP, ce qui peut être lent et paquets selon leur adresse IP, ce qui peut être lent et coûteux étant donné que
coûteux étant donné que la carte est placé en mode de promiscuité. la carte est placé en mode de promiscuité.
### MACVLAN ### MACVLAN
Ici, le noyau va orienter les paquets en fonction de leur adresse MAC Ici, le noyau va orienter les paquets en fonction de leur adresse MAC de
de destination. destination.
``` ```
lxc.network.type = macvlan lxc.network.type = macvlan
@ -559,9 +577,9 @@ lxc.network.link = br0
## Stockage ## Stockage
Par défaut, le stockage se fait dans l'arborescence du système hôte, Par défaut, le stockage se fait dans l'arborescence du système hôte, mais il
mais il est possible d'utiliser d'autres backends tels que Btrfs, LVM, est possible d'utiliser d'autres backends tels que Btrfs, LVM, overlayfs, AUFS
overlayfs, AUFS ou ZFS. ou ZFS.
Pour utiliser un type de stockage particulier, préciser lors de la Pour utiliser un type de stockage particulier, préciser lors de la création de
création de l'environnement du conteneur `-B [btrfs|zfs|lvm|...]`. l'environnement du conteneur `-B [btrfs|zfs|lvm|...]`.