Présentation donnée le 18 novembre 2015 au Paris Open Source Summit par Hervé Leclerc (Alterway) et Jérôme Petazzoni (Docker), présentant entre autres les nouvelles fonctionalités de Docker pour le stockage et le réseau arrivées dans la version 1.9 du Docker Engine.
3. Présentations
Hervé Leclerc (@hleclerc)
- CTO Alter Way
( Agnostique )
- Depuis 2006 chez Alter Way ntégrateur
100% Open Source ( Offre d’hébergement
basé sur Docker)
- Nuages de tags dans l’ordre préférence :
Docker, Ansible, Rancher, CI, Automatisation,
Industrialisation, Prometheus, Grafana, KVM
Jérôme Petazzoni (@jpetazzo)
- Sysadmin, développeur, évangéliste
(they told me I could be anything!)
- Chez Docker Inc. depuis bientôt 5 ans
(depuis l’époque dotCloud)
- Nuage de tags dans le désordre:
Docker, LXC, OpenVZ, Vserver, ØMQ, Solaris,
PaaS, Django, PostGIS, Plone, Asterisk, Zebra,
KVM, Xen, Golang...
3
4. - Pourquoi parler de stockage et réseau ?
- Différences techniques entre VMs et containers
- Le stockage (dans des VMs, dans des containers)
- Le réseau (dans des VMs, dans des containers)
- Conclusions
Plan de bataille
4
6. Virtualiser le processeur et la mémoire, c’est (relativement) facile.
Virtualiser le stockage et le réseau, c’est plus difficile, car :
- plusieurs composants doivent communiquer ensemble
(toujours pour le réseau, parfois pour le stockage)
- les défaillances peuvent être critiques
(perte de données, indisponibilité massive)
Notre environnement virtuel devient un système distribué. (Argh.)
Quelques rappels
6
8. - Ressemble à une machine physique
- séquence de boot
- noyau
- drivers
- SSH, cron, init ...
- Exécute du code pour un processeur donné
(généralement x86_64, mais pas que)
- Communique avec l’extérieur via des périphériques virtuels
(virtio chez les gens civilisés)
Machine virtuelle ...
8
9. - N’essaie pas de ressembler à une machine physique
- pas de boot, pas de noyau, pas de drivers
- pas de SSH, pas de cron, pas de systemd, pas de problème
- Se contente de faire tourner des processus
(qui tournent sur le noyau hôte comme des processus ordinaires)
- Exécute du code pour un processeur donné
(généralement x86_64, mais pas que)
- Communique avec l’extérieur via des appels système
(comme n’importe quel processus ordinaire)
Container ...
9
10. - N’essaie pas de ressembler à un ordinateur
- pas de noyau, pas de périphériques …
- juste une application Java !
- Exécute du bytecode Java
- Communique avec l’extérieur via l’API Java
Analogie : une JVM ...
10
11. Combien de containers peut-on mettre sur un Raspberry Pi 2?
2499 (dans 1 Go de RAM)
2740 (en patchant Docker)
Densité : containers > VMs
11
12. Processus dans un container = processus tout à fait ordinaire
Dans un container:
- pas d’émulation matérielle
- chemins critiques identiques pour les entrées/sorties
- performances identiques
Performances identiques, qu’on soit dans un container ou pas
(À condition d’utiliser les bons paramétrages)
Performances : containers > VMs
12
13. La surface d’attaque est beaucoup plus petite :
- VM → hyperviseur = hypercalls
(bien délimités ; ~40 pour Xen)
- container → noyau = syscalls
(plus de 300 ; certains sont corsés, e.g. ioctl, splice/tee/vmsplice ...)
Sortir d’une VM est plus difficile que sortir d’un container
(mais c’est loin d’être impossible)
La communication entre VMs se fait via le réseau
Isolation : VMs > containers
13
14. Des containers peuvent partager, sans aucun overhead :
- des fichiers et répertoires
- des sockets UNIX
- des segments de mémoire
Des containers peuvent avoir la même pile réseau
(interfaces réseau, routes, règles iptables, sockets ouvertes, etc.)
Ceci permet une meilleure séparation des tâches opérationelles
Communications : containers > VMs
14
15. Un container peut se concentrer sur l’essentiel (l’application)
Les tâches “ops” sont fournies par le runtime ou par d’autres containers :
- logs
- backups
- supervision
- connexion au réseau
- service discovery
- load balancing
Séparation des tâches opérationnelles
15
17. Deux écoles (deux églises?) :
- stockage local
(accessible uniquement par l’hyperviseur)
- stockage réseau
(accessible par plusieurs hyperviseurs)
Dans le monde des VMs
17
18. Disques locaux, “ephemeral storage”, “instance store” ...
Avantages :
- Simple, pas d’intermédiaire
- Performances faciles à maîtriser
- Pas de SPOF (autre que l’hyperviseur lui-même)
Inconvénients :
- Migrations pénibles (puisqu’il faut déplacer les données)
- L’hyperviseur est un SPOF
Stockage local
18
19. SAN, NAS, Ceph, Gluster, EBS, EFS …
Avantages :
- Migrations faciles (les données ne bougent pas)
- L’hyperviseur n’est plus un SPOF (pour l’accès aux données)
Inconvénients :
- L’unité de stockage reste un SPOF (sauf redondance active…)
- Le réseau peut devenir un problème (disponibilité, performances)
- Vous avez plein de nouveaux voisins ! (ibid.)
Stockage réseau
19
20. Bryan Cantrill:
“Network storage embodies a key design issue in architecting and operating a cloud:
The tension between economies of scale and overconsolidation of risk.”
https://www.joyent.com/blog/network-storage-in-the-cloud-delicious-but-deadly/
Richard Kiene:
“Try as they may to be redundant, OpenStack and Ceph architecturally force
non-obvious single points of failure [...] when used for virtual machine storage.
— SATApocalypse, https://ops.faithlife.com/?p=6
A méditer
20
21. - Les données doivent bien résider quelque part
(merci Captain Obvious!)
- Alors, stockage local ou réseau ?
- On peut (facilement) combiner les deux
Dans le monde des containers
21
22. Il n’y a aucun intérêt à mettre les choses suivantes sur le réseau :
- Système d’exploitation
- avec Docker, le système est réduit à sa plus simple expression
- il peut être identique sur un parc hétérogène (comme un hyperviseur)
- Images de containers
- en production, elles proviennent toujours d’une registry
- Fichiers temporaires
Si on met tout ça de côté, que reste-t-il ?
Stockage local
22
23. Concept Docker indiquant un répertoire partagé :
- entre un container et l’hôte
- entre plusieurs containers
- contenant des données “précieuses”
Exemple:
docker run -v /mnt/db01:/var/lib/mysql mysql
Volumes
23
24. Deux containers peuvent partager un répertoire.
Par exemple, pour des logs :
docker run --name webapp -v /logs jerome/webapp
Mon application web est configurée pour écrire ses logs dans /logs
docker run --volumes-from webapp jerome/logcollector
Cet autre container va “aspirer” les fichiers dans /logs et les envoyer ailleurs (ELK, Splunk…)
Volumes locaux (partage)
24
25. Les volumes permettent de migrer instantanément les données d’un container à l’
autre :
docker run --name monjoliredis redis:2.8
L’image redis spécifie que “/var/lib/redis” (qui contient les données) doit être placé sur un volume.
docker stop monjoliredis
docker run --volumes-from monjoliredis redis:3.0
Ce nouveau container va “hériter” du volume /var/lib/redis de l’ancien, et des données qu’il contient.
Volumes locaux (migration)
25
26. Vous vous rappelez notre premier exemple ?
docker run -v /mnt/db01:/var/lib/mysql mysql
Imaginons que “db01” est le nom d’un volume réseau (SAN ou autre…)
docker run -v db01:/var/lib/mysql mysql
Ça serait pratique si Docker pouvait le monter pour nous, au bon endroit,
automatiquement, pas vrai ?
Volumes distants
26
27. DEMO #1
Sur le premier Host Docker :
docker run --rm -it --volume-driver=nfs -v gfs2/nfs_volume:/app --name c1 ubuntu /bin/bash
docker run --rm -it --volume-driver=nfs -v gfs2/nfs_volume:/app --name c2 ubuntu /bin/bash
Vérification / Modification / Création / Suppression d’un fichier
Partage d’information entre container sur un système de fichier distant
DEMO #2
Sur le premier Host Docker :
docker run --rm -it --volume-driver=nfs -v gfs2/nfs_volume:/app --name c1 ubuntu /bin/bash
Sur le deuxième Host Docker :
docker run --rm -it --volume-driver=nfs -v gfs2/nfs_volume:/app --name c2 ubuntu /bin/bash
Vérification / Modification / Création / Suppression d’un fichier
Partage d’information entre containers sur hosts distincts sur un système de fichier distant
Volumes distants
27
28. Les volumes Docker sont maintenant des objets “de première classe”.
Un volume peut être créé indépendamment d’un container :
docker volume create --driver=xxx --name=yyy
Le volume sera mis a disposition (monté) par le driver.
Quelques drivers: Convoy, Flocker, Gluster, Keywhiz, PFS...
Récapitulatif
28
30. Plusieurs approches pour les services accessibles de l’extérieur :
- Adressage public sans fioritures
- Adressage public avec interfaces ou adresses flottantes
- Adressage interne + NAT + filtrage maison
Il faut souvent ajouter un load balancer opéré par le fournisseur.
(À ma connaissance, aucun cloud ne permet de faire tourner son propre load balancer dans des conditions de disponibilité
satisfaisantes, c’est-à-dire sans dépendre de l’API de l’opérateur pour effectuer le fail over)
Dans le monde des VMs
30
31. Là aussi, plusieurs approches :
- Rien du tout (utiliser les adresses et interfaces externes)
- Réseau interne partagé niveau 3
- Réseau privé niveau 3
- Réseau privé niveau 2
Dans le monde des VMs (traffic interne)
31
32. Plein de technos :
- VLAN
- QinQ
- TRILL
- VNI, VNT
- MPLS, VPLS
- VXLAN
- OSPF, IS-IS
- BGP
Dans le monde des VMs (coté opérateur)
32
33. Solution de facilité : une adresse IP publique par container
Ça aurait marché en 2003 …
Mais Docker est sorti en 2013 (un peu tard)
On doit donc faire face à un léger problème
Dans le monde des containers
33
37. Avantages :
- marche partout (pas de nouveau protocole, équipement, etc.)
Inconvénients :
- performances (iptables, bridge …)
- nécessité de spécifier hôte+port (au lieu de l’hôte seul)
- le DNS ne suffit plus
- problématique pour certains systèmes distribués
(qui ont besoin de plages de ports et/ou de connaître leur adresse IP)
Port Mapping
37
40. Des drivers fournissent des réseaux
Ces réseaux peuvent être :
- locaux à une machine (e.g.: le bridge actuel)
- globaux (e.g.: overlay)
À chaque réseau est associé une plage d’adresses IP
Les réseaux globaux s’appuient typiquement sur un mécanisme distribué pour
enregistrer et découvrir les réseaux, ainsi qu’allouer les adresses IP
Container Network Model
40
41. (dans le cadre de la demo)
b skynet skynet skynetbh h h
c1 c2 c3
ping c2
ping c3.skynet
docker run --ti -d --net=skynet alpine
Mettre en oeuvre le réseau Overlay avec Docker
41
42. #1
(d1) docker run -ti -d --name=A1 alpine /bin/sh
(d1) docker run -ti -d --name=A2 alpine /bin/sh
(d1) inspect --format '{{ .NetworkSettings.IPAddress }}' A1
(d1) inspect --format '{{ .NetworkSettings.IPAddress }}' A2
(d1) docker attach A2
(d1) cat /etc/hosts # (on note qu’il n’y a pas de mise à jour du fichier)
(d1) ping [IP de A1]
------------------------------------------------------------------------------------------------------------------------------------------------------------------
(d1) docker network create d1net
(d1) docker run -ti -d --name=B1 --net=d1net alpine /bin/sh
(d1) docker run -ti -d --name=B2 --net=d1net alpine /bin/sh
(d1) docker attach B2
(d1) cat /etc/hosts # (on note qu’il n’y a une mise à jour du fichier avec b1 et b1.d1.net)
(d1) ping [IP de A1] (pas de réponse)
(d1) ping B1.d1net (ping OK) # Attention les casse est importante avec alpine :(
------------------------------------------------------------------------------------------------------------------------------------------------------------------
(d1) docker network create -d overlay skynet
(d2) docker network ls
(d1) docker run -ti -d --name=C1 --net=skynet alpine /bin/sh
(d2) docker run -ti -d --name=C2 --net=skynet alpine /bin/sh
(d2) docker attach C2
(d2) cat /etc/hosts # (on note qu’il n’y a une mise à jour du fichier avec C1 et C1.skynet)
(d2) ping [IP de A1] (pas de réponse)
(d2) ping B1.d1net (pas de réponse)
(d2) ping C1.skynet (ping ok)
A1 A2
d1netB1 B2
skynet
C1
C2
Docket Host #1
Docket Host #2
Deux exemples d’utilisation de la libnetwork
42
43. Orchestrer le déploiement et l’utilisation d’une stack lamp
skynet
http
Docker #1
Docker #2
mysql
php-fpm
NFS
GlusterFS
EC2...
/var/www
/var/lib/mysql
80
bridge
#2Deux exemples d’utilisation de la libnetwork
43
45. Développeur :
- je fabrique un container pour mon application
- je ne m’occupe pas du stockage, du réseau, etc.
Opérateur :
- je lance des containers
- je n’ai pas besoin de les modifier
- j’effectue la “plomberie” stockage, réseau, de manière transparente
Docker + volume plugins + network drivers = ♥
Séparations des tâches
45