Van Docker-Compose naar Docker Swarm: Configs
Docker Configs laat Docker Swarm onze (statische) configuratie beheren, geen gedeelde volumeopslag nodig.
U hebt een applicatie die bestaat uit een aantal Docker-Compose projecten en gebruikt Docker-Compose om te bouwen, starten en implementeren.
Nu wilt u een stap verder gaan en een aantal van de Docker-Compose projecten naar een andere server verplaatsen. De meest voor de hand liggende keuze om dit te doen, om eerst te proberen, is Docker Swarm. Je leert nog een paar Docker commando's en je bent klaar. Is het echt zo gemakkelijk?
Spoiler alert. Nee, het is niet eenvoudig als je containers hebt die volumes gebruiken, bijvoorbeeld voor configuratiegegevens, gegevens met hoge prestaties, persistente gegevens. Veel voorbeelden op het internet vermijden dit probleem volledig, of noemen terloops het gebruik van gedeelde opslagoplossingen zoals NFS (niet versleuteld) of GlusterFS, of gebruiken opslagoplossingen van cloud providers. Al deze opslagoplossingen hebben dezelfde eigenschap: Ze zijn netwerkgebaseerd en erg traag in vergelijking met native opslag. Ja, je kunt sneller gaan maar dan betaal je meer.
Voordat je Docker Swarm zelfs maar overweegt, raad ik je aan om over dit onderwerp te lezen om te begrijpen of jouw use case geschikt is voor Docker Swarm. Hier is bijvoorbeeld een discussie over 'Data(base) persistence in docker swarm mode', zie onderstaande links. En van deze Stackoverflow antwoord 'How does Docker Swarm implement volume sharing?', zie links hieronder:
Swarm Mode zelf doet niets anders met volumes, het voert elk volume mount-commando uit dat je opgeeft op het knooppunt waar de container draait. Als je volume mount lokaal is op dat knooppunt, dan worden je gegevens lokaal op dat knooppunt opgeslagen. Er is geen ingebouwde functionaliteit om gegevens automatisch tussen knooppunten te verplaatsen.
Dit betekent dat het mogelijk is om een mappenstructuur voor te bereiden op een worker node en ervoor te zorgen dat je een container alleen op dit node draait met behulp van de deploy placement parameters. Opties ...
In deze post gebruiken we Docker Swarm Configs om (statische) configuratiegegevens door te geven aan containers op worker nodes. Dit is een beetje een antipatroon, maar het mooie is dat we een opslagvereiste elimineren.
Zoals altijd draai ik op Ubuntu 22.04. Op dit moment gebruik ik Docker Desktop niet. Ik heb VirtualBox gebruikt om een Ubuntu server VM te maken en deze als worker te gebruiken.
Docker Swarm beheert geen volumegegevens!
Docker Swarm is een servicemanager en services zijn containers (gebaseerd op images), geen volumegegevens. Dit betekent dat je de volumegegevens zelf moet beheren.
Neem als voorbeeld een DSN-servercontainer. Deze maakt standaard verbinding met DNS-service A op het internet, geen externe gegevens hier.Met Docker Swarm kunnen we deze container implementeren, replica's specificeren, dat gaat heel eenvoudig.
Nu willen we dezelfde DSN-servercontainer verbinden met DNS-service B op het internet. We volgen de instructies van de containerbeheerder, maken twee (configuratie)bestanden aan, maken een volume mapping aan en we zijn klaar.
Deel van het Docker-Compose bestand:
...
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
...
Maar nu hebben we een probleem met Docker Swarm omdat het onze volumegegevens niet beheert! Als we de service op een worker node implementeren, zijn de gegevens, de configuratiebestanden, er niet!
Configuratiegegevens in de service 'bakken
Als we Docker Swarm gebruiken, hebben we geen gegevens in onze volumes ... als we niets doen. Er is een manier om dit te omzeilen, genaamd 'Configs', die niet beschikbaar is in Docker-Compose. We kunnen dit gebruiken om bestanden te specificeren die in de container worden gemount, net zoals we dat met volumes kunnen doen. We kijken eerst naar de Docker-Compose oplossing en wijzigen deze vervolgens in Docker Swarm.
Docker-Compose gebruiken
Wanneer we Docker-Compose gebruiken, gebruikt het bestand 'docker-compose.yml' voor ons DNS-serverproject, zie hierboven,
volumes en ziet het er ongeveer zo uit:
# 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"
We voegen een 'Dockerfile' toe:
# Dockerfile
FROM busybox
En bouwen de image:
docker-compose build
En dan draaien we het:
docker-compose up
De tekst die op het scherm wordt afgedrukt is:
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
Dit is zoals verwacht. Maar als Docker Swarm deze service zou deployen naar een andere host, een worker node, dan zouden onze bestanden ontbreken.
Docker Swarm gebruiken
Hier verwijderen we de 'volumes' sectie en voegen we de nieuwe 'configs' sectie toe:
# 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
Bouw de image:
docker-compose build
En dan deployen we:
docker stack deploy -c docker-compose.yml configs
Het resultaat van het deploy commando toont de creatie van de 'configs':
Creating network configs_default
Creating config configs_definitions2
Creating config configs_definitions1
Creating service configs_app
Er wordt niets afgedrukt op het scherm, om te zien wat er aan de hand is bekijken we het logboek van deze service:
docker service logs configs_app
Het resultaat:
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
Dit betekent dat de Docker Swarm manager onze bestanden correct heeft toegevoegd.
In mijn geval is de service geïnstalleerd op het knooppunt van de Docker Swarm manager, niet op het knooppunt van de worker. Om het op het worker node uit te voeren, voegen we het volgende toe aan 'docker-compose.yml':
deploy:
placement:
constraints:
- node.role == worker
replicas: 1
Tag je image en push het naar je Docker register.
Alleen als u een privé register gebruikt
Als je een privé, niet beveiligd, register gebruikt, moet je alle Docker knooppunten vertellen dat het niet beveiligd is door deze informatie toe te voegen:
{
"insecure-registries":[
"<your registry ip address>:<your registry port>"
],
}
aan het bestand toe te voegen:
/etc/docker/daemon.json
Herstart Docker nadat je dit gedaan hebt:
sudo systemctl restart docker
Belangrijk: Je moet dit op alle nodes doen.
Bewerk nu je 'docker-compose.yml' bestand om Docker Swarm te vertellen waar het je image vandaan kan halen.
Van:
...
services:
app:
image: busybox_configs:latest
...
To:
...
services:
app:
image: <registry host>:<registry port>/busybox_configs:latest
...
Deploy de service naar het worker knooppunt
Verwijder de service van dit knooppunt, als het er nog steeds is:
docker stack rm configs_app
En zet opnieuw uit:
docker stack deploy -c docker-compose.yml configs
Nu kun je controleren of de service draait op het worker node:
docker service ps configs_app
Het resultaat bevat het knooppunt, zie 'NODE':
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
xotczxp65lub configs_app.1 ... vmubs2204a Running Running 9 minutes ago
Je kunt meer informatie krijgen met bijvoorbeeld het commando:
docker service inspect --pretty configs_app
Oh, en het belangrijkste, wat heeft onze service precies gedaan? Er wordt niets afgedrukt op het scherm, we moeten naar de logboeken kijken:
docker service logs configs_app
Het resultaat is precies hetzelfde als voorheen. Dat betekent dat Docker Swarm niet alleen onze service (container) heeft uitgerold, maar ook onze 'configs' bestanden beschikbaar heeft gemaakt voor onze container die op de worker node draait. Gereed.
Samenvatting
In deze post hebben we Docker Configs gebruikt om (statische) configuratiegegevens door te geven aan containers. In 'docker-compose.yml' hebben we de sectie 'volumes' verwijderd en vervangen door de sectie 'configs' . Nu beheert Docker Swarm deze gegevens en hebben we hiervoor geen gedeeld opslagvolume nodig. Het vervelende is dat 'configs' niet werkt in Docker-Compose, wat betekent dat je afstapt van een enkele 'docker-compose.yml' die kan worden gebruikt door Docker-Compose en Docker Swarm.
Links / credits
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
Lees meer
Docker Docker-compose
Recent
- Database UUID primaire sleutels van je webapplicatie verbergen
- Don't Repeat Yourself (DRY) met Jinja2
- SQLAlchemy, PostgreSQL, maximum aantal rijen per user
- Toon de waarden in SQLAlchemy dynamische filters
- Veilige gegevensoverdracht met Public Key versleuteling en pyNaCl
- rqlite: een alternatief voor SQLite met hoge beschikbaarheid en distributed
Meest bekeken
- Met behulp van Python's pyOpenSSL om SSL-certificaten die van een host zijn gedownload te controleren
- Gebruik van UUIDs in plaats van Integer Autoincrement Primary Keys met SQLAlchemy en MariaDb
- Maak verbinding met een dienst op een Docker host vanaf een Docker container
- PyInstaller en Cython gebruiken om een Python executable te maken
- SQLAlchemy: Gebruik van Cascade Deletes om verwante objecten te verwijderen
- Flask RESTful API verzoekparametervalidatie met Marshmallow-schema's