Introduktion
Forudsætninger
Hvem er jeg
Opsætning af Traefik
Hvordan det virker
Introduktion
Docker Swarm forvandler dine individuelle servere til en klynge af computere; letter skalering, høj tilgængelighed og belastningsbalancering. Swarm load-balancer implementerer en round-robin load-balance-strategi, og dette kan forstyrre den korrekte funktion af (legacy) stateful-applikationer, som kræver en form for klæbrige sessioner for at tillade en høj-tilgængelig opsætning med flere instanser. Docker Enterprise Edition understøtter Layer-7 sticky session, men i denne guide vil vi fokusere på den gratis (CE) version af Docker. For at implementere klæbrige sessioner bruger vi Traefik.
Forudsætninger
- Mindst to nyligt installerede og opdaterede Debian 9-instanser i samme undernet med privat netværk aktiveret
- Docker CE installeret på disse forekomster
- Forekomsterne skal være en del af den samme Swarm og skal kunne kommunikere med hinanden over det private netværk
- Forudgående kendskab til Docker og Docker Swarm
- En ikke-root-bruger med
sudo
rettigheder (valgfrit, men det anbefales kraftigt ikke at bruge root-brugeren)
I denne vejledning vil vi bruge to Vultr-instanser med private IP-adresser 192.168.0.100
og 192.168.0.101
. Begge af dem er Docker Swarm manager noder (som ikke er ideel til produktion, men nok til denne tutorial).
Hvem er jeg
Denne vejledning bruger jwilder/whoami
docker-billedet som et demoprogram. Denne simple container vil reagere på et REST-kald med navnet på den reagerende container, hvilket gør det meget nemt at teste, om de klæbrige sessioner virker. Dette billede bruges naturligvis kun til demoformål og skal erstattes af dit eget programs billede.
Whoami-tjenesten er konfigureret som følger:
sudo docker network create whoaminet -d overlay
sudo docker service create --name whoami-service --mode global --network whoaminet --publish "80:8000" jwilder/whoami
sudo iptables -I INPUT 1 -p tcp --dport 80 -j ACCEPT
Hvis vi efterfølgende curl
whoami REST-endepunktet på http://192.168.0.100/
, kan vi se round-robin belastningsbalanceringen af Docker Swarm på arbejde:
curl http://192.168.0.100
I'm a6a8c9294fc3
curl http://192.168.0.100
I'm ae9d1763b4ad
curl http://192.168.0.100
I'm a6a8c9294fc3
curl http://192.168.0.100
I'm ae9d1763b4ad
curl http://192.168.0.100
I'm a6a8c9294fc3
Det nytter ikke at teste dette med moderne browsere som Chrome eller Firefox, fordi de er designet til at holde forbindelserne i live, og Docker Swarm load-balancer vil kun skifte til den anden container ved hver ny forbindelse. Hvis du vil teste dette med en browser, skal du vente mindst 30 sekunder på, at forbindelsen lukker, før du opdaterer igen.
Opsætning af Traefik
Traefik understøtter indbygget Docker Swarm, det kan registrere og registrere eller afregistrere containere på farten, og det kommunikerer med din applikation via det interne overlejringsnetværk. Traefik har brug for nogle oplysninger om din ansøgning, før den kan begynde at behandle anmodninger om den. Disse oplysninger gives til Traefik ved at tilføje etiketter til din Swarm-tjeneste:
sudo docker service update --label-add "traefik.docker.network=whoaminet" --label-add "traefik.port=8000" --label-add "traefik.frontend.rule=PathPrefix:/" --label-add "traefik.backend.loadbalancer.stickiness=true" whoami-service
Følgende liste beskriver, hvad hver etikett betyder:
traefik.docker.network
: Docker-overlejringsnetværket, via hvilket Traefik kommunikerer med din tjeneste
traefik.port
: Porten, som din tjeneste lytter til (dette er den internt eksponerede port, ikke den offentliggjorte port)
traefik.frontend.rule
: PathPrefix:/
binder kontekstroden ' /
' til denne tjeneste
traefik.backend.loadbalancer.stickiness
: Aktiverer klæbrige sessioner for denne tjeneste
Nu hvor den whoami-service
er blevet konfigureret med de nødvendige etiketter, kan vi tilføje Traefik-tjenesten til sværmen:
sudo docker service create --name traefik -p8080:80 -p9090:8080 --mount type=bind,source=/var/run/docker.sock,destination=/var/run/docker.sock --mode=global --constraint 'node.role == manager' --network whoaminet traefik --docker --docker.swarmmode --docker.watch --web --loglevel=DEBUG
Denne kommando gør en hel del ting på én gang, som vist i følgende liste:
--name traefik
: Vores nye Docker-tjeneste hedder Traefik
-p8080:80
: Vi udgiver Traefiks port 80
til port, 8080
fordi port 80
allerede er i brug af vores whoami-service
-p9090:8080
: Vi udgiver Traefiks egen webgrænseflade til port 9090
--mount ...
: Vi monterer Docker Socket i containeren, så Traefik kan få adgang til værtens Docker runtime
--global
: Vi ønsker Traefik-containere på hver managerknude af høje tilgængelighedsårsager
--constraint 'node.role == manager'
: Vi ønsker kun, at Traefik skal køre på managerknudepunkter, fordi arbejdsknudepunkter ikke kan give Traefik den information, den har brug for. For eksempel docker service ls
virker en arbejderknude ikke, så Traefik ville ikke engang være i stand til at opdage, hvilke tjenester der kører
--network whoaminet
: Tilslut Traefik til samme netværk som vores whoami-service
, ellers kan den ikke oprette forbindelse til den. Vi har tidligere bedt Traefik om at oprette forbindelse til vores tjeneste via dette netværk med traefik.docker.network
etiketten
traefik
: Bed docker om at bruge det seneste Traefik docker-billede til denne tjeneste
--docker --docker.swarmmode --docker.watch --web --loglevel=DEBUG
: Kommandolinjeargumenter sendt direkte til Traefik for at tillade det at køre i Docker swarm mode. DEBUG
er valgfrit her, men interessant under opsætningen og til denne vejledning
Det eneste, der er tilbage at gøre, er at åbne de nødvendige porte i Debians firewall:
sudo iptables -I INPUT 1 -p tcp --dport 8080 -j ACCEPT
sudo iptables -I INPUT 1 -p tcp --dport 9090 -j ACCEPT
Hvordan det virker
Så snart Traefik starter op, kan du se i loggene, at Traefik opdager de to whoami
containere. Den udsender også cookienavnet, som den vil bruge til at håndtere den klæbrige session:
time="2018-11-25T13:17:30Z" level=debug msg="Configuration received from provider docker: {\"backends\":{\"backend-whoami-service\":{\"servers\":{\"server-whoami-service-1-a179b2e38a607b1127e5537c2e614b05\":{\"url\":\"http://10.0.0.5:8000\",\"weight\":1},\"server-whoami-service-2-df8a622478a5a709fcb23c50e689b5b6\":{\"url\":\"http://10.0.0.4:8000\",\"weight\":1}},\"loadBalancer\":{\"method\":\"wrr\",\"stickiness\":{}}}},\"frontends\":{\"frontend-PathPrefix-0\":{\"entryPoints\":[\"http\"],\"backend\":\"backend-whoami-service\",\"routes\":{\"route-frontend-PathPrefix-0\":{\"rule\":\"PathPrefix:/\"}},\"passHostHeader\":true,\"priority\":0,\"basicAuth\":null}}}"
time="2018-11-25T13:17:30Z" level=debug msg="Wiring frontend frontend-PathPrefix-0 to entryPoint http"
time="2018-11-25T13:17:30Z" level=debug msg="Creating backend backend-whoami-service"
time="2018-11-25T13:17:30Z" level=debug msg="Adding TLSClientHeaders middleware for frontend frontend-PathPrefix-0"
time="2018-11-25T13:17:30Z" level=debug msg="Creating load-balancer wrr"
time="2018-11-25T13:17:30Z" level=debug msg="Sticky session with cookie _a49bc"
time="2018-11-25T13:17:30Z" level=debug msg="Creating server server-whoami-service-1-a179b2e38a607b1127e5537c2e614b05 at http://10.0.0.5:8000 with weight 1"
time="2018-11-25T13:17:30Z" level=debug msg="Creating server server-whoami-service-2-df8a622478a5a709fcb23c50e689b5b6 at http://10.0.0.4:8000 with weight 1"
time="2018-11-25T13:17:30Z" level=debug msg="Creating route route-frontend-PathPrefix-0 PathPrefix:/"
time="2018-11-25T13:17:30Z" level=info msg="Server configuration reloaded on :80"
time="2018-11-25T13:17:30Z" level=info msg="Server configuration reloaded on :8080"
Hvis vi krøller til, http://192.168.0.100:8080
kan vi se, at en ny cookie, _a49bc
, er blevet sat:
curl -v http://192.168.0.100:8080
* About to connect() to 192.168.0.100 port 8080 (#0)
* Trying 192.168.0.100...
* Connected to 192.168.0.100 (192.168.0.100) port 8080 (#0)
> GET / HTTP/1.1
> User-Agent: curl/7.29.0
> Host: 192.168.0.100:8080
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Length: 17
< Content-Type: text/plain; charset=utf-8
< Date: Sun, 25 Nov 2018 13:18:40 GMT
< Set-Cookie: _a49bc=http://10.0.0.5:8000; Path=/
<
I'm a6a8c9294fc3
* Connection #0 to host 192.168.0.100 left intact
Hvis vi ved efterfølgende opkald sender denne cookie til Traefik, vil vi altid blive videresendt til samme beholder:
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
curl http://192.168.0.100:8080 --cookie "_a49bc=http://10.0.0.5:8000"
I'm a6a8c9294fc3
Cookien indeholder intet andet end den interne IP-adresse på den container, som Traefik skal sende til for at anmode. Hvis du ændrer til cookieværdi til http://10.0.0.4:8000
, vil anmodningen reelt blive videresendt til den anden beholder. Hvis cookien aldrig skulle sendes til Traefik igen, vil den klæbrige session ikke fungere, og anmodninger vil blive afbalanceret mellem applikationens containere og Traefik-beholderne.
Det er alt, der skal til for at konfigurere Layer 7 Sticky Sessions i Docker CE på Debian 9.