[Debian] Machine virtuelle headless hyper-rapide avec Vagrant et Docker
Vagrant est un outil qui permet de lancer des machines virtuelles headless. C’est à dire sans interface graphique.
Docker est un outils qui permet de gérer simplement l’isolation de processus sur un système avec un noyaux Linux.
Nous allons voir ici comment installer une machine virtuelle Vagrant basée sur les conteneurs Docker. Objectif ? Démarrage en moins de 3 secondes !
Même si les commandes présentées ici concernent Debian ceci peut être facilement adapté sur d’autres systèmes GNU/Linux (RHEL, CentOS, Gentoo, ArchLinux, …)
Installation
Vagrant
Nous allons tous d’abord installer Vagrant. Le support de Docker dans vagrant n’est disponible depuis la version 1.6 de Vagrant(1) il nous faudra donc au minimum cette version.
Téléchargeons le paquet et installons le.
$ wget https://dl.bintray.com/mitchellh/vagrant/vagrant_1.6.5_x86_64.deb
$ sudo dpkg -i vagrant_1.6.5_x86_64.deb
Vous pouvez vérifier que vagrant est correctement installé simplement en tapant la command vagrant
$ vagrant
Usage: vagrant [options] <command> [<args>]
-v, --version Print the version and exit.
-h, --help Print this help.
Common commands:
box manages boxes: installation, removal, etc.
connect connect to a remotely shared Vagrant environment
...
Note : Il est possible que vagrant vous demande de réaliser certaine mise à jours. Exemple :
Vagrant is upgrading some internal state for the latest version. Please do not quit Vagrant at this time. ... Press any other key to continue.</blockquote>
Vagrant est maintenant installé passons à l’installation de docker.
Docker
La documentation officielle de Docker est très bien faite pour l’installation de docker(2). Nous allons donc la suivre. L’exemple ici concerne une Debian Wheezy.
Pour pouvoir fonctionner docker nécessite les fonctionnalités du noyau Linux 3.8. Il faudra donc tout d’abord installer un noyau à jour. Sous Wheezy nous sommes obligé de passer par les backports.
# echo "deb http://http.debian.net/debian wheezy-backports main" > /etc/apt/sources.list.d/backport.list
# aptitude update
# aptitude install -t wheezy-backports linux-image-amd64
Pour utiliser ce noyau il faut redémarrer. Alors : on bookmark l’article, on sauvegarde ses documents et on reboot !
Vous re-voila ? Super ! Installons docker. Pour cela un petit script est fournit par les développeurs et fonctionne très bien. Votre mot de passe vous sera demandé pour procéder à l'élévation de privilège nécessaire à l’installation de certains composants.
$ curl -sSL https://get.docker.com/ | sh
L’installation terminée nous devons ajouter notre utilisateur courant au groupe “docker” de manière à pouvoir lancer des conteneur dans un environnement non privilégié.
$ sudo usermod -aG docker username
$ newgrp docker
Remplacer username dans la commande précédente par votre nom d’utilisateur.
Si tout est bien installé la commande suivante doit fonctionner.
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Démarrer une premier conteneur
Nous allons maintenant démarrer notre premier conteneur.
La image de base
Pour pouvoir démarrer un conteneur docker il faut avoir un image de machine de base. De nombreuse image de base sont disponible sur le “registre” docker(3). Nous allons ici télécharger l’image de base debian 8 : jessie (encore en beta aujourd’hui).
$ docker pull debian:jessie
debian:jessie: The image you are pulling has been verified
50215b109eda: Pull complete
53f380325ee9: Pull complete
511136ea3c5a: Already exists
Status: Downloaded newer image for debian:jessie
Comme vous le voyez plusieurs fichiers au nom barbare sont téléchargés car docker gère ses images hirarchiquement. Chaque image dépend d’une image mère(4). Ces images intermédiaires sont appelées des “layers”.
On voit maintenant que nous avons une nouvelle image
$ docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
debian jessie 53f380325ee9 8 days ago 120 MB
Nous allons nous pencher sur Vagrant pour voir comment exécuter celle-ci.
Un fichier Vagrantfile
Pour pouvoir lancer une machine virtuelle vagrant nous avons besoin d’un fichier de configuration nommé Vagrantfile à la racine du dossier de la machine virtuelle. Ce dossier sera d’ailleurs accessible en lecture/écriture sur la machine virtuelle dans /vagrant.
Voici un fichier Vagrantfile minimaliste.
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.image = "debian:jessie"
d.has_ssh = false
end
end
Ce fichier Vagrantfile va être lu au moment où on nous allons démarrer la machine virtuelle avec la commande vagrant up. Ici le paramètre le plus intéressant est ‘d.image’ qui nous permet de spécifier l’image que nous souhaitons utiliser comme base.
Go !
Allez on se lance ?!
$ vagrant up --provider=docker
Bringing machine 'default' up with 'docker' provider...
==> default: Creating the container...
default: Name: blog_default_1413568195
default: Image: debian:jessie
default: Volume: /home/romain/project/vagrant/blog:/vagrant
default:
default: Container created: 6a5fab70c2822549
==> default: Starting container...
==> default: Provisioners will not be run since container doesn't support SSH.
Quoi ?! Tout ca pour ca ?
Et oui ! Notre conteneur a bien démarré mais comme aucun processus SSH n’a été lancé à l’intérieur de celui-ci il c’est arrêté tout de suite.
Nous pouvons constater ceci à l’aide la commande suivante.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6a5fab70c282 debian:jessie "/bin/bash" 9 seconds ago Exited (0) 7 seconds ago blog_default_1413568195
Nous allons voir dans la prochaine section comment palier ce petit problème.
Démarrer un conteneur et le garder en vie
Pour qu’un conteneur docker reste en vie il faut que le processus lancé à l’initialisation du conteneur reste en vie. Ainsi tant que ce processus est en vie, le conteneur l’est aussi.
Vagrant utilise activement SSH pour se connecter sur ses machines virtuelles. Nous allons donc partir du principe que notre commande initial sera le démons SSH.
init devient SSH
Une machine docker n’a aucun logiciel installé par défaut nous allons donc devoir installer OpenSSH. Ceci se passera en trois étapes :
1/ Démarrer un conteneur sur /bin/bash et se connecter dessus.
2/ Installer OpenSSH
3/ “Commiter” les modifications pour créer une nouvelle image docker utilisable par vagrant.
Pour démarrer un conteneur simple et nous connecter dessus nous allons utiliser la commande suivante :
$ docker run -i -t debian:jessie /bin/bash
Installons OpenSSH.
# apt-get update
# apt-get install openssh-server
# mkdir /var/run/sshd
# exit
Sauvegardons nos changements en les commitants. Ceci va créer une nouvelle image. Elle doit être préfixé (seul les VMs de docker peuvent ne pas être préfixée). Pour faire le commit il vous faudra l’id du conteneur que nous venons de modifier.
$ docker ps -la
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
775fb1a292af debian:jessie "/bin/bash" 4 minutes ago Exited (0) 11 seconds ago goofy_pare
La commande suivante commite l’image.
docker commit 775fb1a292af lermit/debian-vagrant
afbcca54a4796abe6f27da6004df258f6deb7d448002df3f4280609691dd8413
Autoriser vagrant à se connecter
Nous allons maintenant modifier notre configuration Vagrant pour dire “C’est bon on a un démon SSH” !. Voici ce à quoi doit ressembler votre fichier Vagrantfile
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.image = 'lermit/debian-vagrant'
d.has_ssh = true
d.cmd = [ '/usr/sbin/sshd', '-D', '-e' ]
end
end
Pensez bien à modifier le nom de l’image par celui que vous avez créé précédemment.
Nous allons maintenant supprimer notre ancienne machine virtuel vagrant et en créer une nouvelle basée sur notre nouvelle image. Ces commandes sont à exécuter dans le dossier de votre fichier Vagrantfile.
$ vagrant destroy
default: Are you sure you want to destroy the 'default' VM? [y/N] y
==> default: Deleting the container...
$ vagrant up --provider=docker
Bringing machine 'default' up with 'docker' provider...
==> default: Creating the container...
default: Name: blog_default_1415214859
default: Image: lermit/debian-vagrant
default: Cmd: /usr/sbin/sshd -D -e
default: Volume: /home/romain/project/vagrant/blog:/vagrant
default: Port: 2222:22
default:
default: Container created: 5f48f604248e17d9
==> default: Starting container...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 172.17.0.15:22
default: SSH username: vagrant
default: SSH auth method: private key
default: Warning: Authentication failure. Retrying...
default: Warning: Authentication failure. Retrying...
default: Warning: Authentication failure. Retrying...
default: Warning: Authentication failure. Retrying...
Et on arrive encure sur un échec ! C’est normal car vagrant attend de pouvoir se connecter en SSH et tant qu’il n’y arrive pas … et bien il attend ! On va donc créer l’utilisateur vagrant.
Démarrons un nouveau conteneur basé sur notre image avec un shell bash et créons l’utilisateur. Nous lui attribuerons le mot de passe ‘vagrant’ et profiterons de l’occasion pour lui donner les droits d’administration via sudo.
$ docker run -i -t lermit/debian-vagrant:latest /bin/bash
root@70a37163e19c:/# useradd -m -s /bin/bash vagrant
root@70a37163e19c:/# passwd vagrant
Enter new UNIX password:
Retype new UNIX password:
passwd: password updated successfully
root@70a37163e19c:/# apt-get install sudo
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
sudo
0 upgraded, 1 newly installed, 0 to remove and 29 not upgraded.
Need to get 848 kB of archives.
After this operation, 2694 kB of additional disk space will be used.
Get:1 http://http.debian.net/debian/ jessie/main sudo amd64 1.8.10p3-1 [848 kB]
Fetched 848 kB in 1s (525 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package sudo.
(Reading database ... 12249 files and directories currently installed.)
Preparing to unpack .../sudo_1.8.10p3-1_amd64.deb ...
Unpacking sudo (1.8.10p3-1) ...
Setting up sudo (1.8.10p3-1) ...
root@70a37163e19c:/# echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers
root@70a37163e19c:/# exit
Sauvegarder nos modifications
Comme pour la création de notre image nous allons devoir commiter les modifications effectué sur notre image.
On récupère l’ID et on commit sur le même nom !
$ docker ps -al
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
70a37163e19c lermit/debian-vagrant:latest "/bin/bash" 3 minutes ago Exited (0) About a minute ago tender_meitner
$ docker commit 70a37163e19c lermit/debian-vagrant
e0a3bd14989af0659801937e6fc0b76e30bd0224f5ffe79a960fd237aa002b30
Avant de pouvoir relancer notre instance vagrant nous allons devoir modifier notre fichier Vagrantfile pour qu’il connaisse les identifiants avec lesquels se connecter. Voici le contenu du fichier Vagrantfile.
Vagrant.configure("2") do |config|
config.vm.provider "docker" do |d|
d.image = 'lermit/debian-vagrant'
d.has_ssh = true
d.cmd = [ '/usr/sbin/sshd', '-D', '-e' ]
end
config.ssh.password = 'vagrant'
end
Et cette fois la connexion fonctionne !
$ vagrant up --provider=docker
Bringing machine 'default' up with 'docker' provider...
==> default: Fixed port collision for 22 => 2222. Now on port 2200.
==> default: Creating the container...
default: Name: blog_default_1415215454
default: Image: lermit/debian-vagrant
default: Cmd: /usr/sbin/sshd -D -e
default: Volume: /home/romain/project/vagrant/blog:/vagrant
default: Port: 2200:22
default:
default: Container created: d45f3a9cfaa18b0a
==> default: Starting container...
==> default: Waiting for machine to boot. This may take a few minutes...
default: SSH address: 172.17.0.18:22
default: SSH username: vagrant
default: SSH auth method: password
==> default: Inserting Vagrant public key within guest...
==> default: Key inserted! Disconnecting and reconnecting using new SSH key...
==> default: Machine booted and ready!
$ vagrant ssh
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
vagrant@7ea874e8b88a:~$
Allez plus loin
Ca arrive …
Puppet
Librarian Puppet
Un template de base pour toutes nos machines
Références
1. https://github.com/mitchellh/vagrant/blob/master/CHANGELOG.md#160-may-6-2014