Introducere
Docker Swarm transformă serverele dvs. individuale într-un grup de calculatoare, facilitând scalarea, disponibilitatea ridicată și echilibrarea sarcinii. Swarm load-balancer implementează o strategie de echilibrare a sarcinii rotunde și acest lucru ar putea interfera cu funcționarea corectă a aplicațiilor (moștenite), care necesită o formă de sesiuni lipicioase pentru a permite o configurare cu disponibilitate ridicată cu mai multe instanțe. Docker Enterprise Edition acceptă sesiunea lipicioasă Layer-7, dar în acest ghid ne vom concentra pe versiunea gratuită (CE) a Docker. Pentru a implementa sesiuni lipicioase, vom folosi Traefik.
Cerințe preliminare
- Cel puțin două instanțe proaspăt implementate și actualizate CentOS 7 în aceeași subrețea cu rețea privată activată
- Docker CE instalat în aceste cazuri
- Instanțele ar trebui să facă parte din același Swarm și ar trebui să poată comunica între ele prin intermediul rețelei private
- Cunoașterea prealabilă a Docker and Docker Swarm
- Un utilizator non-admin cu drepturi sudo (opțional, dar este recomandat să nu folosească utilizatorul root)
În acest tutorial vom folosi două instanțe Vultr cu adrese IP private 192.168.0.100 și 192.168.0.101, ambele sunt noduri manager Dwarer Swarm (care nu este ideal pentru producție, dar suficient pentru acest tutorial).
Cine sunt
Acest tutorial utilizează jwilder/whoamiimaginea docker ca aplicație demo. Acest container simplu va răspunde la un apel REST cu numele containerului care răspunde, ceea ce face foarte ușor să testați dacă funcționează sesiunile lipicioase. Această imagine este folosită numai în scopuri demonstrative și trebuie înlocuită de imaginea propriei aplicații. Este whoami-serviceconfigurat după cum urmează:
sudo docker network create whoaminet -d overlay
sudo docker service create --name whoami-service --mode global --network whoaminet --publish "80:8000" jwilder/whoami
sudo firewall-cmd --zone=public --add-port=80/tcp --permanent
sudo firewall-cmd --reload
Dacă am atinge ulterior curlpunctul whoamifinal REST http://192.168.0.100/, putem observa la locul de muncă echilibrarea sarcinii rotunde a Docker Swarm.
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
Nu are niciun rost să testați acest lucru cu browsere moderne, cum ar fi Chrome sau Firefox, deoarece sunt concepute pentru a menține conexiunile în viață (deschise), iar balansatorul de sarcină Docker Swarm va comuta la celălalt container la fiecare nouă conexiune. Dacă doriți să testați acest lucru cu un browser, ar trebui să așteptați cel puțin 30 de secunde ca conexiunea să se închidă înainte de a reîncărca din nou.
Înființarea lui Traefik
Traefik acceptă în mod nativ Docker Swarm, poate detecta și înregistra sau anula înregistrarea containerelor în zbor și comunică cu aplicația dvs. prin rețeaua de acoperire internă. Traefik are nevoie de informații despre aplicația dvs. înainte de a putea începe gestionarea cererilor pentru aceasta. Aceste informații sunt furnizate către Traefik prin adăugarea de etichete la serviciul dvs. Swarm.
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
Lista de mai jos descrie ce înseamnă fiecare etichetă:
traefik.docker.network: Rețeaua de suprapunere Docker peste care Traefik va comunica cu serviciul dvs.
traefik.port: Portul pe care îl ascultă serviciul (acesta este portul expus intern, nu portul publicat)
traefik.frontend.rule: PathPrefix:/leagă rădăcina de context /la acest serviciu.
traefik.backend.loadbalancer.stickiness: Permite sesiuni lipicioase pentru acest serviciu
Acum că whoami-servicea fost configurat cu etichetele necesare, putem adăuga serviciul Traefik la roi:
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
Această comandă face o serie de lucruri simultan. Lista de mai jos va explica mai detaliat:
--name traefik: Numele noului nostru serviciu Docker este traefik
-p8080:80: Publicăm portul Traefik 80în port 8080(portul 80este deja folosit de către nostru whoami-service)
-p9090:8080: Publicăm propria interfață web a Traefik în port 9090
--mount ...: Montăm Docker Socket în container, astfel încât Traefik să poată accesa timpul de rulare Docker al gazdei
--global: Vrem containere Traefik pe fiecare nod de manager din motive de disponibilitate ridicată
--constraint 'node.role == manager': Vrem ca Traefik să ruleze numai pe nodurile managerului, deoarece nodurile lucrătorului nu pot oferi Traefik informațiile de care are nevoie. De exemplu, docker service lspe un nod lucrător nu funcționează, deci Traefik nici măcar nu ar putea descoperi ce servicii rulează
--network whoaminet: Conectează Traefik la aceeași rețea ca a noastră whoami-service, altfel nu se pot conecta. Înainte am spus lui Traefik să se conecteze la serviciul nostru prin intermediul acestei rețele cu ajutorul traefik.docker.networketichetei
traefik: Spuneți-i docker-ului să utilizeze cea mai recentă imagine docker Traefik pentru acest serviciu
--docker --docker.swarmmode --docker.watch --web --loglevel=DEBUG: Argumentele din linia de comandă transmise direct către Traefik pentru a-i permite să ruleze în modul Docker Swarm ( --loglevel=DEBUGeste opțional aici, dar interesant în timpul configurării și pentru acest tutorial)
Nu mai rămâne decât să deschizi porturile necesare în firewall-ul CentOS:
sudo firewall-cmd --zone=public --add-port=8080/tcp --permanent
sudo firewall-cmd --zone=public --add-port=9090/tcp --permanent
sudo firewall-cmd --reload
Cum functioneaza
Imediat ce Traefik pornește, puteți vedea în jurnalele pe care Traefik descoperă cele două whoamicontainere. De asemenea, este lansat numele cookie pe care îl va folosi pentru a gestiona sesiunea lipicioasă:
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"
Dacă ne îndreptăm către http://192.168.0.100:8080, putem vedea că _a49bca fost setat un nou cookie :
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
Dacă, la apelurile ulterioare, trimitem acest cookie către Traefik, vom fi întotdeauna transmise către același container:
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
Cookie-ul nu conține altceva decât adresa internă ((suprapunere), a IP a containerului către care Traefik ar trebui să trimită să solicite. Dacă schimbați valoarea cookie-ului, http://10.0.0.4:8000atunci solicitarea ar fi transmisă efectiv către celălalt container. Dacă cookie-ul nu a fost niciodată trimis la Traefik, atunci sesiunea lipicioasă nu va funcționa și solicitările vor fi echilibrate între containerele aplicației și containerele Traefik.
Aceasta este tot ceea ce este necesar pentru a configura Layer 7 Sticky Sessions în Docker CE pe CentOS 7.