Categories

Formation docker

ssh dockeradmin@docker-8-a.westeurope.cloudapp.azure.com

dockeradmin/D@cker@Azure2017

Docker : Ateliers pratiques
Auteur : Loïc THOBOIS (lthobois@live.com)

Table des matières
1)	Installation de Docker	2
a)	Compte de connexion	2
b)	Configuration de l'hôte	2
c)	Configuration du dépôt Docker	2
d)	Installation de Docker Community Edition	2
2)	Initiation aux conteneurs	3
a)	Présentation d'un conteneur	3
b)	Création d'une image	3
c)	Exploitation applicative standard	4
d)	Exploitation applicative du stockage	5
e)	Déploiement d’un conteneur LAMP	5
3)	Conception des images avec Dockerfile	5
a)	Création d'une image à l'aide de DockerFile	5
b)	Optimisation de la création des images	6
c)	Créer une image mongodb à l’aide de la description GitHub	6
d)	Création d’une image LAMP	7
4)	Administration de la registry	7
a)	Navigation dans le Docker Hub	7
b)	Envoi de l'image sur le docker hub	7
c)	Création d’un registre privé	7
d)	Administration du registre	8
5)	Docker Compose	8
a)	Installation de docker-compose	8
b)	Création d’un projet docker-compose	8
c)	Créer un projet LAMP piloté par Docker compose	9
6)	Exploitation des conteneurs	9
a)	Configuration du réseau en mode bridge	9
b)	Configuration du réseau en mode hôte	10
c)	Configuration du réseau en mode join	10
d)	Configuration du réseau en mode link	10
e)	Différentes références en mode	10
f)	Gestion du stockage	10
g)	Déploiement d’un frontal web d’administration	11
7)	Docker Machine	11
a)	Déploiement des nœuds	11
8)	Docker Swarm	11
a)	Configuration de la ferme Swarm	11
b)	Déploiement des services Swarm	12
c)	Déploiement d’une stack de service	13
d)	Déploiement d’un frontal web d’administration	14


1)	Installation de Docker
a)	Compte de connexion
# Connexion SSH (Linux)
ssh dockeradmin@ docker-<id>-a.westeurope.cloudapp.azure.com

# Compte des démos
dockeradmin
D@cker@Azure2017

# Afficher et analyser les sources de Docker
https://get.docker.com

b)	Configuration de l'hôte

# Délégation des droits admin Docker
sudo su
D@cker@Azure2017

c)	Configuration du dépôt Docker
# Documentation d’installation
https://docs.docker.com/install/linux/docker-ce/debian/
# Mise à jour des références du dépôt local
apt-get update

# Installation des prérequis pour la connexion au dépôt en HTTPS (Debian Jessie ou Stretch)
apt-get install \
     apt-transport-https \
     ca-certificates \
     curl \
     software-properties-common

# Ajout de la clé GPG officielle Docker
curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add -

# Vérification que la clé est 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
apt-key fingerprint 0EBFCD88
#pub   4096R/0EBFCD88 2017-02-22
#      Key fingerprint = 9DC8 5822 9FC7 DD38 854A  E2D8 8D81 803C 0EBF CD88
#uid                  Docker Release (CE deb) <docker@docker.com>
#sub   4096R/F273FCD8 2017-02-22

# Configuration du dépôt stable de docker
add-apt-repository \
   "deb [arch=amd64] https://download.docker.com/linux/debian \
   $(lsb_release -cs) \
   stable"

d)	Installation de Docker Community Edition

# Mise à jour avec le nouveau dépot
apt-get update

# Liste des versions disponibles de Docker CE
apt-cache madison docker-ce

# Installation de la dernière version de Docker
apt-get install docker-ce

# Affiche la version de Docker
docker version

# Liste des commandes Docker
docker help

2)	Initiation aux conteneurs
a)	Présentation d'un conteneur

# Execution du conteneur Hello-World
docker run hello-world

# Afficher et analyser le dépot officiel et public
https://hub.docker.com/
https://hub.docker.com/_/hello-world/

# Affiche les images présentes localement
docker images

