Tuto 1: wip
This commit is contained in:
parent
7752f11472
commit
50913a7493
19
tutorial/1/Makefile
Normal file
19
tutorial/1/Makefile
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
SOURCES = tutorial.md installation.md lxc.md cgroups.md namespaces.md
|
||||||
|
TEMPLATE = ../../template.tex
|
||||||
|
PANDOCOPTS = --latex-engine=xelatex \
|
||||||
|
--standalone \
|
||||||
|
--normalize \
|
||||||
|
--number-sections \
|
||||||
|
-M lang=frenchb \
|
||||||
|
-M fontsize=12pt \
|
||||||
|
-M papersize=a4paper \
|
||||||
|
--template=${TEMPLATE}
|
||||||
|
|
||||||
|
|
||||||
|
all: tutorial.pdf
|
||||||
|
|
||||||
|
tutorial.pdf: ${SOURCES}
|
||||||
|
pandoc ${PANDOCOPTS} -o $@ $+
|
||||||
|
|
||||||
|
clean::
|
||||||
|
rm tutorial.pdf
|
50
tutorial/1/cgroups.md
Normal file
50
tutorial/1/cgroups.md
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
\newpage
|
||||||
|
|
||||||
|
# Utiliser les *cgroups*
|
||||||
|
|
||||||
|
## Premiers tests
|
||||||
|
|
||||||
|
### Création d'un nouveau groupe
|
||||||
|
|
||||||
|
### Rattachement de processus
|
||||||
|
|
||||||
|
### Consultatation de l'état
|
||||||
|
|
||||||
|
### Changement d'état
|
||||||
|
|
||||||
|
|
||||||
|
## Script de monitoring
|
||||||
|
|
||||||
|
### Monitoring instantanné vers la console
|
||||||
|
|
||||||
|
#### Option pour choisir l'intervalle de polling
|
||||||
|
|
||||||
|
### Monitoring vers InfluxDB
|
||||||
|
|
||||||
|
### Permettre à l'utilisateur de monitorer des process
|
||||||
|
|
||||||
|
#### Séparer en deux scripts
|
||||||
|
|
||||||
|
#### Ajouter les bonnes capabilities sur le premier script
|
||||||
|
|
||||||
|
#### Rendre ok avec les exécutions concurrentes du second script
|
||||||
|
|
||||||
|
### Monitorer chaque fils indépendamment
|
||||||
|
|
||||||
|
|
||||||
|
## Rendu
|
||||||
|
|
||||||
|
### Script de monitoring
|
||||||
|
|
||||||
|
Rendez la révision la plus avancées de vos scripts de monitoring de process via
|
||||||
|
les *cgroups*.
|
||||||
|
|
||||||
|
### Questions
|
||||||
|
|
||||||
|
1. Un même processus peut-il être dans plusieurs cgroups de type différents (freezer et cpuacct par exemple) ?
|
||||||
|
|
||||||
|
1. Que sera-t-il possible de limiter via un nouveau cgroup dans la prochaine
|
||||||
|
version du noyau (4.3) ?
|
||||||
|
|
||||||
|
1. Comment peut-on limiter le nombre de processus lancés par un utilisateur ou
|
||||||
|
un groupe ?
|
52
tutorial/1/installation.md
Normal file
52
tutorial/1/installation.md
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
\newpage
|
||||||
|
|
||||||
|
# Installation
|
||||||
|
|
||||||
|
## Noyau Linux
|
||||||
|
|
||||||
|
Ce TP requiert d'avoir un noyau Linux en version 3.8 au minimum. De plus, il
|
||||||
|
doit être compilé avec les options suivantes :
|
||||||
|
|
||||||
|
```
|
||||||
|
General setup --->
|
||||||
|
[*] Control Group support --->
|
||||||
|
[*] Freezer cgroup subsystem
|
||||||
|
[*] Device controller for cgroups
|
||||||
|
[*] Cpuset support
|
||||||
|
[*] Include legacy /proc/<pid>/cpuset file
|
||||||
|
[*] Simple CPU accounting cgroup subsystem
|
||||||
|
[*] Group CPU scheduler --->
|
||||||
|
[*] Group scheduling for SCHED_OTHER
|
||||||
|
[*] Group scheduling for SCHED_RR/FIFO
|
||||||
|
<*> Block IO controller
|
||||||
|
-*- Namespaces support
|
||||||
|
[*] UTS namespace
|
||||||
|
[*] IPC namespace
|
||||||
|
[*] User namespace
|
||||||
|
[*] PID Namespaces
|
||||||
|
[*] Network namespace
|
||||||
|
[*] Networking support --->
|
||||||
|
Networking options --->
|
||||||
|
<*> 802.1d Ethernet Bridging
|
||||||
|
<M> 802.1Q VLAN Support
|
||||||
|
Device Drivers --->
|
||||||
|
[*] Network device support --->
|
||||||
|
<M> MAC-VLAN support
|
||||||
|
<*> Virtual ethernet pair device
|
||||||
|
Character devices --->
|
||||||
|
-*- Unix98 PTY support
|
||||||
|
[*] Support multiple instances of devpts
|
||||||
|
```
|
||||||
|
|
||||||
|
Une fois que vous aurez installé LXC, vous pouvez vérifier la compatibilité de
|
||||||
|
la configuration de votre noyau en utilisant la commande `lxc-checkconfig`.
|
||||||
|
|
||||||
|
|
||||||
|
## LXC
|
||||||
|
|
||||||
|
Pour installer LXC, utilisez le gestionnaire de paquets de votre
|
||||||
|
distribution. Toute les bonnes distributions fournissent un paquet `lxc`.
|
||||||
|
|
||||||
|
Aucune configuration ne devrait vous être demandé durant l'installation. Une
|
||||||
|
fois l'installation terminée, exécutez la commande `lxc-checkconfig` pour
|
||||||
|
vérifier que votre noyau possède bien toutes les options nécessaires.
|
148
tutorial/1/lxc.md
Normal file
148
tutorial/1/lxc.md
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
\newpage
|
||||||
|
|
||||||
|
# Utiliser LXC
|
||||||
|
|
||||||
|
Le but de cette première partie est d'appréhender la virtualisation légère au
|
||||||
|
travers d'un programme, `lxc`, qui va mettre en place pour nous un
|
||||||
|
environnement distinct.
|
||||||
|
|
||||||
|
|
||||||
|
## 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/`).
|
||||||
|
|
||||||
|
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 (`config`),
|
||||||
|
la table des partitions (`fstab`) s'il y a besoin de faire des montages
|
||||||
|
particuliers et enfin le dossier `rootfs` contenant le système en lui-même.
|
||||||
|
|
||||||
|
Une fois l'installation terminée, on peut démarrer le conteneur :
|
||||||
|
|
||||||
|
```
|
||||||
|
lxc-start --name toto_first
|
||||||
|
```
|
||||||
|
|
||||||
|
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`, car on ne s'attend
|
||||||
|
pas à ce que la machine s'arrête lorsque l'on va quitter notre terminal. Dans
|
||||||
|
ce cas, utiliser la commande `lxc-console` pour vous attacher à votre
|
||||||
|
conteneur. À tout moment, vous pouvez vous détacher de la console (sans que
|
||||||
|
cela n'affecte l'état du conteneur) en pressant les touches : `^A q`.
|
||||||
|
|
||||||
|
Connectez-vous, lancez quelques commandes puis éteignez la machine avec `sudo
|
||||||
|
poweroff` dans le conteneur. Vous pouvez aussi lancer la commande `lxc-stop
|
||||||
|
--name toto_first` dans un autre terminal, depuis la machine hôte.
|
||||||
|
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
Un excellent article détaillant les différents types de réseau est accessible à
|
||||||
|
<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. Malheureusement, ces deux méthodes nécessitent de mettre en place un
|
||||||
|
pont Ethernet sur votre machine :
|
||||||
|
|
||||||
|
|
||||||
|
### Installation du pont réseau
|
||||||
|
|
||||||
|
#### Bridge interface
|
||||||
|
|
||||||
|
#### Port forwarding
|
||||||
|
|
||||||
|
|
||||||
|
### 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.
|
||||||
|
|
||||||
|
Voici un extrait de configuration correspondant au paramétrage d'une interface
|
||||||
|
`eth0` pour un conteneur donné :
|
||||||
|
|
||||||
|
```
|
||||||
|
lxc.network.type = veth
|
||||||
|
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é.
|
||||||
|
|
||||||
|
|
||||||
|
### MACVLAN
|
||||||
|
|
||||||
|
Ici, le noyau va orienter les paquets en fonction de leur adresse MAC de
|
||||||
|
destination.
|
||||||
|
|
||||||
|
```
|
||||||
|
lxc.network.type = macvlan
|
||||||
|
lxc.network.macvlan.mode = bridge
|
||||||
|
lxc.network.flags = up
|
||||||
|
lxc.network.link = br0
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Utilisation du conteneur
|
||||||
|
|
||||||
|
### Redémarrage du conteneur
|
||||||
|
|
||||||
|
### Installation de InFluxDB et Graphana
|
||||||
|
|
||||||
|
### Test de l'installation
|
||||||
|
|
||||||
|
|
||||||
|
## Rendu
|
||||||
|
|
||||||
|
### Configuration du conteneur
|
||||||
|
|
||||||
|
En plus des modifications que vous avez effectuées durant le TP, modifiez la
|
||||||
|
configuration du conteneur afin qu'il ne puisse pas utiliser plus que 256 MB de
|
||||||
|
RAM et 512 MB de swap.
|
||||||
|
|
||||||
|
Limitez ensuite les `capabilities(7)` de ce conteneur afin qu'il s'exécute avec
|
||||||
|
le strict minimum de droits, nécessaire au bon fonctionnement des programmes
|
||||||
|
installés.
|
||||||
|
|
||||||
|
**Rendez le fichier `config` de ce premier conteneur.** N'hésitez pas à laisser
|
||||||
|
des commentaires justifiant vos éventuels choix.
|
||||||
|
|
||||||
|
### Questions
|
||||||
|
|
||||||
|
1. Quel type de virtualisation réseau avez-vous utilisé ? pourquoi ?
|
||||||
|
|
||||||
|
1. Quels sont les autres types de virtualisation réseau existants ? Expliquez
|
||||||
|
en chacun une phrase leurs particularités.
|
||||||
|
|
||||||
|
1. Dans quel langage InfluxDB a-t-il était écrit ? Quelle est la particularité
|
||||||
|
des binaires générés par ce langage ?
|
||||||
|
|
||||||
|
1. Quels sont les avantages et les inconvénients associés au linkage statique
|
||||||
|
et au linkage dynamique ? (pas forcément que dans le cadre de la
|
||||||
|
virtualisation légère).
|
||||||
|
|
||||||
|
1. J'ai utilisé la méthode *Virtual Ethernet* pour relier mes conteneurs à
|
||||||
|
Internet, via un PAT (`br0`). Quelle(s) règle(s) `iptables` devrais-je
|
||||||
|
écrire sur mon hôte afin de permettre l'accès à InfluxDB depuis une autre
|
||||||
|
machine ?
|
129
tutorial/1/namespaces.md
Normal file
129
tutorial/1/namespaces.md
Normal file
@ -0,0 +1,129 @@
|
|||||||
|
\newpage
|
||||||
|
|
||||||
|
# Utiliser les *namespaces*
|
||||||
|
|
||||||
|
## Comparaison de *namespace*
|
||||||
|
|
||||||
|
Écrivez un script ou un programme, `cmpns`, dans le langage courant de votre
|
||||||
|
choix, permettant de déterminer si deux programmes s'exécutent dans les mêmes
|
||||||
|
*namespaces*.
|
||||||
|
|
||||||
|
### Exemples
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh$ cmpns $(pgrep influxdb) $(pgrep init)
|
||||||
|
- ipc: differ
|
||||||
|
- mnt: differ
|
||||||
|
- net: differ
|
||||||
|
- pid: differ
|
||||||
|
- user: same
|
||||||
|
- uts: same
|
||||||
|
```
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh$ cmpns $(pgrep init) self
|
||||||
|
- ipc: same
|
||||||
|
- mnt: same
|
||||||
|
- net: same
|
||||||
|
- pid: same
|
||||||
|
- user: same
|
||||||
|
- uts: same
|
||||||
|
```
|
||||||
|
|
||||||
|
Ici, `self` fait référence au processus actuellement exécuté.
|
||||||
|
|
||||||
|
|
||||||
|
## Rejoindre un *namespace*
|
||||||
|
|
||||||
|
Dans le langage courant de votre choix, écrivez un programme : `setns`,
|
||||||
|
permettant, à la manière de `unshare(1)` et `unshare(2)`, d'utiliser `setns(2)`
|
||||||
|
via votre interpréteur.
|
||||||
|
|
||||||
|
Les options attendues sont :
|
||||||
|
|
||||||
|
* rejoindre un namespace IPC : `-i`, `--ipc` ;
|
||||||
|
* rejoindre un namespace mount : `-m`, `--mount` ;
|
||||||
|
* rejoindre un namespace net : `-n`, `--net` ;
|
||||||
|
* rejoindre un namespace PID : `-p`, `--pid` ;
|
||||||
|
* rejoindre un namespace UTS : `-u`, `--uts` ;
|
||||||
|
* rejoindre un namespace user : `-U`, `--user`.
|
||||||
|
|
||||||
|
### Exemples
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh# setns /bin/bash
|
||||||
|
bash# _
|
||||||
|
```
|
||||||
|
|
||||||
|
#### IPC and PID Namespaces
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh# setns --ipc=/proc/42/ns/ipc -p /proc/42/ns/pid /bin/echo toto
|
||||||
|
toto
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Net Namespace
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh# setns --net=/proc/42/ns/net ip a
|
||||||
|
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
|
||||||
|
link/loopback 00:00:00:00:00:00 brd 00:00:00:00::00
|
||||||
|
inet 127.0.0.1/8 brd 127.255.255.255 scope lo
|
||||||
|
valid_lft forever preferred_lft
|
||||||
|
inet6 ::1/128 scope host
|
||||||
|
valid_lft forever preferred_lft forever
|
||||||
|
```
|
||||||
|
|
||||||
|
#### UTS Namespace
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh# hostname --fqdn
|
||||||
|
koala.zoo.paris
|
||||||
|
42sh# setns --uts=/proc/42/ns/uts hostname --fqdn
|
||||||
|
lynx.zoo.paris
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## My Little Container
|
||||||
|
|
||||||
|
En utilisant le langage courant de votre choix, concevez l'exécutable `mlc`,
|
||||||
|
permettant de lancer une application dans un environnement différent (comme un
|
||||||
|
`chroot`, mais sans permettre de s'en échapper) et avec des privilèges réduits.
|
||||||
|
|
||||||
|
Votre solution doit créer au moins un nouveau *namespace* mount et PID.
|
||||||
|
|
||||||
|
Vous aurez sans doute besoin de : `clone(2)`, `capabilities(7)`, `capset(2)`, `pivot_root(2)`,
|
||||||
|
|
||||||
|
### Exemples
|
||||||
|
|
||||||
|
```sh
|
||||||
|
42sh# ls newroot
|
||||||
|
bin etc home usr root proc var
|
||||||
|
|
||||||
|
42sh# mlc newroot/ /bin/bash
|
||||||
|
bash# ls ../../../
|
||||||
|
bin etc home usr root proc var
|
||||||
|
|
||||||
|
bash# escape_chroot ls
|
||||||
|
bin etc home usr root proc var
|
||||||
|
|
||||||
|
bash# ls -ld /proc/[0-9]* | wc -l
|
||||||
|
2
|
||||||
|
|
||||||
|
bash# curl http://www.linuxcontainers.org/ | md5sum
|
||||||
|
0123456789abcdef
|
||||||
|
|
||||||
|
bash# ping 8.8.8.8
|
||||||
|
Operation not permitted
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Rendu
|
||||||
|
|
||||||
|
Pour chaque exercice de cette partie, vous pouvez rendre un seul fichier s'il
|
||||||
|
s'agit d'un script ; sinon, vous devez rendre une tarball contenant un
|
||||||
|
`Makefile` permettant de générer les éventuels exécutables et/ou un `README`
|
||||||
|
expliquant comment s'en servir.
|
||||||
|
|
||||||
|
Vous devez donc rendre 3 fichiers : `cmpns` ou `cmpns.tar.bz2`, `setns` ou
|
||||||
|
`setns.tar.bz2` et `mlc` ou `mlc.tar.bz2`.
|
21
tutorial/1/tutorial.md
Normal file
21
tutorial/1/tutorial.md
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
% Virtualisation légère -- TP n^o^ 1
|
||||||
|
% Pierre-Olivier *nemunaire* Mercier
|
||||||
|
% Jeudi 8 octobre 2015
|
||||||
|
|
||||||
|
Le but de ce premier TP est d'utiliser les commandes et les appels systèmes vu
|
||||||
|
durant le cours.
|
||||||
|
|
||||||
|
Tous les éléments de ce TP (exercices et questions) sont à rendre à
|
||||||
|
<virli@nemunai.re> au plus tard le mercredi 21 octobre 2015 à 23 h 42. Consultez la
|
||||||
|
dernière section de chaque partie pour plus d'information sur les éléments à
|
||||||
|
rendre. Vous pouvez placer les réponses aux questions dans le corps du courriel
|
||||||
|
ou dans un fichier joint.
|
||||||
|
|
||||||
|
En tant que personnes sensibilisées à la sécurité des échanges électroniques,
|
||||||
|
vous devriez m'envoyer vos rendus signés avec votre clef PGP. Pensez à
|
||||||
|
[me](http://pgp.mit.edu/pks/lookup?op=vindex&search=0x842807A84573CC96) faire
|
||||||
|
signer votre clef et n'hésitez pas à
|
||||||
|
[faire signer votre clef](http://www.meetup.com/fr/Paris-certification-de-cles-PGP-et-CAcert/).
|
||||||
|
|
||||||
|
\hypersetup{linkcolor=black}
|
||||||
|
\tableofcontents
|
@ -1,9 +0,0 @@
|
|||||||
all: tutorial.pdf
|
|
||||||
|
|
||||||
.md.pdf:
|
|
||||||
pandoc --latex-engine=xelatex --toc --normalize -M lang=frenchb --standalone -N --template=../template.tex -M fontsize=12pt -M papersize=a4paper -o $@ $<
|
|
||||||
|
|
||||||
.md.tex:
|
|
||||||
pandoc --latex-engine=xelatex --toc --normalize -M lang=frenchb --standalone -N --template=../template.tex -M fontsize=12pt -M papersize=a4paper -o $@ $<
|
|
||||||
|
|
||||||
.SUFFIXES: .md .tex .pdf
|
|
@ -1,593 +0,0 @@
|
|||||||
% Virtualisation légère
|
|
||||||
% Pierre-Olivier *Nemunaire* Mercier
|
|
||||||
% Samedi 29 novembre 2014
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
## Noyau Linux
|
|
||||||
|
|
||||||
Ce TP requiert d'avoir un noyau Linux en version 3.8 au minimum. De plus, il
|
|
||||||
doit être compilé avec les options suivantes :
|
|
||||||
|
|
||||||
```
|
|
||||||
General setup --->
|
|
||||||
[*] Control Group support --->
|
|
||||||
[*] Freezer cgroup subsystem
|
|
||||||
[*] Device controller for cgroups
|
|
||||||
[*] Cpuset support
|
|
||||||
[*] Include legacy /proc/<pid>/cpuset file
|
|
||||||
[*] Simple CPU accounting cgroup subsystem
|
|
||||||
[*] Group CPU scheduler --->
|
|
||||||
[*] Group scheduling for SCHED_OTHER
|
|
||||||
[*] Group scheduling for SCHED_RR/FIFO
|
|
||||||
<*> Block IO controller
|
|
||||||
-*- Namespaces support
|
|
||||||
[*] UTS namespace
|
|
||||||
[*] IPC namespace
|
|
||||||
[*] User namespace
|
|
||||||
[*] PID Namespaces
|
|
||||||
[*] Network namespace
|
|
||||||
[*] Networking support --->
|
|
||||||
Networking options --->
|
|
||||||
<M> 802.1d Ethernet Bridging
|
|
||||||
<M> 802.1Q VLAN Support
|
|
||||||
Device Drivers --->
|
|
||||||
[*] Network device support --->
|
|
||||||
<M> MAC-VLAN support
|
|
||||||
<*> Virtual ethernet pair device
|
|
||||||
Character devices --->
|
|
||||||
-*- Unix98 PTY support
|
|
||||||
[*] Support multiple instances of devpts
|
|
||||||
```
|
|
||||||
|
|
||||||
Une fois que vous aurez installé LXC, vous pouvez vérifier la compatibilité de
|
|
||||||
la configuration de votre noyau en utilisant la commande `lxc-checkconfig`.
|
|
||||||
|
|
||||||
|
|
||||||
## Docker
|
|
||||||
|
|
||||||
### 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`. Vous pouvez vous créer un alias `alias docker=docker.io` si
|
|
||||||
celui-ci n'a pas déjà été défini.
|
|
||||||
|
|
||||||
Sous les autres distributions, `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 :
|
|
||||||
|
|
||||||
```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 fournit sans doute un paquet `lxc`.
|
|
||||||
|
|
||||||
|
|
||||||
# Docker
|
|
||||||
|
|
||||||
Docker est un outil haut niveau permettant de faire fonctionner facilement les
|
|
||||||
conteneurs.
|
|
||||||
|
|
||||||
## Composition de Docker
|
|
||||||
|
|
||||||
Docker est un daemon lancé au démarrage de votre machine, avec lequel vous
|
|
||||||
interagissez via un client qui se connecte au daemon au moyen d'une socket (le
|
|
||||||
client peut donc être sur une machine distincte du daemon où sont exécutés les
|
|
||||||
conteneurs).
|
|
||||||
|
|
||||||
|
|
||||||
## Mon premier conteneur
|
|
||||||
|
|
||||||
Afin de tester la bonne marche de votre installation, exécutez la commande :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run hello-world
|
|
||||||
```
|
|
||||||
|
|
||||||
Cette commande va automatiquement exécuter une série de commandes pour vous,
|
|
||||||
comme indiqué dans le message affiché en retour :
|
|
||||||
|
|
||||||
D'abord, le démon va rechercher s'il possède localement l'image
|
|
||||||
*hello-world*. Si ce n'est pas le cas, il va aller la récupérer sur
|
|
||||||
hub.docker.com. Ce site met à votre disposition un grand nombre d'images : des
|
|
||||||
systèmes de base comme Ubuntu, Debian, Centos, etc. jusqu'à des conteneurs
|
|
||||||
prêts à l'emploi : le serveur web nginx, la base de données MySQL, un serveur
|
|
||||||
node.js, etc.
|
|
||||||
|
|
||||||
Vous pouvez directement utiliser le client pour rechercher une image sur le
|
|
||||||
hub, en utilisant la commande `search` :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker search mariadb
|
|
||||||
```
|
|
||||||
|
|
||||||
Vous pouvez mettre à jour vos images locales ou simplement pré-télécharger des
|
|
||||||
images depuis le hub en utilisant la commande `pull` :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker pull ubuntu
|
|
||||||
```
|
|
||||||
|
|
||||||
Pour consulter la liste des images dont vous disposez localement (soit
|
|
||||||
parce que vous les avez téléchargées, soit parce que vous les avez
|
|
||||||
créées vous-même), utilisez la commande `images` :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker images
|
|
||||||
```
|
|
||||||
|
|
||||||
Vous devez constater la présence de deux images « Ubuntu », ayant un *TAG*
|
|
||||||
différent. Souvent, il existe plusieurs versions d'une même image. Pour Ubuntu
|
|
||||||
par exemple, vous avez la possibilité de lancer la version `vivid`, `trusty` ou
|
|
||||||
`precise`.
|
|
||||||
|
|
||||||
Chaque image est identifiable par son *Image ID* unique, les noms d'images
|
|
||||||
ainsi que leurs tags sont, comme les tags Git, une manière humainement plus
|
|
||||||
simple de faire référence aux identifiants.
|
|
||||||
|
|
||||||
Chaque nom d'image possède au moins un tag associé : *latest*, c'est le tag qui
|
|
||||||
est automatiquement recherché lorsque vous ne le précisez pas en lançant
|
|
||||||
l'image.
|
|
||||||
|
|
||||||
|
|
||||||
## Exécuter un programme dans un conteneur
|
|
||||||
|
|
||||||
Maintenant que nous avons à notre disposition l'image d'un conteneur Ubuntu,
|
|
||||||
lançons-la !
|
|
||||||
|
|
||||||
La commande `run` de Docker prend comme derniers arguments le programme à
|
|
||||||
lancer dans le conteneur ainsi que ses éventuels arguments. Essayons d'afficher
|
|
||||||
un Hello World :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run ubuntu /bin/echo "Hello World"
|
|
||||||
```
|
|
||||||
|
|
||||||
Dans notre exemple, c'est bien le `/bin/echo` présent dans le conteneur qui est
|
|
||||||
appelé (et non pas le programme `/bin/echo` de la machine hôte qui est
|
|
||||||
transféré dans le conteneur).
|
|
||||||
|
|
||||||
|
|
||||||
## Modifier un conteneur
|
|
||||||
|
|
||||||
À chaque fois que vous lancez un `run`, un nouveau conteneur est créé à partir
|
|
||||||
de l'image que vous précisez (via un mécanisme de Copy-On-Write, c'est donc
|
|
||||||
très rapide et ne consomme pas beaucoup d'espace disque). Cela signifie que
|
|
||||||
lorsque vous exécutez une commande modifiant le contenu d'un conteneur, cela ne
|
|
||||||
modifie pas l'image de base, mais crée une nouvelle image. Que vous pouvez
|
|
||||||
ensuite utiliser comme image de base.
|
|
||||||
|
|
||||||
Commençons par entrer dans un nouveau conteneur pour modifier l'image :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -it ubuntu /bin/bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Vous voilà maintenant dans le conteneur ! Il est assez épuré, il n'y a rien de
|
|
||||||
superflu : vous n'avez pas d'éditeur de texte : ni vim, ni emacs, même pas vi !
|
|
||||||
|
|
||||||
La première chose à faire est de mettre à jour la liste des paquets :
|
|
||||||
|
|
||||||
```
|
|
||||||
apt-get update
|
|
||||||
```
|
|
||||||
|
|
||||||
Il peut arriver que des paquets présents dans l'image officielle ne soient pas
|
|
||||||
à jour. Afin de garder un environnement cohérent, il est recommandé de ne pas
|
|
||||||
utiliser le gestionnaire de paquets pour mettre à jour les paquets, mais plutôt
|
|
||||||
de contacter le mainteneur de l'image pour qu'il la mette à jour.
|
|
||||||
|
|
||||||
Installons maintenant un programme :
|
|
||||||
|
|
||||||
```
|
|
||||||
apt-get install nano
|
|
||||||
```
|
|
||||||
|
|
||||||
En attendant la fin de l'installation, jetez un œil à la commande dans un autre
|
|
||||||
terminal :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker ps
|
|
||||||
```
|
|
||||||
|
|
||||||
Cette commande liste les conteneurs actifs. Notez le *Container ID* ainsi que
|
|
||||||
le *NAMES* du conteneur du conteneur actuellement en cours d'installation de
|
|
||||||
nano.
|
|
||||||
|
|
||||||
Lorsque l'installation de `nano` est terminée, quittez l'image en tapant
|
|
||||||
`exit`.
|
|
||||||
|
|
||||||
Sauvegardez votre image modifiée avec la commande `commit` pour pouvoir
|
|
||||||
commencer directement de votre image avec `nano` :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker commit CONTAINER my_nano
|
|
||||||
```
|
|
||||||
|
|
||||||
En remplaçant `CONTAINER` par le nom ou l'identifiant de votre
|
|
||||||
container. `my_nano` est le nom que vous voudrez utiliser à la place
|
|
||||||
d'`ubuntu` :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -it my_nano /bin/bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Vous constatez cette fois que vous pouvez lancer `nano`, alors que vous ne
|
|
||||||
pouvez toujours pas le faire dans un conteneur issue d'une image `ubuntu` !
|
|
||||||
|
|
||||||
|
|
||||||
## Dockerfile
|
|
||||||
|
|
||||||
Pour construire une image, vous n'êtes pas obligé de passer par une série de
|
|
||||||
commits. Docker dispose d'un mécanisme permettant d'automatiser la construction
|
|
||||||
de nouvelles images. Vous pouvez arriver au même résultat que ce que l'on a
|
|
||||||
réussi à faire précédemment en utilisant le Docker file suivant :
|
|
||||||
|
|
||||||
```
|
|
||||||
FROM ubuntu:latest
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y nano
|
|
||||||
```
|
|
||||||
|
|
||||||
La syntaxe d'un `Dockerfile` est simple, le premier mot de chaque ligne est
|
|
||||||
l'intitulé d'une instruction (que l'on écrit généralement en majuscule), elle
|
|
||||||
est suivie de ses arguments.
|
|
||||||
|
|
||||||
Dans notre exemple, nous utilisons `FROM` qui indique une image de départ à
|
|
||||||
utiliser ; `RUN` est une commande qui sera exécutée dans le conteneur, dans le
|
|
||||||
but de le construire. Chaque ligne est exécutée indépendamment des autres ;
|
|
||||||
cela signifie que l'exemple suivant ne fonctionne pas :
|
|
||||||
|
|
||||||
```
|
|
||||||
COPY db.sql /db.sql
|
|
||||||
RUN service mysqld start
|
|
||||||
RUN mysql -u root -p toor virli < /db.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
Cet exemple ne fonctionne pas car le serveur MySQL est lancé dans le premier
|
|
||||||
RUN, n'est plus lancé au moment du deuxième RUN. Pour avoir le résultat
|
|
||||||
escompté, il faut exécuter les commandes ensemble :
|
|
||||||
|
|
||||||
```
|
|
||||||
COPY db.sql /db.sql
|
|
||||||
RUN service mysqld start && mysql -u root -p toor virli < /db.sql
|
|
||||||
```
|
|
||||||
|
|
||||||
Après le `RUN`, MySQL sera de nouveau arrêté, si on veut l'utiliser dans le
|
|
||||||
conteneur, il ne faudra pas oublier lancer le processus.
|
|
||||||
|
|
||||||
Pour lancer la construction de la nouvelle image, créer un nouveau dossier ne
|
|
||||||
contenant que votre fichier `Dockerfile`, placez-vous dedans, puis utilisez la
|
|
||||||
commande `build` :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker build --tag=my_editor .
|
|
||||||
```
|
|
||||||
|
|
||||||
Une fois la construction de l'image terminée, vous pouvez la lancer et
|
|
||||||
constater l'existence de notre éditeur favori :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -it my_editor /bin/bash
|
|
||||||
```
|
|
||||||
|
|
||||||
Consultez <https://docs.docker.com/reference/builder/> pour la liste complète
|
|
||||||
des instructions reconnues.
|
|
||||||
|
|
||||||
|
|
||||||
## Exposer des ports
|
|
||||||
|
|
||||||
Construisons maintenant un conteneur avec un serveur web :
|
|
||||||
|
|
||||||
```
|
|
||||||
FROM my_editor
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y nginx
|
|
||||||
|
|
||||||
EXPOSE 80
|
|
||||||
```
|
|
||||||
|
|
||||||
L'instruction `EXPOSE` sera traité plus tard par le client Docker
|
|
||||||
(équivalent à l'argument `--expose`). Il s'agit de préciser les ports
|
|
||||||
sur lesquels votre image écoute.
|
|
||||||
|
|
||||||
En utilisant l'option `-P` du `run`, vous allez pouvoir assigner une
|
|
||||||
redirection de port aléatoire sur la machine hôte vers votre
|
|
||||||
conteneur :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker build --tag=my_webserver .
|
|
||||||
docker run -it -P my_webserver /bin/bash
|
|
||||||
service nginx start
|
|
||||||
```
|
|
||||||
|
|
||||||
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/>.
|
|
||||||
|
|
||||||
À vous de jouer : utilisez l'instruction `COPY` pour afficher votre
|
|
||||||
propre `index.html` remplaçant celui installé de base par nginx.
|
|
||||||
|
|
||||||
|
|
||||||
## Lancement de commande automatique
|
|
||||||
|
|
||||||
Vous pouvez placer dans un `Dockerfile` une instruction `CMD` qui sera
|
|
||||||
exécutée si aucune commande n'est passée lors du `run`, par exemple :
|
|
||||||
|
|
||||||
```
|
|
||||||
CMD nginx -g "daemon off;"
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
docker build --tag=my_nginx .
|
|
||||||
docker run -d -P my_nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
L'option `-d` passée au `run` lance le conteneur en tâche de
|
|
||||||
fond. Si vous constatez via un `docker ps` que le conteneur s'arrête
|
|
||||||
directement, retirer cette option pour voir ce qui ne va pas, ou
|
|
||||||
utilisez la commande `docker logs`.
|
|
||||||
|
|
||||||
|
|
||||||
## Volumes
|
|
||||||
|
|
||||||
Il est possible de partager des répertoires entre plusieurs
|
|
||||||
conteneurs. Pour ce faire, il faut déclarer dans le `Dockerfile` une
|
|
||||||
ou plusieurs instructions `VOLUME` avec le chemin du répertoire à
|
|
||||||
considérer comme volume (il est également possible de le faire via
|
|
||||||
l'option `--volume` du client). Ces deux lignes sont équivalentes :
|
|
||||||
|
|
||||||
```
|
|
||||||
VOLUME /var/log/nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -v /var/log/nginx my_nginx
|
|
||||||
```
|
|
||||||
|
|
||||||
Pour monter les volumes dans un autre conteneur, on utilise l'argument
|
|
||||||
`--volume-from` du client, en indiquant le nom du conteneur avec
|
|
||||||
lequel on souhaite partager les volumes :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -it --volume-from romantic_archimedes ubuntu /bin/bash
|
|
||||||
```
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 :
|
|
||||||
|
|
||||||
```
|
|
||||||
docker run -v /var/lib/mysql --name dbdata busybox
|
|
||||||
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.
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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).
|
|
||||||
|
|
||||||
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
|
|
||||||
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*.
|
|
||||||
|
|
||||||
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
|
|
||||||
(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.
|
|
||||||
|
|
||||||
## 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/`).
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
On peut maintenant démarrer le conteneur :
|
|
||||||
|
|
||||||
```
|
|
||||||
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).
|
|
||||||
|
|
||||||
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`.
|
|
||||||
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
|
|
||||||
## 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.
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
### 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.
|
|
||||||
|
|
||||||
Voici un extrait de configuration correspondant au paramétrage d'une interface
|
|
||||||
`eth0` pour un conteneur donné :
|
|
||||||
|
|
||||||
```
|
|
||||||
lxc.network.type = veth
|
|
||||||
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é.
|
|
||||||
|
|
||||||
|
|
||||||
### MACVLAN
|
|
||||||
|
|
||||||
Ici, le noyau va orienter les paquets en fonction de leur adresse MAC de
|
|
||||||
destination.
|
|
||||||
|
|
||||||
```
|
|
||||||
lxc.network.type = macvlan
|
|
||||||
lxc.network.macvlan.mode = bridge
|
|
||||||
lxc.network.flags = up
|
|
||||||
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.
|
|
||||||
|
|
||||||
Pour utiliser un type de stockage particulier, préciser lors de la création de
|
|
||||||
l'environnement du conteneur `-B [btrfs|zfs|lvm|...]`.
|
|
Loading…
Reference in New Issue
Block a user