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