Dans cette présentation, nous donnons plusieurs réponses aux grandes questions classiques associées au déploiement avec Docker. Entre autres :
- comment orchestrer des déploiements non triviaux (plusieurs containers sur plusieurs machines) ?
- comment avoir des métriques sur les ressources utilisées par les containers ?
- comment optimiser les performances de Docker, en particulier pour des applications où ces performances sont critiques ?
- comment intégrer Docker avec des outils de "configuration management" comme Puppet, Chef, Salt, Ansible ?
- comment implémenter la "service discovery", ou, de manière générale, connecter entre eux plusieurs containers ?
La présentation a été donnée Lundi 8 Septembre à Paris dans les locaux de Zenika, cabinet spécialisé dans l'architecture informatique et les méthodes Agiles possédant une triple compétence de conseil, réalisation et formation.
Containerization is more than the new Virtualization: enabling separation of ...
Docker en Production (Docker Paris)
1. Ce bouquin n'est pas encore dans les bacs Docker Paris
Docker
en production
Des containers de la cave au grenier!
www.docker.com
@docker
2. Jérôme Petazzoni (@jpetazzo)
Pingouin grognon de service
- “Go away or I will replace you with a very small shell script”
Ces 3 dernières années : dotCloud PAAS
- EC2, LXC, Puppet, Python, Shell, ØMQ...
Contributeur Docker occasionel
- sécurité, réseau, --privileged
A tendance à mettre un peu tout et
n'importe quoi dans des containers
- Docker-in-Docker, VPN-in-Docker,
KVM-in-Docker, Xorg-in-Docker...
3. Plan
Rapide intro à Docker et la version 1.0
Ce qui marche bien : installation, build, distribution
Service discovery, interconnexion de containers
Orchestration (faire tourner plusieurs containers)
Performance (la mesurer, l'améliorer)
Configuration management
Les corvées du sysadmin : logs, backups, accès distant
4. Docker 1.0 1.1 1.1.1 1.1.2 1.2 est là !
Sortie de Docker 1.0 en juin pour DockerCon
Quelques fonctionalités récentes au pif :
- pause/unpause (pour avoir des snapshots et commits cohérents)
- SELinux (pour ce truc bizarre qu'on appelle “sécurité”)
- grosse amélioration du modèle réseau, avec docker run --net …
Et surtout : le label “prêt pour la prod'”
- en plus des traditionnels t-shirts et autres autocollants,
vous pouvez nous acheter du support, de la formation...
5. Installation
Sur une machine de dev : boot2docker
- toute petite VM (25 Mo), marche partout (tous hyperviseurs, dédié...)
- script pour OS X permettant de lancer la CLI en local
- prochaines améliorations : partage des volumes avec docker run -v …
Sur les serveurs : quelle distro choisir ?
- n'importe quoi de récent (Ubuntu 14.04 LTS, RHEL 7, Fedora 20...)
- nouvelles distros spécifiques Docker : CoreOS, Project Atomic
(prometteuses, mais encore très jeunes)
6. Build avec Dockerfiles
FROM ubuntu:14.04
MAINTAINER Docker Education Team <education@docker.com>
RUN apt-get update
RUN apt-get install -y nginx
RUN echo 'Hi, I am in your container'
>/usr/share/nginx/html/index.html
CMD [ "nginx", "-g", "daemon off;" ]
EXPOSE 80
7. Build avec Dockerfiles
Marche bien dans la plupart des cas
- le système de cache permet d'avoir un rebuild complet mais rapide
Inconvénients (c-à-d travaux en cours...)
- séparer l'environnement de build et celui de run
(histoire de ne pas déployer une image de 5 Go quand on a juste
besoin du binaire/JAR/etc. de 10 Mo qu'elle produit...)
- droits d'accès, identifiants, et autres informations sensibles
(que faire si le build a besoin d'accéder à une repo privée?)
Comment contourner ces problèmes
- utiliser deux Dockerfiles ; garder privés les Dockerfiles et les images
8. Distribuer les images
Docker Hub
- docker push à gauche, docker pull à droite : problème réglé !
- images publiques et privées ; droits d'accès ; etc.
- pas de version sur site ; mais c'est la demande la plus fréquente
(chez les grands comptes)
Héberger votre propre registry (=juste le stockage)
- docker run registry # “docker run -P” pour l'exposer sur le réseau
- par défaut : stockage sur le disque local
- peut utiliser un système de stockage “Cloud”
(par exemple Swift, GCE, S3, Elliptics...)
9. Distribuer les images
Bricoler avec docker load/save
- load/save va charger/exporter des images sous forme de tarballs
- ces tarballs peuvent être stockés n'importe où
- https://github.com/blake-education/dogestry (much image, such docker, wow)
En cours de développement : plug-ins de transport
- il y a des outils (comme git, rsync...) qui gèrent très bien les diffs
- pourrait-on les copier s'en inspirer les réutiliser ?
10. Service discovery
On a l'embarras du choix :
- injecter ce dont on a besoin sous forme de variable d'environnement
docker run -e DB_HOST=… -e DB_PORT=… -e …
- faire in bind-mount d'un fichier de configuration dans le container
docker run -v /etc/docker/config/myapp.yaml:/config.yaml …
- tout mettre dans une base clé-valeur redondante, à haute dispo
(zookeeper, etcd, consul...)
- tout mettre dans le DNS
(consul, skydns, skydock, dnsmasq...)
11. On a testé pour vous :
les 4 mécanismes de
Service Discovery pour
Docker au banc d'essai !
13. Docker links
docker run -d --name frontdb mysqlimage
docker run -d --link frontdb:sql webimage
Crée des entrées DNS dans les containers
Injecte des variables d'environnement dans le 2e :
SQL_PORT=tcp://172.17.0.10:5432
SQL_PORT_5432_TCP=tcp://172.17.0.10:5432
SQL_PORT_5432_TCP_ADDR=172.17.0.10
SQL_PORT_5432_TCP_PORT=5432
SQL_PORT_5432_TCP_PROTO=tcp
Les containers doivent être sur le même hôte Docker
14. Service discovery:
variables d'environnement
Facile à intégrer dans le code
- même Java supporte les variables d'environnement (je crois)
Facile à mettre en place
- démarrer les containers, récupérer les ports, injecter les variables
Encore plus facile si on utilise les links
- complètement automatique si on travaille en local avec un seul hôte
Mais : statique
- quand on déplace un container, on ne peut pas mettre à jour les
variables d'environnement à chaud
16. Service discovery:
bind-mount un fichier de configuration
Facile à intégrer dans le code
- même Ruby a un parser JSON/YAML potable (je crois)
Facile à mettre en place
- comme pour les variables d'environnement, mais on génère un fichier
Vaguement dynamique
- on peut mettre à jour le fichier de configuration pendant l'exécution
Mais en fait, non
- les services doivent détecter les modifications du fichier, et se relancer
18. Service discovery:
Base clé-valeur
Plus difficile à intégrer dans le code
- Faire des requêtes HTTP (plutôt qu'un simple getenv) n'est pas très
difficile, mais tout de même plus complexe
Plus difficile à mettre en place
- il faut déployer la base clé-valeur, sur plusieurs machines
Dynamique (en théorie)
- la plupart des bases clé-valeur permettent d'observer une valeur ou
un groupe de valeurs
Mais pas tant que ça (en pratique)
- les services doivent détecter les changements et recharger les clés
20. Service discovery:
DNS
Facile à intégrer dans le code
- la plupart du temps, il n'y a rien à faire, ça juste marche
Plus difficile à mettre en place*
- il faut mettre en place un DNS facile à mettre à jour
Dynamique
- il suffit de mettre à jour les zones DNS
Pas de notification (“push”) de changement, mais...
- en cas de problème (provoquant une déconnexion), l'application va
probablement se reconnecter en refaisant une requête DNS
*Sauf sur une machine isolée, quand on utilise les links ; car les links créent automatiquement des entrées DNS.
24. Les ambassadeurs
machine 1 (base de données)
docker run -d --name mabase imagemysql
docker run -d --link mabase:sql ambassadeur
machine 2 (serveur web)
docker run -d --name mabase ambassadeur
docker run -d --link mabase:sql imagenginx
25. serveur DB serveur web
container DB
Je suis “mabase” !
container web
Je veux parler à “mabase” !
ambassadeur
Moi, je parle vraiment
à “mabase” !
ambassadeur
Je prétends être “mabase” !
docker
linklink
docker
?
26. serveur DB serveur web
container DB
Je suis “mabase” !
container web
Je veux parler à “mabase” !
ambassadeur
Moi, je parle vraiment
à “mabase” !
ambassadeur
Je prétends être “mabase” !
docker
linklink
docker
??
27.
28. serveur DB serveur web
container DB
Je suis “mabase” !
container web
Je veux parler à “mabase” !
ambassadeur
Moi, je parle vraiment
à “mabase” !
ambassadeur
Je prétends être “mabase” !
docker
linklink
docker
LICORNES
29. Des licornes ? Sans blague ?
En travaux ; mais vous pouvez déjà jouer avec :
- Docksul
https://github.com/progrium/docksul
- Grand Ambassador
https://github.com/cpuguy83/docker-grand-ambassador
Ou faites votre propre implémentation, avec :
- une base clé-valeur à haute dispo (les revoilà!)
- HAProxy, stunnel, iptables...
(générer+relancer à chaque fois qu'on détecte un changement)
30. Service discovery:
links avec ambassadeurs
Facile à intégrer dans le code
- ça reste des variables d'environnement
Facile à mettre en place en dev' ; plus dur en prod'
- utilisez des links normaux en dev
- sortez l'artillerie lourde seulement pour la prod
Dynamique
- les ambassadeurs peuvent re-router le trafic si besoin
33. Orchestration
On a (encore) l'embarras du choix
- décrire les différents composants dans des fichiers YAML ou autre
(Fig, Maestro-NG, Ansible et autres systèmes de CM)
- requêter une API (Mesos, Helios, Kubernetes)
- implémenter un PAAS ou assimilé (Flynn, Deis, OpenShift, Tsuru)
- OpenStack (parce qu'on peut tout faire avec OpenStack même le café)
34. TEST :
comment déterminer le
système d'orchestration
Docker qu'il vous faut ?
35. Voulez-vous* utiliser OpenStack?
*ou devez-vous
Oui
- si vous voulez un PAAS, gardez un oeil sur Solum
(encore mieux : contribuez au développement du projet)
- si vous migrez des VMs vers des containers, utilisez Nova
(c'est probablement ce que vous avez déjà ; activez le driver Docker)
- sinon, utilisez Heat
(et déclarez simplement des ressources Docker dans vos templates)
Non
- tournez la page
36. Est-ce que vous voulez un PAAS?
Oui
- CloudFoundry (Ruby, but réécriture en Go en cours)
- Deis (Python, conçu pour Docker, tourne par-dessus CoreOS)
- Dokku (quelques centaines de ligne de Bash!)
- Flynn (Go, à la pointe de la technologie, mais très jeune)
- Tsuru (Go, plus mûr)
- OpenShift geard (encore du Go!)
Soyez prudents (ou tournez la page)
- http://blog.lusis.org/blog/2014/06/14/paas-for-realists/
“Je pense que pour l'instant, il n'y a aucun PAAS privé qui tienne la route.”
37. Combien de machines vous avez ?
Une seule par application ou par environnement
- Fig
Un peu (jusqu'à une dizaine)
- Maestro-NG
- votre outil de CM favori (par exemple, Ansible a un module Docker sympa)
Beaucoup (quelques centaines)
- Helios (bon compromis, mais encore pas mal d'opérations manuelles)
Moult (des milliers)
- Mesos (la version 0.20 du 3 septembre supporte Docker nativement)
- Kubernetes (mais attention, ça pique!)
38. En travaux : libswarm
Lancez un <truc> qui ...
- expose l'API Docker
- communique avec de “vrais” hôtes Docker
- démarre et arrête des hôtes Docker supplémentaires à la demande
- s'occupe de l'ordonnancement, la communication, le scaling ...
N'importe quel client Docker peut parler à ce <truc>
- ça ressemble à un hôte Docker
- mais c'est un hôte Docker élastique, évolutif, magique!
https://github.com/docker/libswarm
39. Performance : la mesurer
Grâce aux cgroups, on a pour chaque container...
- l'utilisation CPU
- l'utilisation mémoire détaillée (cache vs. resident set size)
- l'utilisation I/O (par périphérique, par lecture/écriture, en octets et en opérations)
Mais les cgroups ne donnent pas...
- l'utilisation réseau (il faut “ruser” avec les namespaces réseau)
https://github.com/google/cadvisor
http://jpetazzo.github.io/2013/10/08/docker-containers-metrics/
40. Performance : l'améliorer
Il n'y a pas grand chose à faire
- CPU : on a déjà des perfs natives
- I/O : les perfs sur les volumes sont natives
(assurez-vous de placer les données actives sur des volumes)
- mémoire : pas de surcoût si désactive le comptage de la mémoire
(utile pour les clusters de calcul ; probablement pas pour le reste)
- réseau : pas de surcoût pour les containers lancés avec “--net host”
(utile si on veut pousser plus de 1 Gb/s)
(ou si on a un taux élevé de paquets par seconde : VOIP, jeux...)
41. Configuration management
On a l'embarras du choix (c'est fou, non?)
Si vous n'utilisez pas de CM : continuez !
- Si vous utilisez, ou maîtrisez, un système de CM, vous pouvez l'utiliser
pour encoder des petits déploiement (jusqu'à une dizaine de noeuds)
Le CM, c'est bien pour les hôtes Docker
Mais pour les applis elles-mêmes, Dockerfiles = ♥
Si vous voulez vraiment utiliser vos configurations
actuelles, voilà comment les intégrer !
42. Configuration management,
pour mélanger VMs et containers
Faites une image Docker générique avec votre outil
de configuration management favori, prêt à tourner
Lancez des containers à partir de cette image, en
indiquant son identité (certificat/hostname/...)
Quand le container démarre, il contacte le serveur
(puppetmaster etc.), qui lui donne sa configuration
Le container converge vers l'état voulu
Inconvénients : c'est lent ; et c'est pas fiable à 100%
43. Configuration management,
pour mélanger VMs et containers
Faites une image Docker générique de configuration management NON
avec votre outil
favori, prêt à tourner
Lancez des containers FAIT, à partir de cette image, en
indiquant son identité (certificat/hostname/...)
Quand le EN container démarre, il contacte le serveur
(puppetmaster etc.), qui lui donne sa configuration
Le container converge vers l'état voulu
Inconvénients : c'est lent ; et c'est pas fiable à 100%
44. Configuration management,
en mode “immutable infrastructure”
Fabriquez une image Docker avec votre outil de CM
favori, et utilisez la comme base pour les autres
Pour les autres images :
FROM jerome/mon_image_puppet_de_base
ADD manifests/ /etc/puppet/manifests
RUN puppet apply --certname db1138.dystopia.io
Cette image est prête (pas besoin d'étape en plus!)
Inconvénient : il faut faire une nouvelle image à
chaque modification, même mineure
(ça peut être vu comme un avantage)
45. Configuration management,
en mode “immutable infrastructure”
Fabriquez une image Docker avec votre outil de CM
favori, et utilisez la comme base pour les autres
Pour les autres images :
FROM jerome/mon_image_puppet_de_base
ADD manifests/ /etc/puppet/manifests
RUN puppet apply --certname db1138.dystopia.io
Cette image est prête (pas besoin d'étape en plus!)
Inconvénient : il faut faire une nouvelle image à
chaque modification, même mineure
(ça peut être vu comme un avantage)
UN PEU MIEUX
(MAIS BOF QUAND MÊME)
46. Les corvées des sysadmins
Sauvegardes
Logs
Accès distant
Et il ne s'agit là que d'un petit échantillon des nombreux méfaits ennuyeux mais
nécessaires que les sysadmins doivent commettre de temps à autres...
47. Sauvegarder au niveau fichiers
Utilisez des volumes
docker run --name mysqldata -v /var/lib/mysql busybox true
docker run --name mysql --volumes-from mysqldata mysql
docker run --rm --volumes-from mysqldata mysqlbackup
tar -cJf- /var/lib/mysql | stream-it-to-the-cloud.py
Bien sûr, vous pouvez utiliser autre chose que tar
(par exemple rsync, tarsnap...)
48. Sauvegarder au niveau applicatif
Utilisez des links
docker run --name mysql mysql
docker run --rm --link mysql:db mysqlbackup
mysqldump --all-databases | stream-it-to-the-cloud.py
Peut être combiné avec des volumes
- mettez le dump SQL sur un volume
- puis sauvegardez le dump avec les outils de la page d'avant
49. Les logs à l'ancienne
À l'ancienne = et si j'écrivais quarante-douze miyards
de fichiers dans /var/lib/tomcat/logs ?
Solution : volumes
docker run --name logs -v /var/lib/tomcat/logs busybox true
docker run --name tomcat --volumes-from logs my_tomcat_image
- Inspecter les logs:
docker run --rm --volumes-from logs ubuntu bash
- Envoyer les logs quelquepart :
docker run --name logshipper --volumes-from logs sawmill
50. Les logs à la Docker
À la Docker = j'écris tout sur la sortie standard
Solution: Docker CLI/API
docker run --name tomcat dockerized_tomcat
docker logs tomcat
docker run -v /var/run/docker.sock:/var/run/docker.sock
logshipper docker logs tomcat | pipestash ...
Problème : pas de rotation des logs (pour l'instant)
51. Accès distant
Si vous avez accès à l'hôte : SSH dessus + nsenter
https://github.com/jpetazzo/nsenter
Si vous n'avez pas accès : SSHD dans le container
https://github.com/phusion/baseimage-docker
Pour en savoir plus sur la question
(“Pour ou contre le démon SSH dans le container?”)
http://blog.docker.com/2014/06/why-you-dont-need-to-run-sshd-in-docker/
À l'avenir :
- lancer un container SSH à part
- se connecter dessus
- rebondir vers le container cible
52. Ce bouquin n'est pas encore dans les bacs Merci !
Docker
en production
Des containers de la cave au grenier!
Questions ?
www.docker.com
@docker