# Affichage de l’OS du système hôte
>cat /etc/os-release

# Lance le conteneur ubuntu de manière interactive avec l'invite bash
docker run -i -t ubuntu /bin/bash

# Affichage de l’OS au sein du conteneur
>cat /etc/os-release

# Suppression d'un répertoire dans le conteneur puis sorti du conteneur
>ls
>rm -fr /home
>ls
>exit

# Le répertoire n'est pas supprimé sur l'hôte
ls /

# Affiche les conteneurs en cours d'exécution
docker ps

# Voir tous les conteneurs présents
docker ps -a

# Supprime le conteneur (f pour force et v pour volume)
docker rm -fv <container id>

# Lance puis supprime le conteneur dès sa sortie
docker run --rm hello-world

# Voir qu’aucun conteneur n’est présent
docker ps -a

# Lancer un conteneur et lancer la commande env dedans
docker run --rm ubuntu env

 # Lancer un conteneur et injecter une variable d’environnement
docker run --rm -e LANGUAGE=fr_FR ubuntu env

# Créer un fichier de paramètre
nano env-list.txt
LANG_FR=fr_FR
LANG_EN=en_US

# Lancer un conteneur et injecter une variable d’environnement
docker run --rm --env-file=env-list.txt ubuntu env

b)	Création d'une image

# Lance le conteneur ubuntu de manière intéractive avec comme nom test
docker run -it --name test ubuntu

# Personnaliser un conteneur
>ls
>cd home
>apt-get update
>apt-get install nano
>nano coucou
>ls
>exit

# Voir tous les conteneurs en cours
docker ps -a

# Afficher les modifications du conteneur
docker diff test

# Enregistre le conteneur en tant que nouvelle image
docker commit test ubuntuamoi:1.0

# Affiche la liste des images
docker images

# Supprime le conteneur test
docker rm -fv test

# Lance le conteneur ubuntuamoi
docker run -it --name test ubuntuamoi:1.0

# Affiche le contenu du conteneur
>ls
>cd home
>ls
>exit

# Supprime le conteneur
docker rm -fv test

c)	Exploitation applicative standard

# Créer un premier site web sur la machine hôte
mkdir /home/dockeradmin/web1
cd /home/dockeradmin/web1
nano index.html
<html><head><title>Docker 1</title></head><body><h1>Hello Web from Docker !</h1></body></html>

# Lance un conteneur en mode détaché de l'image nginx avec mapping réseau et stockage en lecture seule
docker run -d --name web1 -v /home/dockeradmin/web1:/usr/share/nginx/html:ro -p 80:80 nginx

# Affiche l'état des conteneurs et les informations de mapping
docker ps

# Affiche le site web
http://<adresse ip>

# Affiche les logs de nginx dans le conteneur
docker logs web1

# Créer un second site web sur la machine hôte
mkdir /home/dockeradmin/web2
cd /home/dockeradmin/web2
nano index.html
<html><head><title>Docker 2</title></head><body><h1>Hello Web 2 from Docker !</h1></body></html>

# Lance une seconde instance du conteneur pour l'image nginx avec mapping réseau et stockage en lecture seule
docker run -d --name web2 -v /home/dockeradmin/web2:/usr/share/nginx/html:ro -p 88:80 nginx

# Affiche le site web
http://<url>:88

# Liste des processus du conteneur
docker top web2

# Arrêt du conteneur
docker stop web1

# Affiche le site web
http://<url>

# Démarrage du conteneur
docker start web1

# Affiche le site web
http://<url>

# Redémarrage du conteneur
docker restart -t 20 web1

# Lance une instance de l'image nginx
docker run -d --name webkill nginx

# Arrêt brutal du conteneur webkill
docker kill -s 9 webkill

# Suppression des conteneurs
docker rm -vf web1
docker rm -vf web2

d)	Exploitation applicative du stockage

# Création du répertoire de donnée
mkdir /home/dockeradmin/data

# Lance le conteneur bd pour l'image mongodb
docker run -d --name bd -p 27017:27017 -v /home/dockeradmin/data:/data/db mongo

