virli/tutorial/docker-orchestration/stack.md

177 lines
4.8 KiB
Markdown
Raw Normal View History

2017-10-16 01:10:34 +00:00
\newpage
Déploiement de services
=======================
2017-10-19 01:14:30 +00:00
## Services ?
Une petite minute terminologie avant de continuer, car lorsque l'on passe sur
les clusters de Docker, cela change un peu :
* une *tâche* correspond à **un** unique conteneur, lancé sur l'un des nœuds
*workers* du cluster ;
* un *service* est un groupe de tâches (oui, les tâches du point précédent),
exécutant la même image.
Les services sont donc très utiles lorsque l'on veut avoir de la redondance, de
la haute-disponibilité ou pour répartir la charge.
<div lang="en-US">
### Hello world, again?
</div>
Non, pas d'hello-world ici, mais nous allons prendre en main les services avec
un serveur web, qui sera bien plus représentatif de ce que l'on pourra obtenir.
Précédemment, nous lancions notre serveur web favori avec :
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```bash
docker container run --name mywebs -d nginx
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
La même commande, mais déployée à partir d'un nœud manager, vers un nœud
*workers*, est :
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```bash
docker service create --name myWebS nginx
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
Allons-y, essayons !
On peut consulter l'état du service avec, comme d'habitude `ls` :
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```
42sh$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
iyue3rgd0ohs myWebS replicated 1/1 nginx:latest
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
Vous pouvez constater que sur l'un des nœuds, sur lequel votre serveur aura été
déployé, le tâche apparaît dans la liste des conteneurs !
Rien de très excitant pour le moment, car nous ne pouvons pas vraiment accéder
à notre serveur. Essayons de modifier sa configuration en direct, afin
d'ajouter une redirection de port :
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```bash
docker service update --publish-add 80 myWebS
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
À chaque modification de configuration, les conteneurs lancés au sein du
service sont stoppés puis, le manager voyant que le service n'est pas dans
l'état demandé, va lancer des tâches avec la nouvelle configuration.
La commande `update` est très puissante : vous pouvez mettre à jour
pratiquement n'importe quel élément de configuration, y compris le nom de
l'image ou son tag. Grâce à cela, faire des mises à jour se fait de manière
transparente.
#### Magie du mesh
Lorsque l'on publie un port de cette manière, chaque nœud du cluster devient un
point d'entrée pour ce port, même si la tâche ne s'exécute pas sur ce nœud
particulièrement.
Essayons de nous connecter aux ports 80 des deux IP correspondant à nos deux
nœuds. Vous devriez voir la même page.
Lorsque plusieurs tâches s'exécutent pour ce service, le nœud d'entrée choisi
selon un round-robin à quelle tâche il va diriger la requête. C'est grâce à ce
mécanisme qu'il est possible faire une répartition de charge très simplement.
2018-10-19 23:51:35 +00:00
\vspace{1.5em}
2017-10-19 01:14:30 +00:00
Cette méthode n'est pas la seule permettant d'exposer des ports. Mais c'est
sans doute la plus intuitive. Si vous souhaitez en apprendre plus, vous deviez
consulter la
[documentation à ce sujet](https://docs.docker.com/engine/swarm/networking/).
### Mise à l'échelle et placement
On parle depuis toute à l'heure de lancer plusieurs tâches pour le même
service. La mise à l'échelle c'est ça : exécuter plusieurs conteneurs pour la
même tâche afin de mieux répartir la charge, idéalement sur des machines
physique différentes.
Ce qui se fait souvent avec beaucoup de douleur hors de Docker, se résume ici à
:
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```bash
docker service update --replicas 3 myWebS
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
Roulement de tambours .......
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```bash
docker service ps myWebS
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
nous montre bien, a priori 3 tâches en cours d'exécution pour ce service !
Enfin, vous avez compris le principe !
## Stack ?
Refermons cette longue parenthèse et revenons-en au sujet du jour : la
supervision de nos machines.
Une *stack* est un groupe de services. Un projet, par exemple un site web dans
son ensemble : frontend, API, base de données, ...
Notre système de monitoring est une *stack* lui aussi, d'ailleurs, nous pouvons
la lancer grâce à notre `docker-compose.yml` :
2018-10-19 23:51:35 +00:00
<div lang="en-US">
```bash
docker stack deploy --compose-file docker-compose.yml tic
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
### Règle de déploiement
Par rapport à `docker-compose`, nous pouvons indiquer dans ce fichier des
paramètres qui ne serviront qu'au déploiement de notre tâche.
2018-10-19 23:51:35 +00:00
<div lang="en-US">
2017-10-19 01:14:30 +00:00
```yaml
version: '3'
services:
redis:
image: redis:alpine
deploy:
replicas: 6
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
placement:
constraints:
- node.role == manager
resources:
memory: 50M
2017-10-19 01:14:30 +00:00
```
2018-10-19 23:51:35 +00:00
</div>
2017-10-19 01:14:30 +00:00
Certaines informations comme les ressources, permettent à l'orchestrateur de
mieux choisir le *workers* de destination, en fonction de certaines de ses
caractéristiques.