angle-uparrow-clockwisearrow-counterclockwisearrow-down-uparrow-leftatcalendarcard-listchatcheckenvelopefolderhouseinfo-circlepencilpeoplepersonperson-fillperson-plusphoneplusquestion-circlesearchtagtrashx

Van Docker-Compose naar Docker Swarm: Configs

Docker Configs laat Docker Swarm onze (statische) configuratie beheren, geen gedeelde volumeopslag nodig.

29 augustus 2023 Bijgewerkt 29 augustus 2023
In Docker
post main image

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

Laat een reactie achter

Reageer anoniem of log in om commentaar te geven.

Opmerkingen

Laat een antwoord achter

Antwoord anoniem of log in om te antwoorden.