# Affiche les logs de mongodb dans le conteneur
docker logs bd

# Installation client mongo sur le serveur hôte
apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 0C49F3730359A14518585931BC711F9BA15703C6

echo "deb http://repo.mongodb.org/apt/debian jessie/mongodb-org/3.4 main" | tee /etc/apt/sources.list.d/mongodb-org-3.4.list

apt-get update

apt-get install mongodb-org-shell

# Connexion au mongodb du conteneur
mongo

# Personnalisation du contenu de mongodb
use mydb
db.Personnes.insert({"nom":"THOBOIS","prenom":"Loïc"});
db.Personnes.find();
exit

# Analyse de la configuration du conteneur et des mappages disques
docker inspect bd

# Suppression du conteneur
docker rm -fv bd

# Lancer une nouvelle instance du conteneur bd
docker run -d --name bd -p 27017:27017 -v /home/dockeradmin/data:/data/db mongo

# Connexion au mongodb du conteneur
mongo

# Vérifiez que l’entrée est présente
use mydb
db.Personnes.find();
exit

e)	Déploiement d’un conteneur LAMP

A faire en autonomie :

En vous appuyant sur l’image de base de Debian, créez un conteneur contenant Apache, MySQL et PHP 5 ainsi qu’une page par défaut phpinfo().

Quelles sont les difficultés rencontrées ?
3)	Conception des images avec Dockerfile
a)	Création d'une image à l'aide de DockerFile

# Créer un répertoire image
mkdir /home/dockeradmin/demoimage
cd /home/dockeradmin/demoimage

# Créer un fichier script
nano demoimage.sh

#! /bin/bash
if [ -z "$TIMEWAIT" ]; then
    echo "Veuillez saisir la variable TIMEWAIT";
    return 1;
fi

while true;
do
    echo $1 \($(date +%H:%M:%S)\);
    sleep "$TIMEWAIT";
done

# Créer un fichier Dockerfile
nano Dockerfile

FROM ubuntu:latest
MAINTAINER Loic THOBOIS "lthobois@live.com"

COPY demoimage.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

ENV TIMEWAIT 2
ENTRYPOINT ["/entrypoint.sh"]
CMD ["demoimage"]

# Vérifier qu'aucune image demo n'existe
docker images | grep demo

# Compilation de l'image à partir du contexte du répertoire en cours
 docker build -t lthobois/demoimage:1.0 .

# Afficher la nouvelle image
 docker images

# Lancer un conteneur de notre nouvelle image
 docker run -it --name demo lthobois/demoimage:1.0
# Pour détacher le conteneur: Ctrl<p> - Ctrl<q>.

# Supprimer le conteneur
 docker rm -fv demo

# Lancer un conteneur en spécifiant une variable d’environnement
 docker run -it --name demo -e TIMEWAIT=1 lthobois/demoimage:1.0

# Supprime tous les conteneurs, A NE PAS FARE EN PRODUCTION
 docker rm -fv `docker ps -aq`

b)	Optimisation de la création des images

# Supprime l'image
 docker rmi lthobois/demoimage:1.0

# Compilation de l'image et analyse de l’utilisation du cache de compilation
 docker build -t lthobois/demoimage:1.0 .

# Affiche toutes les couches de compilation
 docker images -a

# Affiche les détails de compilation
 docker history <container id>

# Changez le demoimage à 3 dans le fichier Dockerfile
nano Dockerfile

# Build en utilisant les caches de build precedent
 docker build -t lthobois/demoimage:1.1 .

# Changez le message echo
nano demoimage.sh

# Build en utilisant le nouveau fichier et analyse de l’utilisation du cache de compilation
 docker build -t lthobois/demoimage:1.2 .

c)	Créer une image mongodb à l’aide de la description GitHub
# Créer un répertoire mongodb
mkdir /home/dockeradmin/mongodb
cd /home/dockeradmin/mongodb

# Créer un fichier script
nano docker-entrypoint.sh

<Contenu du fichier docker-entrypoint.sh du site https://github.com/docker-library/mongo/tree/master/3.6>

