En egen Docker registry med lastbalansering och high availability
Det har aldrig varit så enkelt att bygga lastbalanserade lösningar som nu med hjälp av Docker Swarm. Ännu smidigare blir det med Docker Stack och en enkel docker-compose.yml-fil. Här visar jag ett enkelt exempel på hur man kan bygga sin egen lastbalanserade Docker registry med tre noder på internet.
Docker Swarm sköter lastbalanseringen själv mellan noderna. För att vi även ska få DNS:en att automatiskt ta bort noder som ligger nere använder jag AWS Route53.
För att det ska vara möjligt att ha ett gemensamt lagringsutrymme för alla Docker registries i svärmen väljer jag att använda AWS S3 för lagringen.
Denna labben går att applicera på andra tjänster än bara Docker registry. Här har jag valt en registry för att det var smidigt att laborera med.
Förberedelser
Route53 / DNS
Här förutsätter jag att du redan har din domäns DNS hos Route53.
Börja med att skapa en Health Check för varje nod i Route53. Välj HTTPS som check, och ange IP-adresserna till dina noder. Eftersom vi ännu inte satt upp vår Docker registry-tjänst kommer Health Checkarna visa att noderna är nere. Men detta löser sig när vi fått upp vår Docker registry.
Steg två är att skapa tre A-records för din tänkta subdomän som du vill använda för din Docker registry. Jag väljer här registry.labs.cyberinfo.se. I den första A-recorden skriver du in IP-adressen för den första noden, nod1. Under Routing Policy väljer du Weighted. Under Weight skriver du 1, och under Set ID skriver du nod1. Under Associate with Health Check väljer du Yes, och väljer sen den Health Check som är för just denna noden.
Sätt TTL till 60 sekunder för att inte andra DNS:er ska cacha IP-adressen för länge (vi vill att felande noder snabbt ska plockas bort).
Repetera stegen för de andra två noderna, men skriv istället in de nodernas IP-adress och Set ID sätter du till nod2 och nod3. Välj samma Weight för alla, det vill säga 1. Detta gör att alla noderna kommer få ungefär lika mycket trafik. Internt kommer svärmen också att distribuera lasten jämnt över noderna.
Skapa en IAM-policy, en IAM-användare och en S3-bucket på Amazon AWS
Innan vi börjar med Docker kan vi förbereda en S3-bucket och en användare för den. Vi behöver även skapa en policy som bara har åtkomst till just den bucketen.
Jag skapar först en S3-bucket som jag för detta ändamålet döper till my-registry-bucket.
Därefter skapar jag en policy som ser ut enligt nedan och döper den till registry-lab.
Skapa därefter en ny IAM-användare och välj alternativet Programmatic access. Koppla den nya användaren till policyn du skapade ovan. Spara sedan din Access Key och Secret Key som du får.
Installera Docker
Först och främst behöver vi installera Docker på noderna om detta inte är redan är gjort. Hur man gör detta skiljer sig lite från system till system. Installationsanvisningar för de flesta Linuxdistributioner finns på Dockers webbsida.
Aktivera Docker Swarm
Som standard är inte Docker Swarm aktiverat. Här initialiserar jag Docker Swarm på den första noden, nod1. Denna nod blir automatiskt ledaren.
root@nod1~#> docker swarm init
Swarm initialized: current node (w8gg0fzdr6po7gqq3cu58bqtp) is now a
manager.
...
Jag vill att nod2 och nod3 ansluter sig till svärmen som managers (eftersom vi bara har tre noder). Jag skriver därför följande kommando på nod1.
root@nod1~#> docker swarm join-token manager
To add a manager to this swarm, run the following command:
docker swarm join --token SWMTKN-1-45p8k8bh6... 81.4.110.59:2377
Klistra in hela kommandot i nod2 och nod3 och kör det. Då kommer noderna att ansluta sig som managers till svärmen.
root@nod2~#> docker swarm join --token SWMTKN-1-45p8k8bh6... 81.4.110.59:2377
This node joined a swarm as a manager.
root@nod3~#> docker swarm join --token SWMTKN-1-45p8k8bh6... 81.4.110.59:2377
This node joined a swarm as a manager.
Certifikat
För att det ska gå att använda en Docker registry över ett nätverk eller över internet krävs det att anslutningen är säkrad med TLS. Det går även utan – om man kör i insecure mode – men det är inte rekommenderat.
Här utgår jag från att du redan har ett giltigt certifikat för din domän. Placera dina certifikat på nod1. Jag har döpt mitt certifikat till cert.crt och nyckeln till cert.key. För att vi ska kunna använda certifikaten på alla noderna – utan att själva behöva distribuera dem – lägger vi till dem som secrets i Docker.
root@nod1~#> cat cert.key | docker secret create key -
ggyr7tiqk0aygk1225yt4ilzz
root@nod1~#> cat cert.crt | docker secret create cert -
yenfbit23ulu69soz211bxlcn
Om du vill kontrollera att det fungerade kan du köra docker secret ls
. Du
ska nu se två stycken secrets i listan. Det ska gå att se dem med docker
secret ls
på samtliga noder.
Autentisering
Vi behöver också aktivera autentisering, annars hade vem som helst på internet
kunnat hämta och ladda upp images till din Docker registry. För detta använder
vi det vanliga verktyget htpasswd
. Denna finns redan i Docker-imagen för
Docker registry och vi kan därför använda den för att generera en lösenordsfil.
Kör följande på nod1, men byt ut användarnamnet och lösenordet till något du
själv väljer.
root@nod1~#> docker run --entrypoint htpasswd registry:2 -Bbn jackbenny hEmLiGt123 > htpass
Därefter ska vi lägga till lösenordsfilens innehåll som en secret i Docker. Detta gör vi med:
root@nod1~#> cat htpass | docker secret create htpass -
Återigen kan du kontrollera alla secrets med docker secret ls
.
Skapa compose-filen
Nu har det blivit dags att skapa docker-compose.yml-filen som vi sedan ska använda för att ta upp hela miljön. Det du behöver ändra på nedan är S3-fälten så att de matchar din användare, key, bucket och region. Du bör också ändra på HTTP_SECRET till något annat än mitt enkla exempel. Detta kan vara i princip vara vad som helst, men bör vara något långt och slumpmässigt.
I denna labb använder jag tre noder. Jag har därför specificerat replicas: 3 i filen. Detta gör att Docker Stack kommer att spinna upp tre stycken Docker registries.
Management-trafiken mellan noderna i svärmen är krypterad som standard. Men för att även den vanliga trafiken mellan noderna ska vara krypterad (över overlay-nätverket) specificerar jag nätverket manuellt i filen. Här aktiverar jag kryptering med encrypted. Då aktiveras IPSec över overlay-nätverket.
Starta upp allting
Nu har det blivit dags att starta upp allting.
På nod1 ger vi nu följande kommando:
root@nod1~#> docker stack deploy registry -c docker-compose.yml
Creating network registry_my-registry
Creating service registry_my-registry
Nu kan vi kontrollera så att allt ser rätt ut i svärmen med följande kommandon:
root@nod1~#> docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
w8gg0fzdr6po7gqq3cu58bqtp * nod1 Ready Active Leader 19.03.8
sa4kez0jkcs8g00s2dpvuxjvy nod2 Ready Active Reachable 19.03.8
vogsn1bh3tg95x41hncygnkvf nod3 Ready Active Reachable 19.03.8
root@nod1~#> docker stack ls
NAME SERVICES ORCHESTRATOR
registry 1 Swarm
root@nod1~#> docker stack ps registry
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
iydz1a6r4yi6 registry_my-registry.1 registry:2 nod2 Running Running 26 seconds ago
rxr4qdy17b0f registry_my-registry.2 registry:2 nod1 Running Running 26 seconds ago
i9unuiuvw0ib registry_my-registry.3 registry:2 nod3 Running Running 26 seconds ago
Allting ser således rätt ut.
Testa att allt fungerar
Nu har det blivit hög tid att testa att allt fungerar. Först och främst måste vi logga in på vår nya Docker registry. I mitt fall med mitt domännamn ser det ut som nedan.
jake@debian10:~$ docker login registry.labs.cyberinfo.se
Username: jackbenny
Password:
Login Succeeded
Inloggningen lyckades och vi kan gå vidare.
Om du skulle få ett felmeddelande om 503: Service unavailable så testa att skapa en tom fil i din S3-bucket. Filnamnet spelar ingen roll. Det är en bugg som jag sett att många har haft, inklusive jag själv.
För att testa att både ladda upp och ner en image från den egna Docker registryn, hämtar jag först hem en vanlig Ubuntu-image. Denna kommer jag sedan att ladda upp till min egna Docker registry. Därefter tar jag bort den lokalt från datorn, och laddar sen ner den igen från samma Docker registry.
jake@debian10:~$ docker image pull ubuntu:20.04
20.04: Pulling from library/ubuntu
...
docker.io/library/ubuntu:20.04
Nu när jag hämtat hem imagen lägger jag till en ny tagg för imagen för min nya registry.
jake@debian10:~$ docker image tag ubuntu:20.04 registry.labs.cyberinfo.se/ubuntu:20.04
Därefter testar jag att ladda upp den till min nya registry med docker image push
.
jake@debian10:~$ docker image push registry.labs.cyberinfo.se/ubuntu:20.04
The push refers to repository [registry.labs.cyberinfo.se/ubuntu]
8891751e0a17: Pushed
2a19bd70fcd4: Pushed
9e53fd489559: Pushed
7789f1a3d4e9: Pushed
...
Nu kan vi se att filerna finns i min S3-bucket som jag skapade tidigare. Ubuntu-katalogen finns under sökvägen /docker/registry/v2/repositories/ i S3-bucketen. Se bilden nedan.
Därefter raderar jag imagen helt från min lokala dator.
jake@debian10:~$ docker image rm ubuntu:20.04
...
jake@debian10:~$ docker image rm registry.labs.cyberinfo.se/ubuntu:20.04
...
Och till sist testar jag om det går att ladda ner imagen från min egna Docker registry.
jake@debian10:~$ docker image pull registry.labs.cyberinfo.se/ubuntu:20.04
20.04: Pulling from ubuntu
d51af753c3d3: Pull complete
fc878cd0a91c: Pull complete
6154df8ff988: Pull complete
fee5db0ff82f: Pull complete
...
registry.labs.cyberinfo.se/ubuntu:20.04
Allt fungerar således. Dessutom lastbalanserar svärmen trafiken mellan noderna på egen hand. Route53 kommer att rotera så att domännamnet pekar lika ofta på alla noder, men från samma dator kan man få samma IP i ett par minuter som svar. Men internt kommer trafiken distribueras mellan samtliga noder.
Test av high availability
För att testa HA-funktionen stänger jag ner nod1. Efter några minuter ska Route53 bara ge IP-adresserna för nod2 och nod3 som svar. Eftersom Docker Swarm sköter all lastbalansering själv, spelar det ingen roll vilken nod som trafiken kommer in på.
root@nod1~#> poweroff
På min arbetsstation testar jag först att pinga registry.labs.cyberinfo.se med jämna mellanrum för att se så jag bara får nod2 och nod3 som svar.
jake@debian10:~$ ping registry.labs.cyberinfo.se
PING registry.labs.cyberinfo.se (81.4.110.173) 56(84) bytes of data.
64 bytes from 81.4.110.173: icmp_seq=1 ttl=51 time=26.9 ms
jake@debian10:~$ ping registry.labs.cyberinfo.se
PING registry.labs.cyberinfo.se (81.4.109.77) 56(84) bytes of data.
64 bytes from 81.4.109.77: icmp_seq=1 ttl=52 time=24.9 ms
jake@debian10:~$ $ ping registry.labs.cyberinfo.se
PING registry.labs.cyberinfo.se (81.4.110.173) 56(84) bytes of data.
64 bytes from 81.4.110.173: icmp_seq=1 ttl=52 time=24.9 ms
Trafiken går således till bara till nod2 och nod3. Vi kan även kontrollera hur det ser ut i svärmen nu när en nod ligger nere. Följande kommando körs på nod2.
root@nod2~#> docker stack ps registry
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE
iydz1a6r4yi6 registry_my-registry.1 registry:2 nod2 Running Running 22 hours ago
gnu9x5eopxoq registry_my-registry.2 registry:2 nod3 Running Running about a minute ago
butpnatclq9l \_ registry_my-registry.2 registry:2 nod1 Shutdown Running 2 minutes ago
i9unuiuvw0ib registry_my-registry.3 registry:2 nod3 Running Running 29 minutes ago
Här ser vi att det fortfarande körs tre stycken replicas. Servicen med namnet registry_my-registry.2 som tidigare kördes på nod1 har nu flyttats över till nod3. Nod3 kör således två kopior nu.
Om vi tittar på noderna nu ser vi att vi nod1 är nere, och nod två har tagit över rollen som ledare.
root@nod2~#> docker nods ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
w8gg0fzdr6po7gqq3cu58bqtp nod1 Down Active Unreachable 19.03.8
sa4kez0jkcs8g00s2dpvuxjvy * nod2 Ready Active Leader 19.03.8
vogsn1bh3tg95x41hncygnkvf nod3 Ready Active Reachable 19.03.8
Nu är det dags att återigen radera den lokala Ubuntu-imagen och testa att ladda ner den från den egna registryn.
jake@debian10:~$ docker image rm registry.labs.cyberinfo.se/ubuntu:20.04
....
jake@debian10:~$ docker pull registry.labs.cyberinfo.se/ubuntu:20.04
20.04: Pulling from ubuntu
...
Status: Downloaded newer image for registry.labs.cyberinfo.se/ubuntu:20.04
registry.labs.cyberinfo.se/ubuntu:20.04
Registryn fungerar således fortfarande!
Balansera svärmen när nod1 kommer upp igen
När nod1 återansluter sig till svärmen kommer den inte automatiskt att få tillbaka den task (containern för Docker registry) den tidigare körde. Det är gjort så för att inte svärmen konstant ska balansera om sig och därmed orsaka störningar. Med tiden, när nya tasks skapas och försvinner, kommer svärmen att bli balanserad. Men i mitt fall vill jag att alla noder ska köra varsin Docker registry för HA. Jag kan därför manuellt be svärmen att balansera om sig med nedansående kommado.
root@nod1~#> docker service update --force registry_my-registry
registry_my-registry
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
Nu kör alla noder varsin Docker registry igen.
Lista dina images i Docker registryn
Det går att lista alla images som finns i registryn med curl
. I exemplet
nedan ser vi att jag har laddat upp några fler images.
jake@workstation~$> curl -u jackbenny https://registry.labs.cyberinfo.se/v2/_catalog
Enter host password for user 'jackbenny':
{"repositories":["debian","drupal","mycow","nginx","ubuntu"]}
Avslutning
Att göra något liknande med traditionella HA-lösningar (innan Docker och innan molnet) hade varit betydligt mer komplicerat och tidskrävande. Förmodligen hade det tagit dagar, kanske till och med veckor, att sätta upp denna labben. Här tog det mig istället i runda tal cirka två–tre timmar. I den tiden har jag räknat bort tiden det tog mig att göra research, men räknat in tiden för tester med mera. Dessutom kan jag enkelt flytta min labb till andra servrar eller andra molnleverantörer. Jag kan också enkelt utöka svärmen till att omfatta fler noder. Noderna kan befinna sig hos olika molnleverantörer, eller on-prem på egna servrar.
Nyhetsbrev
Nyhetsuppdateringar från tidningen direkt till din inkorg, helt kostnadsfritt. Avsluta när du vill.
Kommentarer
Kommentarsfältet är modererat. Det innebär att alla kommentarer granskas av ansvarig utgivare före publicering.
Du väljer själv om du vill ange ditt riktiga namn, en pseudonym eller vara helt anonym. Ingen registrering behövs.
Relaterade artiklar
-
Avlyssna trafik på servern med Wireshark och TShark
Wireshark är ett ovärderligt verktyg för att felsöka nätverkskonfigurationer, applikationer, API:er, demoner och mycket annat. I kombination med
tshark
kan vi dessutom avlyssna trafiken på en server i realtid. -
Var försiktig med att curl:a skript som root
Att installera program i Linux genom att omdirigera utdata från Curl till skalet är snabbt och smidigt. Men det är ack så farligt om du inte känner till programmet eller dess ursprung.
-
Vidarebefordran av SSH-agenten
SSH agent forwarding, eller vidarebefordran av SSH-agenten, innebär att man kan vidarebefordra SSH-agenten till ett fjärrsystem. På så sätt behöver man inte kopiera sin privata SSH-nyckel till fjärrsystemet, eller skapa flera nycklar för olika system. Men det finns risker med det.
-
Jenkins som ett alternativ till Ansible Tower
Ansible Tower kommer med en stor prislapp, speciellt för ett mindre företag eller en privatperson. AWX å andra sidan är helt fritt, men kräver numera Kubernetes. För den som vill automatisera sina Ansible Playbooks går det dock bra att använda Jenkins som en ersättning för Tower och AWX.
-
Hämta data från API:er med cURL och jq
Med cURL och jq går det att extrahera data från API:er direkt från kommandoraden. Jq är en JSON-tolkare och beskrivs av utvecklarna som sed och awk för JSON.
Senaste nyheterna och inläggen
-
Avlyssna trafik på servern med Wireshark och TShark
Wireshark är ett ovärderligt verktyg för att felsöka nätverkskonfigurationer, applikationer, API:er, demoner och mycket annat. I kombination med
tshark
kan vi dessutom avlyssna trafiken på en server i realtid. -
Mysig stämning på sommarens första demoparty
I helgen var det Reunion 2024 i Kvidinge Folkets hus, sommarens första skånska demoparty. Partyt organiserades av Jesper “Skuggan” Klingvall. På plats fanns ett 30-tal besökare.
-
Sommarens skånska demopartyn
Årets sommar bjuder på två skånska demopartyn. Först ut är Reunion i Kvidinge den 28–30 juni. Därefter är det Pågadata i Örtofta den 9–11 augusti.
-
Riskerna med BankID som ingen pratar om
BankID är ett säkert och smidigt sätt att identifiera sig online. Men i takt med dess ökade popularitet och användning har det blivit en svag länk – en single point of failure – på mer än ett sätt.
-
Polisernas fängelsedomar står fast
Efter tre år är målet mot de två poliser som olovligen tog sig in i en berusad mans bostad i Landskrona och misshandlade honom klart. Högsta domstolen beslutade den sjätte mars att avvisa överklagan. Fängelsedomarna för poliserna står därmed fast.
Utvalda artiklar
-
Mysig stämning på sommarens första demoparty
I helgen var det Reunion 2024 i Kvidinge Folkets hus, sommarens första skånska demoparty. Partyt organiserades av Jesper “Skuggan” Klingvall. På plats fanns ett 30-tal besökare.
-
Datorparty i Landskrona
I helgen höll Syntax Society sitt årliga sommarparty. Platsen var en källarlokal i Landskrona där ett femtontal personer medverkade.
-
Det första Pågadata har ägt rum
I helgen ägde det första Pågadata rum – uppföljaren till Gubbdata. Platsen var Folkets Hus i Kvidinge. Organisatör av partyt var Johan “z-nexx” Osvaldsson med hjälp från Jesper “Skuggan” Klingvall. Partyt hade över 100 anmälda deltagare.
-
Även hovrätten fäller poliserna för att ha satt dit oskyldig
Hovrätten fastställer straffet för de två poliser som förra året dömdes till vardera ett års fängelse av Lunds tingsrätt för att ha misshandlat och satt dit en oskyldig man. De båda poliserna ska även betala skadestånd till mannen.
-
Retroloppis i Påarp
Idag var det retroloppis hos Andreas Nilsson i Påarp. På baksidan av huset fanns hundratals spel uppradade på långa bord. Trots friska vindar och sval temperatur var loppisen välbesökt.
CyberInfo Sverige är ett it- och medieföretag i nordvästra Skåne som tillhandahåller böcker, utbildningar, nyheter och konsulttjänster inom Linux, säkerhet och programmering.
CyberInfo Sverige är godkänd för F-skatt, är momsregistrerat och innehar
utgivningsbevis för webbplatsen www.cyberinfo.se.