De Docker-Composer à Docker Swarm : Configs
Docker Configs gérons notre configuration (statique), sans avoir besoin d'un volume de stockage partagé.
Vous avez une application composée d'un certain nombre de projets Docker-Compose, et vous utilisez Docker-Compose pour construire, démarrer et déployer.
Vous souhaitez maintenant aller plus loin et déplacer certains des projets Docker-Compose vers un autre serveur. Le choix le plus évident pour ce faire, et à essayer en premier, est Docker Swarm. Vous apprenez quelques autres commandes Docker et vous avez terminé. Est-ce vraiment si simple ?
Alerte au spoiler. Non, ce n'est pas facile si vous avez des conteneurs qui utilisent des volumes, par exemple, pour les données de configuration, les données de haute performance, les données persistantes. De nombreux exemples sur Internet évitent complètement ce problème, ou mentionnent simplement l'utilisation de solutions de stockage partagé comme NFS (non crypté) ou GlusterFS, ou utilisent des solutions de stockage provenant de fournisseurs de cloud. Toutes ces solutions de stockage présentent les mêmes caractéristiques : Elles sont basées sur le réseau et très lentes par rapport au stockage natif. Oui, vous pouvez aller plus vite, mais vous paierez plus cher.
Avant même d'envisager Docker Swarm, je vous recommande de lire sur ce sujet pour comprendre si votre cas d'utilisation est adapté à Docker Swarm. Par exemple, voici une discussion à ce sujet, 'Data(base) persistence in docker swarm mode', voir les liens ci-dessous. Et à partir de cette réponse Stackoverflow , réponse 'How does Docker Swarm implement volume sharing?', voir les liens ci-dessous :
Swarm Mode lui-même ne fait rien de différent avec les volumes, il exécute n'importe quelle commande de montage de volume que vous fournissez sur le nœud où le conteneur est en cours d'exécution. Si votre montage de volume est local à ce nœud, alors vos données seront sauvegardées localement sur ce nœud. Il n'existe pas de fonctionnalité intégrée permettant de déplacer automatiquement les données entre les nœuds.
Cela signifie qu'il est possible de préparer une structure de répertoire sur un nœud de travail, et de s'assurer que vous exécutez un conteneur uniquement sur ce nœud en utilisant les paramètres de placement de déploiement. Options ...
Dans ce billet, nous utilisons Docker Swarm Configs pour passer des données de configuration (statiques) aux conteneurs sur les noeuds de travail. C'est un peu un anti-modèle, mais l'avantage est que nous éliminons un besoin de stockage.
Comme toujours, je travaille sur Ubuntu 22.04. Pour le moment, je n'utilise pas Docker Desktop. J'ai utilisé VirtualBox pour créer un serveur Ubuntu VM et l'utiliser comme worker.
Docker Swarm ne gère pas les données de volume !
Docker Swarm est un gestionnaire de services et les services sont des conteneurs (basés sur images), pas des données en volume. Cela signifie que vous devez gérer vous-même les données de volume.
Prenons l'exemple d'un conteneur de serveur DSN. Avec Docker Swarm, nous pouvons déployer ce conteneur, spécifier des répliques, et le faire facilement.
Maintenant, nous voulons que le même conteneur de serveur DSN se connecte au service DNS B sur internet. Nous suivons les instructions du responsable du conteneur, nous créons deux fichiers (de configuration), nous créons un mappage de volume, et nous avons terminé.
Partie du fichier Docker-Compose :
...
services:
dns_service:
image: ...
volumes:
- ./config/definitions1.conf:/opt/dns_server/config/definitions1.conf:ro
- ./config/definitions2.conf:/opt/dns_server/config/definitions2.conf:ro
...
Mais nous avons maintenant un problème avec Docker Swarm parce qu'il ne gère pas nos données de volume ! Si nous déployons le service sur un nœud de travailleur, les données, les fichiers de configuration, ne sont pas là !
Intégrer les données de configuration dans le service
Lorsque nous utilisons Docker Swarm, nous n'avons pas de données dans nos volumes ... si nous ne faisons rien. Il existe un moyen de contourner ce problème, appelé 'Configs', qui n'est pas disponible dans Docker-Compose. Nous pouvons l'utiliser pour spécifier les fichiers qui seront montés dans le conteneur comme nous pouvons le faire avec les volumes. Nous examinerons d'abord la solution Docker-Compose, puis nous la modifierons en Docker Swarm.
Utilisation de la solution Docker-Compose
Lorsque nous utilisons Docker-Compose, le fichier 'docker-compose.yml' pour notre projet de serveur DNS, voir ci-dessus,
utilise des volumes et ressemble à quelque chose comme :
# docker-compose.yml, using volumes
version: '3.7'
services:
app:
image: busybox_volumes
build: .
volumes:
- ./config/definitions1.conf:/opt/dns_server/config/definitions1.conf:ro
- ./config/definitions2.conf:/opt/dns_server/config/definitions2.conf:ro
command: sh -c "ls -l /opt/dns_server/config && cat /opt/dns_server/config/definitions*.conf && tail -f /dev/null"
Nous ajoutons un 'Dockerfile' :
# Dockerfile
FROM busybox
Et nous construisons l'image :
docker-compose build
Puis nous l'exécutons :
docker-compose up
Le texte imprimé à l'écran est le suivant :
app_1 | total 8
app_1 | -rw-rw-r-- 1 1000 1000 14 Aug 29 08:06 definitions1.conf
app_1 | -rw-rw-r-- 1 1000 1000 14 Aug 29 08:06 definitions2.conf
app_1 | definitions=1
app_1 | definitions=2
C'est ce à quoi on s'attendait. Mais si Docker Swarm déployait ce service sur un autre hôte, un nœud de travail, nos fichiers seraient manquants.
Utilisation de Docker Swarm
Ici, nous supprimons la section 'volumes' et ajoutons la nouvelle section 'configs' :
# docker-compose.yml, using configs
version: '3.7'
services:
app:
image: busybox_configs
build: .
configs:
- source: definitions1
target: /opt/dns_server/config/definitions1.conf
- source: definitions2
target: /opt/dns_server/config/definitions2.conf
command: sh -c "ls -l /opt/dns_server/config && cat /opt/dns_server/config/definitions*.conf && tail -f /dev/null"
configs:
definitions1:
file: ./config/definitions1.conf
definitions2:
file: ./config/definitions2.conf
Construire l'image :
docker-compose build
Puis nous déployons :
docker stack deploy -c docker-compose.yml configs
Le résultat de la commande deploy montre la création de la section 'configs' :
Creating network configs_default
Creating config configs_definitions2
Creating config configs_definitions1
Creating service configs_app
Rien n'est imprimé à l'écran, pour voir ce qui se passe nous regardons le journal de ce service :
docker service logs configs_app
Le résultat :
configs_app.1.vqumgq21leq8@myra | total 8
configs_app.1.vqumgq21leq8@myra | -r--r--r-- 1 root root 14 Aug 29 09:58 definitions1.conf
configs_app.1.vqumgq21leq8@myra | -r--r--r-- 1 root root 14 Aug 29 09:58 definitions2.conf
configs_app.1.vqumgq21leq8@myra | definitions=1
configs_app.1.vqumgq21leq8@myra | definitions=2
Cela signifie que le gestionnaire Docker Swarm a correctement ajouté nos fichiers.
Dans mon cas, le service a été déployé sur le nœud manager Docker Swarm , pas sur le nœud travailleur. Pour l'exécuter sur le nœud de travail, nous ajoutons ce qui suit à 'docker-compose.yml' :
deploy:
placement:
constraints:
- node.role == worker
replicas: 1
Marquez votre image et envoyez-la à votre registre Docker .
Uniquement si vous utilisez un registre privé
Si vous utilisez un registre privé, non sécurisé, vous devez indiquer à tous les nœuds Docker qu'il n'est pas sécurisé en ajoutant cette information :
{
"insecure-registries":[
"<your registry ip address>:<your registry port>"
],
}
au fichier :
/etc/docker/daemon.json
Redémarrez Docker une fois cette opération effectuée :
sudo systemctl restart docker
Important : Vous devez effectuer cette opération sur tous les nœuds.
Maintenant, éditez votre fichier 'docker-compose.yml' pour indiquer à Docker Swarm où il peut obtenir votre image.
De :
...
services:
app:
image: busybox_configs:latest
...
A :
...
services:
app:
image: <registry host>:<registry port>/busybox_configs:latest
...
Déployer le service sur le noeud de travail
Supprimez le service de ce nœud, s'il y est encore :
docker stack rm configs_app
Et déployez à nouveau :
docker stack deploy -c docker-compose.yml configs
Vous pouvez maintenant vérifier que le service fonctionne sur le nœud de travail :
docker service ps configs_app
Le résultat contient le nœud, voir 'NODE' :
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xotczxp65lub configs_app.1 ... vmubs2204a Running Running 9 minutes ago
Vous pouvez obtenir plus d'informations, par exemple avec la commande :
docker service inspect --pretty configs_app
Oh, et le plus important, qu'a fait notre service exactement ? Rien n'est imprimé à l'écran, nous devons regarder les journaux :
docker service logs configs_app
Le résultat est exactement le même que précédemment. Cela signifie que Docker Swarm a non seulement déployé notre service (conteneur), mais a également mis nos fichiers 'configs' à la disposition de notre conteneur fonctionnant sur le noeud de travail. C'est fait.
Résumé
Dans cet article, nous avons utilisé Docker Configs pour passer des données de configuration (statiques) aux conteneurs. Dans 'docker-compose.yml', nous avons supprimé la section 'volumes' et l'avons remplacée par la section 'configs' . Désormais, Docker Swarm gère ces données et nous n'avons pas besoin d'un volume de stockage partagé à cette fin. L'inconvénient est que 'configs' ne fonctionne pas dans Docker-Compose, ce qui signifie que vous vous éloignez d'un seul 'docker-compose.yml' qui peut être utilisé par Docker-Compose et Docker Swarm.
Liens / crédits
Data(base) persistence in docker swarm mode
https://forums.docker.com/t/data-base-persistence-in-docker-swarm-mode/20665
Deploy a stack to a swarm
https://docs.docker.com/engine/swarm/stack-deploy
Docker - configs
https://docs.docker.com/compose/compose-file/compose-file-v3/#configs
Docker Swarm Tutorial | Code Along | Zero to Hero under 1 Hour
https://takacsmark.com/docker-swarm-tutorial-for-beginners
How does Docker Swarm implement volume sharing?
https://stackoverflow.com/questions/47756029/how-does-docker-swarm-implement-volume-sharing
En savoir plus...
Docker Docker-compose
Récent
- Masquer les clés primaires de la base de données UUID de votre application web
- Don't Repeat Yourself (DRY) avec Jinja2
- SQLAlchemy, PostgreSQL, nombre maximal de lignes par user
- Afficher les valeurs des filtres dynamiques SQLAlchemy
- Transfert de données sécurisé grâce au cryptage à Public Key et à pyNaCl
- rqlite : une alternative à haute disponibilité et dist distribuée SQLite
Les plus consultés
- Utilisation des Python's pyOpenSSL pour vérifier les certificats SSL téléchargés d'un hôte
- Utiliser UUIDs au lieu de Integer Autoincrement Primary Keys avec SQLAlchemy et MariaDb
- Connexion à un service sur un hôte Docker à partir d'un conteneur Docker
- Utiliser PyInstaller et Cython pour créer un exécutable Python
- SQLAlchemy : Utilisation de Cascade Deletes pour supprimer des objets connexes
- Flask RESTful API validation des paramètres de la requête avec les schémas Marshmallow