# Créer un fichier Dockerfile
nano Dockerfile

<Contenu du fichier Dockerfile du site https://github.com/docker-library/mongo/tree/master/3.6>
# Compilation de l’image mongodb
 docker build .

# Affiche toutes les couches de compilation
 docker images -a

# Affiche les détails de compilation
 docker history <image id>

# Associe un tag à la nouvelle image
 docker tag <image id> lthobois/mongo

d)	Création d’une image LAMP

A faire en autonomie :

En vous appuyant sur l’image de base de Debian et à l’aide d’un fichier Dockerfile, créez une image contenant Apache, MySQL et PHP 5 ainsi qu’une page par défaut phpinfo().

Quelles sont les difficultés rencontrées ?
4)	Administration de la registry
a)	Navigation dans le Docker Hub

# Affichez le contenu du portail
https://hub.docker.com/
Cliquez sur Explore, puis sur nginx.
Analysez le DockerFile et son image source
Analysez les sources

# Aide sur la recherche
docker search --help

# Recherche des images mongo
docker search mongo

# Recherche des images mongo ayant au moins 100 étoiles
docker search -s 100 mongo

b)	Envoi de l'image sur le docker hub

# Créer un compte sur le portail Docker Hub
https://hub.docker.com/

# Entrez votre compte Docker Hub
docker login

# Notez l’image ID
docker images

# Tag l'image en latest
docker tag <IMAGE_ID> <login>/demoimage:latest

# Envoi dans le dockerhub
docker push <login>/demoimage

c)	Création d’un registre privé

# Lancez une instance du registre
docker run -d --name registre -p 88:5000 registry

# Affichez le web services par défaut
http://<adresse_ip>:88/v2/_catalog

# Ajoutez le tag d’envoi vers le nouveau registre
docker tag <login>/demoimage localhost:88/demoimage

# Affiche toutes les images
docker images -a

# Envoi de l’image vers le nouveau registre
docker push localhost:88/demoimage

# Affichez le web service par défaut
http://<adresse_ip>:88/v2/_catalog

d)	Administration du registre

A faire en autonomie :

Identifiez le répertoire de stockage du conteneur registre
Lancez une nouvelle instance du registre en mappant le répertoire de stockage sur l’hôte
Envoyez de nouveau l’image dans le registre
Observez le contenu du répertoire mappé
5)	Docker Compose
a)	Installation de docker-compose
# Téléchargez les sources de docker-compose
curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose

# Autorisez l'execution du script
chmod +x /usr/local/bin/docker-compose

# Affichez la version du script
docker-compose --version

# Affichez l'aide de docker-compose
docker-compose --help

b)	Création d’un projet docker-compose
# Créer le répertoire du projet
mkdir /home/dockeradmin/compose
cd /home/dockeradmin/compose

# Créer le fichier docker-compose du projet
nano docker-compose.yml

site:
  build: site
  ports :
   - "80:80"
  volumes:
   - /home/dockeradmin/web1:/var/www/html/
  links:
   - database
phpmyadmin:
   image: corbinu/docker-phpmyadmin
   ports :
    - "8080:80"
   environment:
    - MYSQL_USERNAME=root
    - MYSQL_PASSWORD=password
   links:
    - database:mysql
database:
  image: mysql:5.5
  ports:
   - "3306:3306"  
  environment:
     - MYSQL_ROOT_PASSWORD=password
     - MYSQL_DATABASE=mysite
     - MYSQL_USER=mysite
     - MYSQL_PASSWORD=password

# Créer le répertoire de l'image site
mkdir /home/dockeradmin/compose/site
cd /home/dockeradmin/compose/site

# Créer le fichier Dockerfile du site
nano Dockerfile

FROM php:5.6-apache
 
RUN docker-php-ext-install pdo mysql
RUN docker-php-ext-install pdo mysqli
 
RUN usermod -u 1000 www-data
 
RUN a2enmod rewrite

# Position sur le répertoire du projet
cd /home/dockeradmin/compose

# Affiche le fichier de configuration
docker-compose config

# Build des composants du site
docker-compose build

# Lancer le projet
docker-compose up

