Difference between revisions of "Docker Swarm Mode"
(→Fájlok másolása) |
(→Traefik szolgáltatás létrehozása) |
||
Line 816: | Line 816: | ||
===Traefik szolgáltatás létrehozása=== | ===Traefik szolgáltatás létrehozása=== | ||
− | + | A Traefik-et a '''docker service create''' paranccsal fogjuk létrehozni. A teljes parancs az alábbi: | |
− | |||
− | |||
− | |||
<pre> | <pre> | ||
docker service create -d -p 8080:8080 -p 80:80 --name loadbalancer \ | docker service create -d -p 8080:8080 -p 80:80 --name loadbalancer \ | ||
Line 826: | Line 823: | ||
--network balancer-net traefik | --network balancer-net traefik | ||
</pre> | </pre> | ||
+ | * ''-p 8080:8080'' - Ez a Traefik webes konzoljának a portja. Ezt a loadbalancer nevű VM 8080 portjára kötjük rá. | ||
+ | * ''-p 80:80'' - A 80-as porton fogja nyújtani a load-balancer szolgáltatást a Traefik (ha https is lenne, akkor a 443-at is meg kéne adni). Ezt szintén a loadbalancer VM 80-as portjára kötjük rá. | ||
+ | * ''--mount type=bind,src=/home/docker/traefik.toml,dst=/etc/traefik/traefik.toml'' - A loadbalancer VM-en lévő traefil.toml konfigurációst fájlt mountoljuk a Traefik konténer /etc/treafik/traefi.toml pontjára, amivel elfedjük a default fájlt, és így a konténer a mienket fogja látni. | ||
+ | * ''--mount type=bind,src=/home/docker/ssl,dst=/etc/ssl'' - mivel a konfigurációs fájlban a /etc/ssl-t adtuk meg, ugyan ide kell mountolni a TLS fájlokat a Traefik konténerben. | ||
+ | * ''--constraint node.labels.loadbalancer==true'' - Ezzel azt mondjuk meg, hogy kizárólag olyan node-ra telepíthető, ami rendelkezik ezzel a címkével | ||
+ | * ''--network balancer-net'' - Rákötjük a Traefik service -t az újonnan létrehozott overlay hálózatra. Ide fogjuk rákötni azokat a service-eket vagy stack-eket is, kiket load balance-olni akarunk. | ||
− | + | Listázzuk a loadbalancer nevű szolgáltatást: | |
− | |||
<pre> | <pre> | ||
# docker service ps loadbalancer | # docker service ps loadbalancer | ||
Line 836: | Line 838: | ||
4vnxiyz8xwoa \_ loadbalancer.1 traefik:latest loadbalancer Shutdown Rejected 9 seconds ago "invalid mount config for type…" | 4vnxiyz8xwoa \_ loadbalancer.1 traefik:latest loadbalancer Shutdown Rejected 9 seconds ago "invalid mount config for type…" | ||
</pre> | </pre> | ||
− | + | {{tip|Ha valamiért nem tudna elindulni a Traefik szolgáltatás, (pl. mert hibásan adtuk meg a mountokat) akkor a swarm folyton meg fogja próbálni újra létrehozni a service-t. Az elhalt példányokat '''\_''' -fogja jelölni. Mivel máshogy nem adtuk meg, alapértelmezetten mindig újra indítja a swarm, ezért mindig keletkezik egy új task, (a régi mindig "Shutdown" állapotba kerül.}} | |
+ | |||
+ | |||
+ | ==Swarm stack készítése== | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
Revision as of 06:45, 29 July 2018
Contents
Bevezető
Docker swarm mode
A docker swarm mode az 1.12-es verziótól része a docker-engine-nek, tehát már nem egy külön komponens. Az egyik leg szembeötlőbb különbség, hogy nem docker konténerekben fut, hanem része a docker-nek. ... ...
...
Fontos fogalmak
IPTV
Az IPVS (IP Virtual Server) egy szállítási rétegbeli load-balancer implementáció, amit "Layer 4 LAN switching"-nek is hívnak. Az IPVS része a Linux kernelnek. Közvetlen a Netfilter kernel szolgáltatásra épül. Az IPVS a külső kéréseket a valós belső TCP és UDP szolgáltatásokra irányítja a konfiguráció alapján, így egyetlen külső IP címmel több belső szolgáltatás is elérhető akárcsak csak az apache név alapú virtuális hosztok esetén. Azonban van egy fontos különbség a Layer 7 HTTP load balancer-ekhez képest. Mivel a szállítási rétegben fut, nem képes http session alapú node választásra. (Természetesen egy TCP kommunikáción belül ugyan az a végpont fogja megkapni a csomagokat különben semmi értelme nem lenne. )
routing mesh
A swarm -on futó szolgáltatások portjait az úgynevezett routing mesh tartja nyilván. Ha egy szolágáltatást egy adott porton el kell hogy érjünk a swarm-on kívülről, akkor be kell regisztrálni a portot a routing mesh-be.
Az alábbi portokat kell kinyitni a VM-ek között még a swarm létrehozása előtt:
- 7946 TCP/UDP for container network discovery.
- 4789 UDP for the container ingress network.
Tip
A docker-machine-el KVM-re létrehozott gépeken minden port nyitva van
Swarm cluster létrehozása
A docker-machine paranccsal már nem lehet közvetlen swarm-hoz kapcsolódott VM-eket létrehozni. Elsőként lére kell hozni a docker ready VM-eket, majd azokra belépve, már a dedikált swarm kezelő parancsokkal tudjuk felépíteni a cluster-t. (docker node, service és stack)
A swarm mode cluster-t egy bash szkripttel fogjuk létrehozni. 3 manager-t és 3 worker node-t. Elsőként a három manager virtuális gépet hozzuk létre. Ezután a mg0-ás gépen inicializáljuk a cluster-t, majd az m1 és m2 node-okat manager-ként beléptetjük a cluster-be. Ha ez megvan, akkor létrehozzuk a három worker node-t és azokat worker-ként léptetjük be a cluster-be.
Note
Mindig páratlan számú manager node-ot kell létrehozni, hogy a leader választó algoritmus nehogy zátonyra fusson
#!/bin/bash
#Create managers
for i in 0 1 2; do
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" --kvm-memory "800" mg$i
done
#Init cluster
docker-machine ssh mg0 docker swarm init --advertise-addr $(docker-machine ip mg0)
#Join managers
MANAGER_TOKEN=`docker-machine ssh mg0 docker swarm join-token -q manager`
WORKER_TOKEN=`docker-machine ssh mg0 docker swarm join-token -q worker`
for i in 0 1 2; do
docker-machine ssh mg$i docker swarm join --token $MANAGER_TOKEN $(docker-machine ip mg0)
done
#Create workers
for i in 0 1 2; do
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" --kvm-memory "800" worker$i
docker-machine ssh worker$i docker swarm join --token $WORKER_TOKEN $(docker-machine ip mg0)
done
Tip
A KVM helyett itt használhattunk volna Amzaon EC2-es driver-t is, pont ugyan így létrehozta volna az egész cluster-t pár perc alatt. Részletek itt: Docker Swarm on AWS
Ha lefutottak a script, nézzük meg a keletkezett VM-eket elsőként docker-machine szemszögből:
# docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS mg0 - kvm Running tcp://192.168.42.41:2376 v18.05.0-ce mg1 - kvm Running tcp://192.168.42.79:2376 v18.05.0-ce mg2 - kvm Running tcp://192.168.42.154:2376 v18.05.0-ce worker0 - kvm Running tcp://192.168.42.162:2376 v18.05.0-ce worker1 - kvm Running tcp://192.168.42.74:2376 v18.05.0-ce worker2 - kvm Running tcp://192.168.42.136:2376 v18.05.0-ce
Majd nézzük meg a virsh-val is.
# virsh list Id Name State ---------------------------------------------------- 2 mg0 running 3 mg1 running 7 mg2 running 8 worker0 running 9 worker1 running 10 worker2 running
Most listázzuk ki a swarm cluster node-jait elsőként az mg0-án, majd az mg1-en. Mind a két esetben ugyan azt az eredményt kapjuk. Láthatjuk, hogy jelenleg az mg0 a vezető.
# docker-machine ssh mg0 docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nl5mmm994ckimhe5vjazjjecs * mg0 Ready Active Leader 18.05.0-ce vacts6xlgb6ufyx49vx6fxgt0 mg1 Ready Active Reachable 18.05.0-ce 3llb2b0qh7oids0qhych9w73r mg2 Ready Active Reachable 18.05.0-ce s7hp748qu6u4bb98doss31t4r worker0 Ready Active 18.05.0-ce 211o588k4qw2uymq6dl977mmt worker1 Ready Active 18.05.0-ce hlzuosjp7wx6rxt0a66fms698 worker2 Ready Active 18.05.0-ce
# docker-machine ssh mg1 docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION nl5mmm994ckimhe5vjazjjecs mg0 Ready Active Leader 18.05.0-ce vacts6xlgb6ufyx49vx6fxgt0 * mg1 Ready Active Reachable 18.05.0-ce 3llb2b0qh7oids0qhych9w73r mg2 Ready Active Reachable 18.05.0-ce s7hp748qu6u4bb98doss31t4r worker0 Ready Active 18.05.0-ce 211o588k4qw2uymq6dl977mmt worker1 Ready Active 18.05.0-ce hlzuosjp7wx6rxt0a66fms698 worker2 Ready Active 18.05.0-ce
Monitorozás
Több grafikus docker monitor eszköz is létezik:
- Shipyard (webes)
- Portainer (webes)
- Kitematic (vastag kliens)
A legegyszerűbb a Portainer használata, ami egyetlen konténert telepít fel a docker-be, képes távoli docker démonho is kapcsolódni, és van benne swarm mode támogatás is.
Két lehetőségünk van a Portainer futtatására:
- Ahhoz hogy a swarm cluster adatait tudjuk monitorozni, valamelyik manager node-on futó docker démonhoz kell kapcsolódni a lokális docker -ben futó Portainer-el. Ezt TLS autentikációval lehet megoldani. Ekkor a Portanier a localhost-on érhető el. (mi ezt fogjuk használni, ez az ajánlott megoldás produkciós környezetben)
- A Portainer-t eleve a manager node-ot is futtató docker démonban telepítjük fel a távoli gépen, ekkor Portanier a távoli gép IP címén érhető el. Ekkor a Portainer közvetlen tud csatlakozni a docker manager-en az ottan lokális docker démonhoz (ez inkább csak tesztelés céljára, a manager node-okon nem szokás semmi mást futtatni).
A KVM dirver-el készült docker-machine-ekre boot2docker operációs rendszer kerül feltelepítésre, ha ezt nem változtatjuk meg. A boot2docker-ben alapértelmezetten be van kapcsolva a TLS remote docker API (port: 2376), és a titkosítatlan távoli hozzáférés ki van kapcsolva (port: 2375), tehát csak TLS-el lehet a manager-en futó docker démon-ra csatlakozni
Note
A példában a mg0 manager node-ra fogunk kapcsolódni, de pont ugyan ezt az eredményt kapnánk az mg1 és mg2 manager-ekkel is.
TLS kulcsok és IP cím begyűjtése
Mikor a docker-machine létrehozta a manager node-okat, legyártotta azokat az ssh kulcsokat, aminek a segítségével a docker-machine be tud ssh-zni a VM-re jelszó és felhasználó név megadása nélkül (docker-machine ssh mg0). Ezeket a kulcsokat fogjuk mi is felhasználni, hogy a lokálisan futó Portainer hozzá tudjon kapcsolódni a (távoli) virtuális gépen futó docker démonhoz.
Adjuk ki docker-machine env parancsot, hogy megtudjuk, hol tárolja a lokális docker-machine környezetünk a távoli VM SSH kulcsait:
# docker-machine env mg0 export DOCKER_TLS_VERIFY="1" export DOCKER_HOST="tcp://192.168.42.41:2376" export DOCKER_CERT_PATH="/root/.docker/machine/machines/mg0" export DOCKER_MACHINE_NAME="mg0" # Run this command to configure your shell: # eval $(docker-machine env mg0)
Látható, hogy a kulcsok a /root/.docker/machine/machines/mg0 mappában vannak
Nekünk három fájlra van innen szükségünk. A CA-ra, a certifikációnkra és a titkos kulcsunkra. A docker-machine a publikus kulcsot még telepítés közben felmásolta a VM-re.
# ll /root/.docker/machine/machines/mg0 total 316444 .. -rw-r--r-- 1 root root 1029 Jul 15 22:41 ca.pem -rw-r--r-- 1 root root 1070 Jul 15 22:41 cert.pem -rw------- 1 root root 1675 Jul 15 22:41 key.pem ...
Másoljuk a kulcsokat egy olyan mappába, ahol a böngészőt futtató user is eléri. (Ugyanis nagy valószínűséggel a root mappában jöttek ezek létre). A kulcsokat majd a Portainer webes telepítése közben majd tallózni kell.
A kulcsokon felül szükségünk lesz a master mg0 IP címére is, ezt kell megadni a Porainer-nek:
# docker-machine ip mg0 192.168.42.41
A port, ahogy már írtuk, az alapértelmezett TLS docker remote port: 2376
Ez az alapértelmezett remote port a docker démonnak. Szerencsére ez a port elve nyitva van a boot2docker operációs rendszerben.
Portainer telepítése
A Portainer-hez egyetlen egy image-et kell telepíteni: portainer/portainer
# docker container run -d -p 9000:9000 --privileged -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
- A webes konzol a localhost:9000 -as porton lehsz elérhető:
- Ha a lokális docker démon-t is monitorozni akarjuk, akkor a docker démon socket-re rá kell kötni a portainer-t.
Note
Ha nem akarjuk a lokális daemon-t is monitorozni, akkor a -v /var/run/docker.sock:/var/run/docker.sock mount nem szükséges
Ha elindult a konténer, akkor válasszuk Remote lehetőséget
- Adjuk meg a manager-t futtató VM IP címét a 2376 portal (alapértelmezett TLS port)
- Kapcsoljuk be a TLS-t.
- TLS CA certificate: ca.pem
- TLS certificate: cert.pem
- TLS key: key.pem
Warning
Ha nem adunk olvasási jogot a docker-nek a kulcsokra, azt fogja kiírni a Portainer: "Unable to create node"
Majd mondjuk hogy connect. Ekkor bejön a desboard. Innentől kezdve a távoli manager docker démonjához kapcsolódunk.
Cluster monitorozása
Nyomjunk rá a Go to cluster visualizer linkre, vagy a baloldali menüben a swarm menüpontra.
Nézzük meg az mg0 node részleteit. Láthatjuk, hogy jelenleg ő a managerek vezetője:
Service futtatása
https://blog.scottlogic.com/2016/08/30/docker-1-12-swarm-mode-round-robin.html
Service létrehozása image-ből (swarm service)
A docker service create paranccsal egy darab docker image-ből készíthetünk a swarm cluster-en futó szolgáltatást. Megadhatjuk, hogy hány példány jöjjön létre belőle, de lényegében megegyezik a szintaxisa a docker run paranccsal.
Szolgáltatás definiálása
Hozzunk létre
# docker-machine ssh mg0 docker service create --name web --replicas 3 --mount type=bind,src=/etc/hostname,dst=/usr/share/nginx/html/index.html,readonly --publish 80:80 nginx
Tip
A docker 1.17-es verziójától kezdve, a --mount paramétert kell használni a -v (--volume) helyett a storage-ek kezelésére, a -v már elavult. Korábbi verziókban csak a swarm parancsokba lehetett használni, mostanra már a standalone docker parancsokban is ezt illik használni. A szintaktikája eltér a -v-től, ugyanis a --mount után név=érték párok következnek vesszővel elválasztva szemben a -v három :-al elválasztott tagjával. Azonban swarm szolgáltatás esetén elve csak a --mount használható, a -v nem.
Monitorozás
Listázzuk ki a swarm-unkon futó szolgáltatásokat. Ezt bármelyik manager-en kiadhatjuk:
# docker-machine ssh mg1 docker service ls ID NAME MODE REPLICAS IMAGE PORTS yv47d25nc6dr web replicated 3/3 nginx:latest *:80->80/tcp
Most listázzuk ki ps-el a szolgáltatás részleteit. Láthatjuk hogy a woker0, 1 és az mg1-re telepítette fel.
# docker-machine ssh mg1 docker service ps web ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS deytk9w7z3et web.1 nginx:latest worker0 Running Running 14 minutes ago j6lwloj4q101 web.2 nginx:latest mg1 Running Running 14 minutes ago wfhucxtrq7pm web.3 nginx:latest worker1 Running Running 14 minutes ago
Nézzük meg a portainer-ben is az új szolgáltatásunkat a services menüpont alatt:
Load balancing
Nézzük meg a swarm nativ load balancert. Hívjuk meg a cluster bármelyik tagjának a publikus IP címét a 80-as porton:
# curl http://192.168.42.41:80 worker0 # curl http://192.168.42.41:80 worker1 # curl http://192.168.42.41:80 mg1
Minden egyes hívásra egy másik lábra fogunk beesni. Ez az elvárt működés. Ha máshogy nem határozzuk meg a swarm szolgáltatás telepítése közben, akkor a natív Layer 4 szolgáltatás rétegbeli load balancer lesz bekapcsolva. Az összes swarm node-on fut a load balancer egy példánya, és ezek össze vannak kötve az úgynevezett routing mesh-el, az ingress hálózaton. Így teljesen mindegy melyik lábra esünk be, az a load balancer példány ami azon a lábon fut, ahova beestünk, át fogja irányítania a kérést annak a node-nak aki a "globális" load balanc algoritmus szerint a soron következő. Ha másképp nem adjuk meg, akkor a load banac-olás round rubin, tehát mindig a soron következőt adja.
Részletek a Routing mesh című fejezetben.
Scaling
A replikák számát a docker service scale paranccsal változtathatjuk meg. Növeljük meg 5-re:
# docker-machine ssh mg0 docker service scale web=5 web scaled to 5
Majd nézzük meg mi lett:
# docker-machine ssh mg1 docker service ps web ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS deytk9w7z3et web.1 nginx:latest worker0 Running Running 28 minutes ago j6lwloj4q101 web.2 nginx:latest mg1 Running Running 28 minutes ago wfhucxtrq7pm web.3 nginx:latest worker1 Running Running 28 minutes ago 7nwtcd43vva9 web.4 nginx:latest worker2 Running Running about a minute ago kbz72e0wf1ba web.5 nginx:latest mg2 Running Running about a minute ago
A portanier-ben egy kattintással növelni tudjuk a szolgáltatás replika számát felfelé vagy lefelé a scale nyílra kattintva a Services listában.
Swarm stack
A docker stack szolgáltatások összessége, amik együttesen egy közöz applikációt alkotnak a cluster-en. Lényegében a docker compose swarm mode-ra adaptált változata. A stack-et ugyan úgy egy yml fájlban kell leírni, akárcsak a docker compose esetén, azonban a yml fájlban van egy extra szekció a szimpla docker compose-hoz képest, ez a deploy, amivel a swarm cluser-nek adhatunk utasításokat, mint pl, hogy hány példányban fusson egy adott image a stack-en belül.
Networking
Hálózat típusok
Háromféle fontos hálózat típus van a swarm-ban az alap docker hálózatokon felül (ebből egyik a másik részlalmaza)
https://docs.docker.com/v17.09/engine/swarm/networking/
- overlay network: Ez egy hostokon átívelő virtuális hálózat fajta, amit a docker emulál. (tehát nem Linux kernel funkció). A rá kapcsolódott konténerek számára transzparensen működik, hiába vannak más és más fizikai hálózatokban, úgy látják, mind ha közös hálózaton lennénk. Az overlay hálózatot a docker az úgynevezett overlay driver-el hozza létre. Ezzel emulálja a hálózatot.
- ingress network: Ez egy speciális overlay hálózat, ebből csak 1 lehet egy swarm-on belül. Nem a neve, hanem a típusa számít. Ha mi nem hozzuk létre, akkor a docker fogja létrehozni a cluster inicializálásakor. Ezt load-balancolásra használja a docker. Ha bármelyik swarm node -ra érkezik egy kérés (akár olyanra is amin nem is fut konténer) akkor is továbbítja a kérést a megfelelő node-ra. A load-balancer-t a Linux kernelben található IPVS-el hozza létre, ami egy szállítási réteg beli load-balancer. A megfelelő konténer megtalálását (IP cím + port) az úgynevezett "routing mesh" végzi.
- docker_gwbridge: Nem teljesen értem mire jó. Egy fizikai hálózati elem, tehát nem a docker emulálja. Az overlay network és a node interfésze között hoz létre egy virtuális hidat. Ha nincs, akkor a docker létrehozza. A neve számít. Ha újat akarunk csinálni, akkor Linux operendszer szinten kell törölni, majd egy pont ilyen nevű új hálózatot kell létrehozni a megfelelő paraméterekkel.
Overlay hálózatok
Átekintés
http://blog.nigelpoulton.com/demystifying-docker-overlay-networking/
- A beépített ingress overlay hálózaton felül mi is létrehozhatunk kézzel új overlay hálózatokat. Az overlay hálózatot össze kell rendelni swarm service-ekkel (ami swarm stack-en belül is lehet)
- Ha egy swarm service-t, egy overlay hálózathoz rendelünk, akkor az adott service összes konténere (akkor is ha távoli node-okon vannak) képes lesz egymással kommunikálni.
- Az overlay hálózatot a manager csak azokra a node-okra fogja kiterjeszteni, amik a megadott szolgáltatás konténereit futtatják. Egészen addig csak a manager-en létezik.
- Az overlay hálózat csak a node-on futó konténerből fog látszani. A konténerben létre fog jönne egy interfész, ami az overlay hálózatra csatlakozik, itt fog kiosztani egy IP címet az overlay network a konténernek. Tehát fontos, hogy a node gépen nem jön létre olyan interfész, ami az overlay hálózatra csatlakozok. A node gépen csak egy bridge jön létre.
- A docker a VXLAN tunel technológiát használja az overlay hálózatok létrehozására. Egy Layer 3 hálózaton hoz létre egy virtuális Layer 2 hálózatot.
Az alábbi ábrán a C1 és C2 konténereken jött létre overlay interfész, aminek az overlay bridge kiosztotta a 10.0.0.3 ill a 10.0.0.4 IP címét. Látható hogy a node1 és node2 hoszt gépeken csak a bridge található, azok nem kaptak overlay IP címéet. A két bridge-et a VXLAN tunnel köti össze.
Hálózat létrehozása
Overlay hálózatot csak a manager node-okon lehet létrehozni a -d overlay kapcsoló használatával. Hozzuk létre az over-test hálózatot.
# docker-machine ssh mg0 docker network create -d overlay over-test
Egészen addig, amíg nem rendeljük szolgáltatáshoz az overlay hálózatot, csak a manager node-okon lesz listázható. Figyeljük meg, hogy az mg0-án hoztuk létre, de az mg1-en is látszik:
# docker-machine ssh mg1 docker network ls NETWORK ID NAME DRIVER SCOPE idf7f51tp95i ingress overlay swarm ... 6hig77pse2xt over-test overlay swarm <<<
Viszont a worker1-en nem látszik. (Aki nem hiszi nézze meg)
Most hozzunk létre egy új szolgáltatást két replikával, és rendeljük hozzá az új over-test overlay hálózathoz. A hálózatot a --network kapcsolóval kell megadni. A szolgáltatásneve test lesz. (Természetesen a manager node-ok egyikén kell létrehozni az új szolgáltatást)
# docker-machine ssh mg1 docker service create --name test \ --network over-test \ --replicas 2 \ ubuntu sleep infinity
Nézzük meg a test szolgáltatás részleteit, hogy lássuk melyik node-okon fut:
# docker-machine ssh mg1 docker service ps test ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS ldg4tr5olwmv test.1 ubuntu:latest worker2 Running Running 50 seconds ago 5vxd6u2zgv1d test.2 ubuntu:latest mg0 Running Running 54 seconds ago
Láthatjuk, hogy létrejött a szolgáltatás két példánya az mg0-án és worker2-ön.
Listázzuk ki a worker2 docker hálózatait. Láthatjuk, hogy a swarm a worke2-re is kiterjesztette az over-test overlay hálózatot.
# docker-machine ssh worker2 docker network ls NETWORK ID NAME DRIVER SCOPE 911906e5a269 bridge bridge local 5125832d68a8 docker_gwbridge bridge local 73a48e5dd720 host host local idf7f51tp95i ingress overlay swarm ae8e1b7bd437 none null local 6hig77pse2xt over-test overlay swarm <<<<
Tesztelés
Innentől kezdve a test szolgáltatás két konténere elérik egymást az over-test hálózaton. Ezt demonstrálva, a test szolgáltatás m0-án futó konténeréből meg fogjuk pingelni a worker2-n futó konténert.
Próbáljuk ki. Derítsük ki a worker2-n futó ubuntu konténer over-test hálózati IP címét. Elsőként listázzuk az overlay hálózatunk részleteit:
# docker-machine ssh worker2 docker network inspect over-test ... "Name": "over-test", "Driver": "overlay", "Subnet": "10.0.0.0/24", "Gateway": "10.0.0.1" "Peers": [ "Name": "c3651bad2030", "IP": "192.168.42.136" <<< ez itt nem az overlay cím, hanem a host címe!!! "Name": "41d7e29fc1fc", "IP": "192.168.42.41"
Láthatjuk, hogy a over-test overlay hálózatunk alhálózata két végpont csatlakozik, ezen felül láthatjuk hogy az overlay hálózatunk IP tartománya a 10.0.0.0/24. Az egyik peer a worker2, a másik az mg0 (De ez nem innen látszik :) )
Note
Fontos látni, hogy a Peers alatt felsorolt IP címek nem az overlay interfészek címe, hanem azoknak a VM-eknek (valódi gépeknek) a 'publikus' IP címei, ahol azok a konténerek futnak, akik csatlakoznak az over-test overlay hálózatra.
Ki kell deríteni, hogy mi a worker2-ön futó ubuntu konténer azon interfészének az IP címe, ami az over-test overlay hálózatra csatlakozik. Ehhez elsőként be kell ssh-zni a worker2 node-ra, majd az ott futó ubuntu konténerhez kell csatlakozni interaktív módon, hogy listázni tudjuk az interfészeit:
# docker-machine ssh worker2 docker@worker2:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED 236f0a0cc334 ubuntu:latest "sleep infinity" 35 minutes ago docker@worker2:~$ docker exec -it 23 bash root@239f2a1d9bc1:/# apt-get update && apt-get install net-tools root@239f2a1d9bc1:/# ifconfig | grep 10.0.0. inet 10.0.0.10 netmask 255.255.255.0 broadcast 10.0.0.255
Tehát a worker2 node-on futó ubuntu konténer overlay címe: 10.0.0.10
Pingeljük meg az mg0-en futó ubuntu konténerből a worker2-n futó konténert. Ha megnézzük a mg0-en futó konténereket, láthatjuk a test szolgáltatáshoz tartozó ubuntu konténert:
# docker-machine ssh mg0 docker ps CONTAINER ID IMAGE COMMAND CREATED 426f0a0bb381 ubuntu:latest "sleep infinity" 35 minutes ago
Ebből az ubuntu konténerből fogjuk pingelni a test szolgáltatás másik konténert, ami a worker2 gépen fut (ami elvileg egy fizikailag teljesen máshol lévő gép is lehetne)
Elsőként ssh-val be kell lépni az mg0-ra. Majd az ubuntu konténeren futtassuk interaktív módon a bash-t. Ez után fel kell telepíteni a ping parancsot, majd már futtathatjuk is a ping-et.
# docker-machine ssh mg0 docker@mg0:~$ docker exec -it 426f0a0bb381 bash root@426f0a0bb381:/# apt-get update && apt-get install -y iputils-ping root@426f0a0bb381:/# ping 10.0.0.10 PING 10.0.0.10 (10.0.0.10) 56(84) bytes of data. 64 bytes from 10.0.0.10: icmp_seq=1 ttl=64 time=1.07 ms 64 bytes from 10.0.0.10: icmp_seq=2 ttl=64 time=1.34 ms
Láthatjuk, hogy a mg0-án lévő konténer képes kommunikálni a worker2-n lévő másik test konténerrel, mivel mind a ketten ugyan ahhoz az overlay hálózathoz (is) csatlakoznak.
Ingress hálózat
Ahogy azt már láthattuk, az ingress network virtuálisan összeköti az összes swarm node-ot, még akkor is ha azok nem egy lokális hálózaton vannak. Annyi a megkötés, hogy a node-oknak el kell tudni egymást érni az alábbi portokon:
- 7946 TCP/UDP for container network discovery.
- 4789 UDP for the container ingress network.
Az ingress hálózat segítségével tudja megvalósítani a swarm a stateless load balancer funkciót alapértelmezetten round rubin módon.
Bármelyik swarm node-on (akár manager, akár worker) kiadhatjuk a docker network ls parancsot, ugyan azt kell látni.
# docker-machine ssh mg0 docker network ls NETWORK ID NAME DRIVER SCOPE b71223c228cd bridge bridge local 410e603aa9c2 docker_gwbridge bridge local 53cd23b3594b host host local idf7f51tp95i ingress overlay swarm <<<< 4fb53b47cf55 none null local
Ha mi magunk nem hoztunk létre új overlay hálózatot kézzel, akkor csak az ingress hálózat lesz swarm scope-ú, az összes többi hálózat lokális lesz
- overlay hálózatból többet is csinálhatunk, de csak egynek lehet ingress a típusa. Az alapértelmezett ingress hálózaton felül a --network kapcsolóval adhatunk meg további overlay hálózatokat a docker service create -nek.
- Ha az ingress hálózatnak nem megfelelőek az alapértelmezett beállításai, pl nem jó az IP tartomány, vagy a service-ek egymás között kommunikációját is titkosítani a akarjuk, akkor sajnos ki kell törölni és kézzel létre kell hozni --ingress kapcsolóval.
- Ez a docker által létrehozott eszköz, nem a linux kernel hozza létre
- Egyszerre csak egy ingress típusú hálózat lehet létezhet egy swarm-ban, ezért fontos, hogy előtt kitöröljük. A neve bármi lehet, nem csak ingress. A swarm nem a neve alapján fogja megtalálni, hanem a típusa alapján. Mivel csak egy lehet, ezért ez egyértelmű.
- az egyetlen hálózat swarm scope-al
docker network create \ --driver overlay \ --ingress \ --subnet=10.11.0.0/16 \ --gateway=10.11.0.2 \ -- --opt encrypted \ <<< a service-ek kommunikációját titkosítja --opt com.docker.network.driver.mtu=1200 \ my-ingress
docker_gwbridge ??
- A docker_gwbridge egy valódi fizikai hálózat, egy virtuális bridge, amit a Linux kernel-ben hoz létre a docker. Ezt láthatjuk a VM-en kiadott ifconfig paranccsal
- viszont itt a név nagyon is számít. Mivel ez egy fizikai hálózat, a docker pont ilyen néven fogja keresni, mikor a swarm -ot létrehozza. Ha nincs készíteni fog egy újat, ha már van, akkor ezt fogja felhasználni.
- Ha módosítani akarnánk, akkor ki kell törölni Linux parancsokkal (pl: ip), majd kézzel létre kell hozni az új beállításokkal a docker network create paranccsal.
# docker-machine ssh mg0 docker network ls NETWORK ID NAME DRIVER SCOPE b71223c228cd bridge bridge local 410e603aa9c2 docker_gwbridge bridge local <<<< 53cd23b3594b host host local idf7f51tp95i ingress overlay swarm <<<< 4fb53b47cf55 none null local
# docker-machine ssh mg0 ifconfig ... docker_gwbridge Link encap:Ethernet HWaddr 02:42:DF:B6:9C:AE inet addr:172.18.0.1 Bcast:172.18.255.255 Mask:255.255.0.0 inet6 addr: fe80::42:dfff:feb6:9cae/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:19 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:0 (0.0 B) TX bytes:1418 (1.3 KiB)
Load balancing
Routing mesh for stateless services
A dokker-ben van egy beépített "layer 4", szállítási rétegbeli, beépített load balnacer.
Ha a --publis kulcsszóval hozunk létre úgy szolgáltatást, akkor
- Ahogy azt már a bevezetőben láthattuk, az úgynevezett routing mesh felelős azért, hogy egy külső portról elérjük a swarm szolgáltatást egy megadott porton.
- A --publish kulcsszóval kell regisztrálni a port mapping-et. A published a külső még a target a belső port.
Warning
A routing mesh-t logikus módon csak akkor tudjuk használni, ha minden host-on a service-nek csak 1 példánya fut. Különben ki kell kapcsolni a routing mesh-t (lásd lentebb)
$ docker service create \ --name my-web \ --publish published=8080,target=80 \ --replicas 2 \ nginx
Vagy meglévő szolgáltatáshoz meg lehet adni új port mapping-et a --publish-add kapcsolóval.
$ docker service update \ --publish-add published=8080,target=80 \ my-web
A --publish és --publish-add parancs alapértelmezetten csak tcp portot ad hozzá. A protocol=udp kapcsolóval lehet udp portot is hozzáadni
--publish published=53,target=53,protocol=udp
A routing mesh akkor van bekapcsolva egy adott service-re, ha a --publish kapcsolónak megadjuk ezt: mode=ingress Ez az alapértelmezett. Ha ki akarjuk kapcsolni a routing mesh-t, akkor ezt host-re kell állítani:
# docker service create --name dns-cache \ --publish published=53,target=53,protocol=udp,mode=host \ dns-cache
Statefull Load balancing with Traefik
Több okból is szükség lehet rá, hogy Layer 7 revers-proxy-t tegyünk a cluster-ünk elé a beépített Layer 4 TCP load balancer helyett: ...
Áttekintés
A Traefik egy univerzális Layer 7 (http) load-balancer és reverse proxy. Direkt microservice környezetre találták ki és támogatja is gyakorlatilag az összes konténer orchestration platformot és többféle service discovery szolgáltatást is:
- Docker
- Swarm mode <<<
- Kubernetes
- Marathon
- Consul, Etcd --> service discovery
- Rancher
- Amazon ECS)
A docker-swarm-ot natívan támogatja. Telepíthető docker image-ként, és van hozzá webes információs felület is.
A Traefik úgy működik, hogy valamelyik swarm manager-tről periodikusan lekérdezi az aktuális swarm konfigurációt (szolgáltatások, és azokat futtató node-ok listája). Ez alapján teljesen automatikusan konfigurálja magát és változás estén újra konfigurálja magát (pl. ha nő vagy csökken a cluster, vagy ha új szolgáltatás kerül telepítésre). Mivel magától leköveti a swarm cluster változásait, ideális megoldás mint reverse proxy és Layer 7 load balancer.
A Traefik-et futtató node publikus IP címén lesz elérhető az összes Traefik által kezelt szolgáltatás. Minden szolgáltatás a következő formán érhető el:
http://<traeif node public IP>/<PathPrefix>
A PathPrefix-et a swarm szolgáltatás telepítése közben kell megadni label-ek segítségével. A Traefik nem kezd el automatikusan minden a cluster-re telepített szolgáltatáshoz load balancer/reverse proxy szolgáltatást nyújtani. A neki szánt szolgáltatásokat a szolgáltatás telepítése közben megadott traefik specifikus címék segítségével azonosítja be és konfigurálja.
Több fórumon is azt írják, hogy a Traefik-et csak valamelyik manager node-on lehet futtatni. Egyrészről ez nem igaz, másrészről hiba lenne ha így lenne. A manager node-ot egyrészt nem szabad load-balanc feladatokkal terhelni. Ha a manager-t túlterhelnénk, leállhat a swarm cluster-ünk. Másrészről másféle hardver konfigurációra van szükség load-balanceoláshoz mint swarm manager futtatásához nem is beszélve a tűzfal szabályokra/hálózati beállításokra. (A manager node-koat nyilván nem lehet elérni a publikus internetről). Ugyan a Traefik dokumentációból ez implicit nem derül ki, de ettől még lehet remote worker node-on futtatni a Traefik-et.
A Traefik a docker swarm API-n keresztül olvassa ki a swarm adatait (szolgáltatások, címék és nodok). Ezt vagy valamelyik manager lokális socker-jét csatlakozva teheti meg, vagy a docker remote API-n keresztül, ami általában TLS felett fut (pláne produkciós környezetben). Nyilván a legegyszerűbb ha az egyik manager node-ra telepítjük föl, és ott mount-oljuk a manager docker engine lokális socket-jét:
/var/run/docker.sock:/var/run/docker.sock
Így s swarm információkat ki tudja olvasni a lokális docker démonból. Azonban ezt csak tesztelésre szabad így megcsinálni, ahogy erre több helyen is felhívják a figyelmet. Ha megnézzük a Traefik konfigurációs leírásának docker szekcióját, találunk benne egy ilyet:
# Can be a tcp or a unix socket endpoint. endpoint =
Ezen felül van benne egy TLS szekció is:
[docker.tls] ca = ...
Tehát képes távoli docker démonhoz kapcsolódni TLS felett a portainer-hez hasonlóan. Tehát ez a része kipipálva.
Van még egy fontos megkötés. A Traefik-nek közös overlay hálózaton kell lenni az összes olyan konténerrel, akiknek load-balancer szolgáltatást nyújt, mindjárt meglátjuk miért. Nyilván az ingress (routing mesh) hálózaton lévő konténer interfészek nem megfelelőek layer 7 load balanc-olásra, mert ott már fut egy layer 4 load banacer, ami minden egyes kérésre másik node-ra irányítja a kérést, tehát a konténerek "publikus" IP címe nem megfelelő. Olyan konténer interfészekre van tehát szükségünk, aminek az IP címeit le lehet kérdezni a swarm master-től (szolgáltatásonként csoportosítva) de nem fut rajta a routing mesh, viszont fontos, hogy a load-balance-olás miatt a Traefik elérje ezen a hálózaton az összes konténert. Ezért létre kell hozzunk a Traefik számára egy új overlay hálózatot, amire egyrészt a Traefik, másrészt minden olyan konténer csatlakozik, ami olyan szolgáltatás része, amihez a Traefik load balancer szolgáltatást nyújt.
A Traefik-et futtathatjuk standalone módban is, docker nélkül egy távoli VM-en, viszont bárhol is fut, fontos, hogy rálásson a fent említett, közös overlay hálózatra. Nyilván ezt a legegyszerűbben úgy érhetjük el, hogy a Traefik-et is swarm szolgáltatásként indítjuk el a cluster-ben egy erre dedikált node-on, így nem kell külön azzal bajlódni, hogy egy cluster-en kívüli entitást csatlakoztassunk egy docker-es overlay hálózatra, ami nem lenne túl egyszerű. Így viszont a manager-ek ezt automatikusan megcsinálják.
A példában az összes kék doboz egy swarm cluster-be van kötve. A swarm clusre-nek két manager-e van, és három worker node-ja. A worker node-okra rá van telepítve egy darab swarm szolgáltatás, ami három példányban fut, miden node-on 1 konténer fut a test nevű szolgáltatásból. Szintén a cluster-re van telepítve a Traefik szolgáltatás, ami egy példányban fut, és ki van erőszakolva, hogy a loadbalancer nevű node-on hozza létre a swarm. A Traefik egy szem konténere a remote docker API-n keresztül rácsatlakozik a 0. számú manager node-ra, és onnan lekéri a szolgáltatások listáját. Meg fogja kapni a Teszt szolgáltatást. Ezután szintén a remote docker API-n keresztül le fogja kérni a Teszt szolgáltatást futtató node-ok IP cím listáját, ekkor fogja megkapni a következő listát: 10.0.0.2, 10.0.0.3, 10.0.0.4. Innentől kezdve, ha a http://example.com/test URL-re érkezik kérés, akkor mindig a 10.0.0.2,3, vagy 4-es IP -jű konténerre fogja irányítani a kérést a saját overlay hálózatán keresztül (az ábrán ezt hívják Traefik overlay hálózatnak). Látható, hogy ettől függetlenül minden node csatlakozik a beépített ingress overlay hálózatra, de a Traefik load-balancing szempontjából annak most nincs jelentősége.
Warning
Van egy kisebb probléma a Traefik jelenlegi architektúrájával, ami az ábrából is látszik. Jelenleg csak 1 darab remote docker API-t lehet konfigurálni a Traefik-nek, vagyis hiába van 3 manager node a cluster-ben, a Traefik sajnos csak egy dedikált manager node-hoz tud kapcsolódni, és ha az az egy manager node kiesik, akkor megszűnik a load banacer is --> single point of failure (SPOF). Ezzel gyakorlatilag értelmét veszti a manger node-ok közötti fail-over. Persze ez csak nagyon nagy cluster-eket érintő probléma. Ezt többen is feszegetik különböző fórumokon, vannak rá különböző hekmányolások, de szép megoldás még nincs rá
Előkészületek
Overlay hálózat definiálása
Ahogy azt már láthattuk, szükség van egy dedikált overlay hálózatra, amire a Traefik konténer és az összes többi olyan konténer is rá lesz csatlakozva, amik részt vesznek a load-balancing-ban.
Bármelyik manager node-on futtassuk le az alábbi parancsot. Ha nem fontos az IP tartomány, akkor simán a docker network create paranccsal hozzuk létre az új hálózatot mindösszesen a -d overlay paraméter megadásával.
# docker-machine ssh mg0 docker network create -d overlay balancer-net o4rhm35gkh24cd25rdt7hsm62
Nézzük meg (szintén a manager node-okon). Látható, hogy létrejött a swarm scope-ú új hálózatunk.
# docker-machine ssh mg0 docker network ls NETWORK ID NAME DRIVER SCOPE o4rhm35gkh24 balancer-net overlay swarm <<<< e7b191c598c3 bridge bridge local 4648968db4af docker_gwbridge bridge local f1ab56710cf2 host host local mzwld5ddadk6 ingress overlay swarm b9b55fc2d01d none null local
Megnézhetjük a Portainter-ben is az új hálózatot a Networks menüpontban:
Load balancer node elkészítése
Elsőként készíteni fogunk egy új VM-et kifejezetten a load balancer számára, és ezt be fogjuk léptetni a swarm cluster-be. Létre fogunk hozni egy címkét is az új node-nak: loadbalancer=true. Ezzel fogjuk kikényszeríteni, hogy a Traefik swarm szolgáltatás egy szem konténere erre a node-ra települjön, ezen felül szintén ezzel a címkével fogjuk elérni, hogy semmilyen más konténert ne tegyen erre a node-ra a swarm.
Az alábbi script létrehozza az új VM-et, belépteti a cluster-be, és rárakja a címkét:
#!/bin/bash
#Get worker token
WORKER_TOKEN=`docker-machine ssh mg0 docker swarm join-token -q worker`
#Create load balancer node
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" --kvm-memory "800" loadBalancer
docker-machine ssh loadbalancer docker swarm join --token $WORKER_TOKEN $(docker-machine ip mg0)
docker node update --label-add loadbalancer=true loadbalancer
Lépjünk be valamelyik manager node-ra és ott kérdezzük le az új loadbalancer nevű node címkéit. Látnunk kell hogy rendelkezik a loadbanacer=true címkével.
# docker node inspect --format='{{.Spec.Labels}}' loadbalancer map[loadbalancer:true]
Traefik telepítése
A Traefik-et docker service-ként telepíteni kell a cluster-re, úgy hogy garantáltan loadbalancer nevű node-ra kerüljön, valamint csatlakozzon a balancer-net nevű overlay hálózatra. Ezen a ponton több lehetőségünk is van. Vagy a docker service create paranccsal definiáljuk az új szolgáltatást, vagy írunk egy compose (yml) fájlt, amiben a többi swarm szolgáltatással együtt telepítjük a Traefik-et is. Bármelyiket is választjuk, még azt is eldönthetjük, hogy megadunk a Traefik szolgáltatásnak (mivel csak egy példány lesz, mondhatnám azt is, hogy a Treaefik konténernek) egy külső konfigurációs fájt, vagy cmd argumentumokkal adjuk meg a teljes konfigurációt.
Note
Ne feledjük el, hogy csak is azért telepítjük swarm szolgáltatásként a Traefik-et, hogy egy mozdulattal rá tudjuk kötne egy közös docker overlay hálózatra, amin azok a konténerek is lógnak majd, akik olyan szolgáltatáshoz tartoznak, akiknek load balnacer szolgáltatást kell nyújtani. Ez ahhoz kell, hogy a Traefik le tudjon kérdezni olyan végpont listát a manager node-tól, ami független a routing mesh-től, és amin keresztül a Traefik el is éri a szóban forgó konténereket.
Konfiguráció elkészítése
A Traefik-nek van egy saját konfigurációs fájlja ami a Traefik konténerben lakik a /etc/traefik/traefik.toml helyen. Vagy ezt a fájlt felülírjuk vagy ezen fájl egyes értékeit írjuk felül CMD argumentumokkal a konténer definiálásakor. Azt szeretnénk, hogy a Traefik a swarm manager-rhez a remote TLS API-k keresztül csatlakozzon, ehhez meg kell adni a CA, a Cert és a titkos kulcsot fájlokat is a csatlakozáshoz. Ezen felül meg kell adjuk a manager node IP címét és TLS portját is. Mivel ennyi paramétert kéne megadni, célravezetőbb ha ezeket a Traefik konfigurációs fájljában adjuk meg
Ahhoz hogy a Traefik csatlakozni tudjon a manager node-hoz a docker remote API-n keresztül lényegében ugyan arra van szükség, amiket a Portainer remote kapcsolódásához beállítottunk a Monitorozás című fejezetben:
- manager node IP címe + secure remote port (192.168.42.75:2376). Emlékezzünk rá, hogy a 2376 secure port a boot2docker oprendszerben defualt nyitva van.
- TLS CA cert: ca.pem
- TLS certificate: cert.pem
- Secret key: key.pem
Az utóbbi hármat a docker-machine már legyártotta a VM létrehozásakor, hogy jelszó nélkül, a docker-machine ssh paranccsal csatlakozni tudjunk a VM-hez. Ugyan ezekre van itt is szükség. A publikus kulcsunkat pedig a VM létrehozásakor már a helyére másolta. (azt hiszem a ca.pem-el tudjuk ellenőrizni a VM tanúsítványát, a VM a mi cert.pem-ünkel ellenörzi a mi kilétünket, és a titkos kulccsal hozzuk létre az ssh kapcsolatot. (ssh -i key.pem loadbalancer)
A /etc/traefik/traefik.toml fájlban minimum az IP címét a portot és a három TLS fájl helyét kell hogy beírjuk. Ehhez létre fogunk hozni egy új traefik.toml fájlt a Traefik-et futtató VM-en, és azt fel fogjuk csatolni bind mount-al az egy szem Traefik konténerben az /etc/traefik/traefik.toml helyre, így el fogjuk fedni a konténerben lévő fájlt.
Induljunk ki ebből: https://github.com/containous/traefik/blob/master/traefik.sample.toml
És írjuk felül az alábbiakat:
################################################################
# Docker Swarm Mode Provider
################################################################
# Enable Docker Provider.
[docker]
# Docker server endpoint.
# Can be a tcp or a unix socket endpoint.
endpoint = "tcp://192.168.42.75:2376"
# Default domain used.
# Can be overridden by setting the "traefik.domain" label on a services.
#
# Optional
# Default: ""
#
domain = "docker.localhost"
# Enable watch docker changes.
#
# Optional
# Default: true
#
watch = true
# Use Docker Swarm Mode as data provider.
#
# Optional
# Default: false
#
swarmMode = true
# Expose services by default in Traefik.
#
# Optional
# Default: true
#
exposedByDefault = true
# Enable docker TLS connection.
#
# Optional
#
[docker.tls]
ca = "/etc/ssl/ca.pem"
cert = "/etc/ssl/cert.pem"
key = "/etc/ssl/key.pem"
insecureSkipVerify = true
Fájlok másolása
Mind a Traefik.toml fájlt, mind a TLS fájlokat (két cert + egy key) a loadbalancer VM-re kell másolni, hogy fel tudjuk őket mountolni a Traefik konténeren.
Note
Bárhol is futtatjuk a docker service create parancsot, az abban megadott --mount paraméter arról a VM-ről próbálja meg mountolni a megadott mappát/fájlt, amire a swarm kiosztja a konténert. Mivel mi ki fogjuk erőszakolni label-ek segítségével, hogy a Traefik szolgáltatás egy darab konténere a loadbalancer nevű VM-en jöjjön létre, ezért fontos, hogy a fent említett fájlokat a VM-re másoljuk
A fájlokat a lokális gépről a docker-machine által létrehozott VM-kre a docker-machine scp paranccsal lehet átmásolni, aminek a szintaktikája szinte teljesen megegyezik a linux-os scp-vel.
Elsőként nézzük meg, hogy mi a home mappánk boot2docker oprendszerben ha ssh-val belépünk a loadbalancer VM-re. Látható, hogy ez a /home/docker, ide fogjuk másolni az TLS fájlokat és a Traefik konfigurációs fájlt is.
# docker-machine ssh loadbalancer pwd /home/docker
A docker-machine scp parancs szintaktikája az alábbi:
docker machine scp /path/to/local/file MACHINE-NAME:/path/to/remote/file
Ezen felül a -r kapcsolóval rekurzívan másolhatunk mappákat.
Elsőként másoljuk a lokális ssl mappa tartalmát (amiben a három TLS fájl van) a loadbalancer nevű VM /home/docker mappájába. (mivel a kettőspont után nem adtam meg semmit, ezért a home mappába fog kerülni)
# docker-machine scp -r ssl loadbalancer: key.pem 100% 1675 2.1MB/s 00:00 ca.pem 100% 1029 1.6MB/s 00:00 cert.pem 100% 1070 1.5MB/s 00:00
# docker-machine ssh loadbalancer ls -l ssl total 12 -rwxr-xr-x 1 docker staff 1029 Jul 28 13:24 ca.pem -rwxr-xr-x 1 docker staff 1070 Jul 28 13:24 cert.pem -rwxr-xr-x 1 docker staff 1675 Jul 28 13:24 key.pem
Most másoljuk a traefik.toml fájlt szintén a home mappába.
# docker-machine scp traefik.toml loadbalancer: traefik.toml 100% 4585 7.1MB/s 00:00
# docker-machine ssh loadbalancer ls -l total 12 drwxrwxr-x 2 docker staff 100 Jul 28 13:24 ssl -rw-r--r-- 1 docker staff 4585 Jul 28 13:26 traefik.toml
Traefik szolgáltatás létrehozása
A Traefik-et a docker service create paranccsal fogjuk létrehozni. A teljes parancs az alábbi:
docker service create -d -p 8080:8080 -p 80:80 --name loadbalancer \ --mount type=bind,src=/home/docker/traefik.toml,dst=/etc/traefik/traefik.toml \ --mount type=bind,src=/home/docker/ssl,dst=/etc/ssl --constraint node.labels.loadbalancer==true \ --network balancer-net traefik
- -p 8080:8080 - Ez a Traefik webes konzoljának a portja. Ezt a loadbalancer nevű VM 8080 portjára kötjük rá.
- -p 80:80 - A 80-as porton fogja nyújtani a load-balancer szolgáltatást a Traefik (ha https is lenne, akkor a 443-at is meg kéne adni). Ezt szintén a loadbalancer VM 80-as portjára kötjük rá.
- --mount type=bind,src=/home/docker/traefik.toml,dst=/etc/traefik/traefik.toml - A loadbalancer VM-en lévő traefil.toml konfigurációst fájlt mountoljuk a Traefik konténer /etc/treafik/traefi.toml pontjára, amivel elfedjük a default fájlt, és így a konténer a mienket fogja látni.
- --mount type=bind,src=/home/docker/ssl,dst=/etc/ssl - mivel a konfigurációs fájlban a /etc/ssl-t adtuk meg, ugyan ide kell mountolni a TLS fájlokat a Traefik konténerben.
- --constraint node.labels.loadbalancer==true - Ezzel azt mondjuk meg, hogy kizárólag olyan node-ra telepíthető, ami rendelkezik ezzel a címkével
- --network balancer-net - Rákötjük a Traefik service -t az újonnan létrehozott overlay hálózatra. Ide fogjuk rákötni azokat a service-eket vagy stack-eket is, kiket load balance-olni akarunk.
Listázzuk a loadbalancer nevű szolgáltatást:
# docker service ps loadbalancer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS v524v9oqqpz7 loadbalancer.1 traefik:latest loadbalancer Running Preparing 9 seconds ago 4vnxiyz8xwoa \_ loadbalancer.1 traefik:latest loadbalancer Shutdown Rejected 9 seconds ago "invalid mount config for type…"
Tip
Ha valamiért nem tudna elindulni a Traefik szolgáltatás, (pl. mert hibásan adtuk meg a mountokat) akkor a swarm folyton meg fogja próbálni újra létrehozni a service-t. Az elhalt példányokat \_ -fogja jelölni. Mivel máshogy nem adtuk meg, alapértelmezetten mindig újra indítja a swarm, ezért mindig keletkezik egy új task, (a régi mindig "Shutdown" állapotba kerül.
Swarm stack készítése
http://www.littlebigextra.com/how-to-maintain-session-persistence-sticky-session-in-docker-swarm-with-multiple-containers/
https://boxboat.com/2017/08/03/deploy-web-app-docker-swarm-sticky-sessions/
version: "3"
services:
loadbalancer:
image: traefik
command: --docker \
--docker.swarmmode \
--docker.watch \
--web \
--loglevel=DEBUG
ports:
- 80:80
- 9090:8080
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
restart_policy:
condition: any
mode: replicated
replicas: 1
update_config:
delay: 2s
placement:
constraints: [node.role == manager]
networks:
- net
networks:
net:[
version: "3"
services:
whoami:
image: tutum/hello-world
networks:
- net
ports:
- "80"
deploy:
restart_policy:
condition: any
mode: replicated
replicas: 5
placement:
constraints: [node.role == worker]
update_config:
delay: 2s
labels:
- "traefik.docker.network=test_net"
- "traefik.port=80"
- "traefik.frontend.rule=PathPrefix:/hello;"
- "traefik.backend.loadbalancer.sticky=true"
http://192.168.42.79:9090/dashboard/
cendra/virtualhost
https://hub.docker.com/r/cendra/virtualhost/
NGINGX
https://www.nginx.com/blog/docker-swarm-load-balancing-nginx-plus/#nginx-demo
Auto scaling
A Docker swarm-ban nincs beépített auto scaling out of the box, nekünk kell implementálni, vagy használhatunk 3rd party eszközöket is. A Kubernetes-ben erre van egy remek beépített algoritmus, de a docker-swarm-ban is meg tudjuk ezt valósítani.
https://stackstorm.com/2017/06/22/autoscaling-swarm-aws-stackstorm/ https://github.com/sahajsoft/docker-swarm-service-autoscaler