# Se connecter au seveur web
http://<url>/

# Se connecter à phpmyadmin
http://<url>:8080/

# Stopper le projet
Ctrl<C>

# Lancer le projet de manière autonome
docker-compose up -d

# Affichez les conteneurs du projet
docker-compose ps

# Affichez les conteneurs actifs
docker ps

# Arrêter les conteneurs du projet
docker-compose stop

# Supprimer les conteneurs avec les volumes associés
docker-compose down --volumes

c)	Créer un projet LAMP piloté par Docker compose

A faire en autonomie :

Créez deux images à l’aide de Dockerfile correspondant à Apache-PHP et MySQL
Créez un fichier docker-compose pour les piloter.
6)	Exploitation des conteneurs
a)	Configuration du réseau en mode bridge

# Affichage de l'adresse IP du serveur hôte
ip a

# Affichage de l'adresse IP du premier conteneur
docker run --name ip1 -d nginx:1.11
docker exec -ti ip1 ip a

# Affichage de l'adresse IP du second conteneur
docker run --name ip2 -d nginx:1.11
docker exec -ti ip2 ip a

# Test de connectivité entre les conteneurs
docker exec -ti ip2 ping <adresse ip1>

# Test d'isolation de la pile TCP/IP
docker run --rm --name ip3 ubuntu:trusty netstat -al

# Test de l'ajout d'une entrée dans le fichier host
docker run -it --add-host avaedos:8.8.8.8 debian
ping avaedos
ip a
exit

# Test de l'isolation réseau
docker run -it --net none debian
ping www.avaedos.com
exit

# Supprimer tous les conteneurs
docker rm -vf `docker ps -qa`

b)	Configuration du réseau en mode hôte

# Installation du navigateur en ligne de commande
apt-get install lynx

# Lancement du serveur Web en mode classique
docker run --name ipconteneur -d nginx:1.11
docker exec -ti ipconteneur ip a

# Test du conteneur sur l'adresse du conteneur
lynx 172.17.0.<x>

# Test du conteneur sur l'adresse de l'hôte
lynx 172.17.0.1

# Test du conteneur sur l'adresse ip publique
http://<adresse ip publique>

# Supprimer tous les conteneurs
docker rm -vf `docker ps -qa`

# Lancement du serveur Web en liaison réseau locale (hôte)
docker run -d --name iplocal --net host nginx:1.11
docker exec -ti iplocal ip a

# Test du conteneur sur l'adresse de l'hôte
lynx 172.17.0.1

# Test du conteneur sur l'adresse ip publique
http://<adresse ip publique>

docker run -d --name iplocal2 --net host nginx:1.11
docker exec -ti iplocal2 ip a
docker logs iplocal2

c)	Configuration du réseau en mode join

# Supprimer tous les conteneurs
docker rm -vf `docker ps -qa`

# Lance un serveur web
docker run -d --name join1 -p 8080:80 nginx:1.11
docker exec -ti join1 ip a

# Affichage l'état de la pile TCP/IP
docker run --rm --name join2 --net container:join1 ubuntu:trusty netstat -al

# Affichage l'adresse IP
docker run --rm --name join2 --net container:join1 ubuntu:trusty ip a


d)	Configuration du réseau en mode link

# Supprimer tous les conteneurs
docker rm -vf `docker ps -qa`

# Lance un serveur web
docker run -d --name link1 -p 8080:80 nginx  

# Lance un serveur web
docker run --rm -it --name link2 --link link1:serveurweb ubuntu:trusty

# Affiche les alias dynamiques
cat /etc/hosts

# Affiche les variables d'environnements
env | grep SERVEURWEB

exit

e)	Différentes références en mode

https://docs.docker.com/engine/reference/run/
https://docs.docker.com/engine/userguide/networking/


f)	Gestion du stockage

mkdir /var/mongodb
mkdir /var/mongodb/data

docker run -d --name dbloc -v /var/mongodb/data:/data/db -p 27017:27017 mongo

# Lien vers le premier conteneur
docker run -it --name linkvol --volumes-from dbloc:ro ubuntu
cd /data/db
ls
exit

# Supprimer tous les conteneurs sans les volumes
docker rm -f `docker ps -qa`

# Liste des volumes orphelins
docker volume ls -qf dangling=true

# Nettoyage des volumes orphelins
docker volume prune

g)	Déploiement d’un frontal web d’administration
A faire en autonomie :

Déployez la solution Rancher d’administration des conteneurs :
https://hub.docker.com/r/rancher/server/
Attention car le chargement du conteneur peut prendre entre 7 et 10 minutes pour se finaliser.
Pensez à afficher les logs du conteneur pour voir l’état d’avancement.
Ajoutez le serveur à la solution via les indications du site.
Arrêtez mais ne supprimez pas le conteneur.

7)	Docker Machine 
a)	Déploiement des nœuds

# Installation de Docker machine Linux
https://docs.docker.com/machine/install-machine/
 
curl -L https://github.com/docker/machine/releases/download/v0.14.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine && 
cp /tmp/docker-machine /usr/local/bin/docker-machine

# Affiche la version
docker-machine version

# Afficher les options
docker-machine
 
# Afficher la liste des options de création
docker-machine create --help

# Déploiement dans Azure (envoyer le code à l’adresse lthobois@live.com)
docker-machine create --driver azure --azure-subscription-id 49abf506-5486-4971-bd94-c0e35de0a68c --azure-location WestEurope --azure-size Standard_A1 --azure-open-port 2377 --azure-open-port 80 --azure-open-port 8080 swarm-<id>-ld
docker-machine create --driver azure --azure-subscription-id 49abf506-5486-4971-bd94-c0e35de0a68c --azure-location WestEurope --azure-size Standard_A1 --azure-open-port 2377 --azure-open-port 80 --azure-open-port 8080 swarm-<id>-n1
docker-machine create --driver azure --azure-subscription-id 49abf506-5486-4971-bd94-c0e35de0a68c --azure-location WestEurope --azure-size Standard_A1 --azure-open-port 2377 --azure-open-port 80 --azure-open-port 8080 swarm-<id>-n2
docker-machine create --driver azure --azure-subscription-id 49abf506-5486-4971-bd94-c0e35de0a68c --azure-location WestEurope --azure-size Standard_A1 --azure-open-port 2377 --azure-open-port 80 --azure-open-port 8080 swarm-<id>-n3

# Liste des nœuds déployés
docker-machine ls

# Récupérer et notez les adresses IP
docker-machine ip swarm-<id>-ld
docker-machine ip swarm-<id>-n1
docker-machine ip swarm-<id>-n2
docker-machine ip swarm-<id>-n3
8)	Docker Swarm

a)	Configuration de la ferme Swarm

# Créer la ferme Docker Swarm
docker-machine ssh swarm-<id>-ld
docker swarm init
docker swarm join-token worker
exit

# Ajout des noeuds
docker-machine ssh swarm-<id>-n1
docker swarm join --token <token> <ip leader>:2377
exit

docker-machine ssh swarm-<id>-n2
docker swarm join --token <token> <ip leader>:2377
exit

docker-machine ssh swarm-<id>-n3
docker swarm join --token <token> <ip leader>:2377
exit

# Ajout d'un noeud de gestion supplémentaire
docker-machine ssh swarm-<id>-ld
docker node promote swarm-<id>-n1

docker node update --role manager swarm-<id>-n2
docker node ls

docker node update --role worker swarm-<id>-n2
docker node ls

# Création du réseau Swarm
docker-machine ssh swarm-<id>-ld
docker network create -d overlay demo_net

# Liste des réseau
docker network ls

b)	Déploiement des services Swarm

# Ajout d'un service
docker service create --name frontend -d --replicas 4 -p 8080:80 --network demo_net lthobois/frontend
docker service ps frontend

# Ajout d'un service
docker service create --name backend -d --replicas 2 --network demo_net lthobois/backend
docker service ps backend

# Affichage de l'état
docker service ls

#Test du site
http://<ip swarm-<id>-ld>:8080
http://<ip swarm-<id>-n1>:8080
http://<ip swarm-<id>-n2>:8080
http://<ip swarm-<id>-n3>:8080

# Mise à jour des paramètres des services
docker service update -d --env-add COLOR=purple --update-delay 30s --update-parallelism 1 frontend
docker service update -d --env-add COLOR=orange --update-delay 30s --update-parallelism 1 backend

#Test du site
http://<ip swarm-<id>-ld>:8080
http://<ip swarm-<id>-n1>:8080
http://<ip swarm-<id>-n2>:8080
http://<ip swarm-<id>-n3>:8080

# Mise à jour du nombre d'instance du backend
docker service scale backend=4

# Affichage de l'état
docker service ls

# Mise à jour du nombre d'instance du frontend
docker service scale frontend=2

#Test du site
http://<ip swarm-<id>-ld>:8080
http://<ip swarm-<id>-n1>:8080
http://<ip swarm-<id>-n2>:8080
http://<ip swarm-<id>-n3>:8080

# Suppression des services
docker service rm frontend
docker service rm backend

c)	Déploiement d’une stack de service

docker-machine ssh swarm-<id>-ld

mkdir /home/docker-user/stack
cd /home/docker-user/stack
nano docker-compose.yml

# Analyser le contenu du projet à déployer
https://github.com/dockersamples/example-voting-app

# Copier le contenu suivant
-----
version: "3"

services:

  redis:
    image: redis:3.2-alpine
    ports:
      - "6379"
    networks:
      - voteapp
    deploy:
      placement:
        constraints: [node.role == manager]

  db:
    image: postgres:9.4
    volumes:
      - db-data:/var/lib/postgresql/data
    networks:
      - voteapp
    deploy:
      placement:
        constraints: [node.role == manager]

  voting-app:
    image: lthobois/voting-app-vote:latest
    ports:
      - 80:80
    networks:
      - voteapp
    depends_on:
      - redis
    deploy:
      mode: replicated
      replicas: 2
      labels: [APP=VOTING]
      placement:
        constraints: [node.role == worker]

  result-app:
    image: lthobois/voting-app-result:latest
    ports:
      - 8080:80
    networks:
      - voteapp
    depends_on:
      - db

  worker:
    image: lthobois/voting-app-worker:latest
    networks:
      voteapp:
        aliases:
          - workers
    depends_on:
      - db
      - redis
    # service deployment
    deploy:
      mode: replicated
      replicas: 2
      labels: [APP=VOTING]
      # service resource management
      resources:
        # Hard limit - Docker does not allow to allocate more
        limits:
          cpus: '0.25'
          memory: 512M
        # Soft limit - Docker makes best effort to return to it
        reservations:
          cpus: '0.25'
          memory: 256M
      # service restart policy
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      # service update configuration
      update_config:
        parallelism: 1
        delay: 10s
        failure_action: continue
        monitor: 60s
        max_failure_ratio: 0.3
      # placement constraint - in this case on 'worker' nodes only
      placement:
        constraints: [node.role == worker]

networks:
    voteapp:

volumes:
  db-data:
-----

# Lancer la stack de service
docker stack deploy --compose-file docker-compose.yml mystack

# Affichage de la liste des stack
docker stack ls

# Affichage des services de la stack
docker stack ps mystack 

# Affichage des services
docker service ls

# Affichage du site et mise en valeur du réseau distribué
exit

docker-machine ip swarm-ld
http://<ip-swarm-ld>
http://<ip-swarm-ld>:8080

docker-machine ip swarm-n1
http://<ip-swarm-n1>
http://<ip-swarm-n1>:8080

docker-machine ip swarm-n2
http://<ip-swarm-n2>
http://<ip-swarm-n2>:8080

docker-machine ip swarm-n3
http://<ip-swarm-n3>
http://<ip-swarm-n3>:8080

# Suppression de la stack
docker stack rm mystack

d)	Déploiement d’un frontal web d’administration
A faire en autonomie :

Ajoutez les nœuds du cluster Swarm à la solution Rancher d’administration des conteneurs :
https://hub.docker.com/r/rancher/server/