[[Docker Orchestration|<< Back to Orchestration Docker main]]
=Bevezető=
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) --advertise-addr $(docker-machine ip mg$i)
done
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) --advertise-addr $(docker-machine ip worker$i)
done
</source>
{{tip|A KVM helyett itt használhattunk volna Amzaon EC2-es driver-t is, pont ugyan így ugyanígy létrehozta volna az egész cluster-t pár perc alatt. Részletek itt: [[Docker_Swarm_on_AWS|Docker Swarm on AWS]] }} A '''--advertise-addr''' paraméterre azt mondjuk meg, hogy az újonnan létrehozandó swarm node a swarm-management node-to-node kommunikációra melyik interfészét használja a VM-nek (ha több is van). A swarm node ezen az interfészen (alhálózaton) fogja magát reklámozni a swarm cluster-ben, a többi node az itt megadott interfészen fogja keresni. A swarm management node-to-node kommunikációt biztonsági okokból mindig VM internal hálózaton kell bonyolítani, tehát a '''--advertise-addr''' paraméternek mindig egy VM internal hálózati interfészt kell megadni. A VM-eket mindig úgy kell létrehozni, hogy legalább két hálózatra csatlakozzanak. Legyen egy VM internal hálózat, ami a publikusan nem érhető el, csak a guest-ek látják rajta egymást, és legyen egy második hálózat, ahol a VM-ek kilátnak a netre, és akár a publikus hálózatból elérhetőek. A "'''docker-machine create'''"-el olyan VM-eket hoztunk létre, amikre ez teljesül: * '''eth0''':192.168.123.0/255.255.255.0 - ('''docker-network''') Azt a hálózatot mi definiáltuk, ez kilát a publikus internetre. (Ezt a hálózatot a KVM a "'''forward mode=nat'''" paraméterrel hoztuk létre, ezért lát ki a publikus net-re, lásd [[KVM#Add new network]] cikket a részletekért.) Ha az ingress load balance-olt hálózaton akarunk elérni egy service-t akkor az adott node ezen IP címét kell használni. * '''eth1''':192.168.42.0/255.255.255.0 - ('''docker-machines''') Ezt a hálózatot a KVM driver hozta létre automatikusan a VM internál kommunikációra, tehát minden node-nak az '''eth1''' interfész IP címét kell megadni az '''--advertise-addr''' paraméterben. Szerencsére a "'''docker-machine ip node-name'''" parancs pont ezt az ip-t adja vissza. <br>Részletek itt: [[Docker Machine#Create machines with KVM]] (ugyan ezen az IP-n is működik az ingress hálózat lokálisan, távolról ez nem elérhető) KVM driver esetén ha nem az alapértelmezett OS-t akarjuk használni, akkor a '''--kvm-boot2docker-url''' kapcsolóval kell megadni a .ISO helyét. Én a rancherOS-t próbáltam ki és működött. Innen lehet letölteni: https://github.com/rancher/os (közvetlen link: https://releases.rancher.com/os/v1.5.0/rancheros.iso) <pre>docker-machine create -d kvm --kvm-boot2docker-url "/home/adam/Downloads/rancheros.iso" --kvm-network "docker-network" manager1</pre> <pre># virsh net-list Name State Autostart Persistent---------------------------------------------------------- default active yes yes docker-machines active yes yes docker-network active yes yes</pre>
<br>
Most Végezetül 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ő.
<pre>
# docker-machine ssh mg0 docker node ls
<br><br>
=MonitorozásGUI swarm management with Portainer=
:[[File:ClipCapIt-180824-214115.PNG]] Több grafikus docker monitor manager/monitoring eszköz is létezik:
* Shipyard (webes)
* Portainer (webes)
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. (docker nélkül is futtatható)
Két lehetőségünk van a Portainer futtatására:
* Ahhoz hogy a swarm cluster adatait tudjuk monitorozniA Portainer konténerünket lokálisan futtatjuk, és távolról kapcsolódik valamelyik manager noderemote API-on futó docker démonhoz kell kapcsolódni jához, ahonnan a swarm adatokat is ki tudja olvasni, illetve módosítani is tudja a lokális docker -ben futó Portainer-elkonfigurációt. Ezt A távoli kapcsolatot TLS autentikációval lehet megoldani. Ekkor a Portanier a localhost-on érhető elA Portainer webes felülete csak lokálisan lesz elérhető. (mi ezt fogjuk használni, ez az ajánlott megoldás produkciós környezetben)* A Portainer-t eleve a manager nodeswarm service-ot is futtató docker démonban ként telepítjük fel azzal a távoli gépenmegkötéssel, ekkor Portanier a távoli gép IP címén érhető elhogy csak manager noder-ra telepíthető. Ekkor a Portainer közvetlen tud csatlakozni a docker A managernode-en on az ottan ott lokális docker démonhoz (ez inkább csak tesztelés céljárasocket-re fog kapcsolódni, ahonnan a swarm adatokat is ki tudja olvasni manager node-okon nem szokás semmi mást futtatni)ról lévén szó. Ekkor a Portainer webes felülete globálisan lesz elérhető mindenki számára. ==Portainer telepítése swarm service-ként==
A legkézenfekvőbb megoldás, ha a Portainer-t swarm service-ként a manager node-ok valamelyikére telepítjük föl. Az már mindegy, hogy melyik manager node-ra kerül, azt bízzuk a swarm-ra (cow személet), bármelyikre is kerül, lokális docker socket-re csatlakozva el fogja érni a cluster adatokat.
Az a gond, hogy a Portainer stateful szolgáltatás, a '''/data''' konténer mappában tárolja az adatait (állapotát). Staeful szolgáltatások kezelése egy kicsit nehézkes. A /data a mappát kéne legalább a guest VM-re lementeni, hogy ha a szolgáltatás újra indulna ne vesszenek el a Portainer adatok (állapot). Azonban ha a swarm egy másik manager nodre-ra újratelepítené, akkor fontos hogy ott is rendelkezésre álljon ugyan az a '''/data''' mappa tartalom (állapot), hogy ne vesszenek el a beállítások. Ehhez valamelyik docker volume plugin -t kell használjuk, lásd a [[Docker volume orchestration]] című cikket. A swarm service-ként való futtatásnak az a nagy előnye, hogy a Portainer életciklusát nem nekünk kell kezelni, ha az a manager node meghal, ahova a Portainer eredetileg telepítve volt, akkor a swarm automatikusan újra fogja telepíteni egy másik manager node-on. És mivel a Portainer /data mappáját a manager node-ok között egy közös perzisztens meghajtóra csatoltuk föl, miután a swarm újratelepíti a Portainer-t, az ott tudja folytatni, ahol a mások node-on abba hagyta. ===Portainer telepítése===Telepítsük fel a '''Netshare''' docker volume plugin-t a [[Docker_volume_orchestration#Netshare|Docker volume orchestration/Netshare]] fejezetben leírtak alapján. A Netshare segítségével felcsatolhatunk NFS megosztást közvetlen a Portainer konténerbe on-demand alapon, tehát a megosztás csak azon a node-on fog létrejönni, ahova a swarm a Portainer-t telepíti majd. A portainer-t swarm service-ként fogjuk telepíteni. Ki fogjuk kötni hogy csak manager node-ra telepítheti a swarm, tehát biztos, hogy az előbb létrehozott mg0, mg1 és mg2 valamelyikén fog landolni. Fontos, hogy megadjuk, hogy csak egy példány jöhessen belőle létre. Két fontos mount-ot kell beállítani: # '''/data''': Egy távoli NFS megosztást fogunk felcsatolni a Netshare plugin segítségével, ahol a Portainer a perzisztens adatait fogja tárolni. # '''/var/run/docker.sock''': ezt a guest VM docker socket-jére kell rákötni, hogy a portainer hozzáférjen a docker/swarm adatokhoz és tudja is módosítani azokat. <pre>eval $(docker-machine env mg0) docker service create \--name portainer \--publish 9000:9000 \--replicas=1 \--constraint 'node.role == manager' \--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \--mount type=volume,src=192.168.42.1/home/adam/Projects/DockerCourse/persistentstore/portainer/data/,dst=/data,volume-driver=nfs \portainer/portainer -H unix:///var/run/docker.sock</pre>Ha a portainer-t swarm service-ként futtatjuk, akkor fontos, hogy command-nak is megadjuk a unix-docker socket használatát: '''-H unix:///var/run/docker.sock'''{{note|A command részben fontos, hogy a unix után három / jel van. Ebből aztán kettő lesz mire konténer lesz belőle, nem pontosan értem, hogy ha escape-elni kell, akkor miért nem négy kell, minden esetre ha csak kettőt írunk, akkor a /run/docker.sock-ban fogja keresni a /var/run/docker.sock helyett}} Nézzük meg melyik manager node-ra települt a portainer. <pre># docker service ps portainer ID NAME IMAGE NODEjh04xrikkskh portainer.1 portainer/portainer:latest mg0 </pre>Láthatjuk hogy az mg0 manager node-ra került ki. <br>===Belépés a web-es konzolra=== A 9000-as portot publikáltuk a swarm ingress hálózatán, ami azt jelenti, hogy a swarm node-ok bármelyikének az IP címén, a 9000-as porotn el fogjuk érni a Portainer webes konzolját:<pre># docker-machine ip mg0192.168.42.231</pre> http://192.168.42.231:9000/#/init/admin:[[File:ClipCapIt-180824-215348.PNG]] Első induláskor be kell állítani az admin felhasználót. A host gépen láthatjuk, hogy az NFS mappában megjelentek a portainer fájlok: :[[File:ClipCapIt-180824-234015.PNG]] <br> ==Portainer telepítése lokális konténerként==A következőkben megnézzük, hogyan lehet távolról kapcsolódni a Portainer-el egy swarm cluster manager node-jához. Ez a megoldás több szempontból sem annyira előnyös mint a swarm service-ként való telepítés, ezek a következők: # Egy dedikált manager-hez kapcsolódunk, ha az kiesik, ugrott az egész GUI management. # Csak azon a laptopon elérhető a portainer, ahol összelőttük a Remote kapcsolatot, tehát csak egy ember fér így hozzá, nem az egész csapat. # Nekünk kell kezelni a Portainer életciklusát, vagyis ha a Portainert konténer, vagy az azt futtató VM leáll, akkor nekünk kell kézzel újra indítani, vagy akár újra telepíteni a szolgáltatást. Ezzel szemben előnyök: # Egy Portainer példányból az összes swarm cluster-ünket kezelhetjük, mivel tetszőleges számú remote rendszert lehet hozzáadni. Ennek az az előnye, hogy a Portainer autentikációt és authorizációt csak egyszer kell beállítani. A Portainer a távoli docker-hez a TLS API-n keresztül fog csatlakozni, amihez szükségünk van az ott futó docker démon publikus és titkos kulcsára. 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. }}
<br>
===Portainer telepítéselokális docker-en===
A Portainer-hez egyetlen egy image-et kell telepíteni: '''portainer/portainer'''
<pre>
Majd mondjuk hogy connect. Ekkor bejön a desboard. Innentől kezdve a távoli manager docker démonjához kapcsolódunk.
<br>
===Cluster monitorozása===
Nyomjunk rá a '''Go to cluster visualizer''' linkre, vagy a baloldali menüben a '''swarm''' menüpontra.
:[[File:ClipCapIt-180716-010553.PNG|1100px]]
<br>
=Statefull Load balancing with Traefik=
https://boxboat.com/2017/08/03/deploy-web-app-docker-swarm-sticky-sessions/<br>http://www.littlebigextra.com/how-to-maintain-session-persistence-sticky-session-in-docker-swarm-with-multiple-containers/<br>=Auto scaling=
Több okból 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 szükség lehet rá. A Kubernetes-ben erre van egy remek beépített algoritmus, hogy Layer 7 reversde a docker-proxyswarm-t tegyünk a cluster-ünk elé a beépített Layer 4 TCP load balancer helyett: ..ban is meg tudjuk ezt valósítani.
==Á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: <br>* 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.''' {{warning|A Traefik nem webserver, csak egy reverse proxy. Nem tud pl static tartalmat kiszolgálni!}} 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. :[[File:ClipCapIt-180728-211924.PNG]]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 httphttps://examplestackstorm.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á}} Anélkül, hogy nagyon mélyen belemennénk a Traefik működésébe, annyit tudni kell róla, hogy három fő eleme van, amit az alábbi móricka ábrán is láthatunk::[[File:ClipCapIt-180729-222107.PNG|700px]]* Entry point: ez kapja meg a kérést, vagy http-n vagy https-en. Leginkább arra jó, hogy a http-t átirányítsuk https-re. Ha a kérés túljutott az entry-point-on, megkapja a frontend szekció. * A front-end szekció tartalmazza azokat a szabályokat, amik megmondják, hogy egy beérkezett kérést (a domain neve, a header mezők vagy a path alapján) melyik beck-end-re kell továbbítani. * A back-end tartalmazza a swarm service végpontok listáját (ezen a szinten már mindenképp service-ről beszélünk és nem stack-ről, mert még akkor is ha compose fájllal hoztuk létre a szolgáltatást, a Traefik service szinten van definiálva) Ha az entry-point-ról a kérés a frent-end szabályok segítségével eltalált a megfelelő back-end-re, akkor a Traefik továbbítja a kérést a kiválasztott tényleges docker konténernek. ==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. <pre># docker-machine ssh mg0 docker network create -d overlay balancer-neto4rhm35gkh24cd25rdt7hsm62<2017/pre> Nézzük meg (szintén a manager node-okon). Látható, hogy létrejött a swarm scope-ú új hálózatunk. <pre># docker-machine ssh mg0 docker network lsNETWORK ID NAME DRIVER SCOPEo4rhm35gkh24 balancer-net overlay swarm <<<<e7b191c598c3 bridge bridge local4648968db4af docker_gwbridge bridge localf1ab56710cf2 host host localmzwld5ddadk6 ingress overlay swarmb9b55fc2d01d none null local<06/pre> Megnézhetjük a Portainter-ben is az új hálózatot a Networks menüpontban: :[[File:ClipCapIt-180728-223041.PNG]]<br> ===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: <source lang="sh">#!22/bin/bash #Get worker tokenWORKER_TOKEN=`docker-machine ssh mg0 docker swarm join-token -q worker` #Create load balancer node docker-machine create autoscaling-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 </source> 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. <pre># docker node inspect -aws-format='{{.Spec.Labels}}' loadbalancermap[loadbalancer:true]<stackstorm/pre> <br> ==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ötni 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===https://docs.traefik.io/configuration/backends/docker/<br> 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 [[Docker_Swarm_Mode#Monitoroz.C3.A1s|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. <br>Induljunk ki ebből: https://github.com/containous/traefik/blob/master/traefik.sample.toml<br>És írjuk felül az alábbiakat: <source lang="sh">################################################################# Docker Swarm Mode Provider################################################################ # Enable Docker Provider.[docker] # Docker server endpoint.# Can be a tcp or a unix socket endpoint.endpoint = "tcp:/sahajsoft/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</source> <br>===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 '''dockerservice-machine scp''' paranccsal lehet átmásolni, aminek a szintaktikája szinte teljesen megegyezik a linux-os scp-vel.autoscaler
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 '''https:/home/docker''', ide fogjuk másolni az TLS fájlokat és a Traefik konfigurációs fájlt isdocs. <pre># docker-machine ssh loadbalancer pwd/home/docker</pre> A docker-machine scp parancs szintaktikája az alábbi: docker machine scp /path/to/local/file MACHINE-NAME:/path/to/remote/fileEzen felül a '''-r''' kapcsolóval rekurzívan másolhatunk mappákatstackstorm. Elsőként másoljuk a lokális '''ssl''' mappa tartalmát (amiben a három TLS fájl van) a '''loadbalancer''' nevű VM '''com/homeinstall/docker''' mappájába. (mivel a kettőspont után nem adtam meg semmit, ezért a home mappába fog kerülni)<pre># 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 </pre>html
<pre>
# 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
</pre>
Auto Scaling Docker Containers in Amazon ECS: https://www.codementor.io/jholub/amazon-ecs-auto-scale-docker-containers-6keydo24n
ECS is an alternative to tools such as Kubernetes, Docker Swarm, or Mesos
Most másoljuk a traefik.toml fájlt szintén a home mappába.
<pre>
# docker-machine scp traefik.toml loadbalancer:
traefik.toml 100% 4585 7.1MB/s 00:00
</pre>
<pre># docker-machine ssh loadbalancer ls -ltotal 12drwxrwxr-x 2 docker staff 100 Jul 28 13https:24 ssl-rw-r--r-- 1 docker staff 4585 Jul 28 13:26 traefik//github.toml<com/gianarb/pre>orbiter
<br>
===Traefik szolgáltatás létrehozása===https://prometheus.io/docs/prometheus/latest/installation/
A Traefik-et a '''docker service create''' paranccsal fogjuk létrehozni. A teljes parancs az alábbi: <pre>docker service create -d -p 8080:8080 -p 80https: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</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ádocs. * '''--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/dockercom/ssl,dst=config/etc/ssl''' - mivel a konfigurációs fájlban a thirdparty/etcprometheus/ssl-t adtuk meg, ugyan ide kell mountolni a TLS fájlokat a Traefik konténerben. * '''-#use-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. prometheus
===Mi jött létre===<br>Listázzuk a futó szolgáltatásokat. Látható, hogy a '''loadbalancer''' nevű szolgáltatás 1 példánnyal elindult<pre> # docker service lsID NAME MODE REPLICAS IMAGE PORTS04cj4vdsu0qu loadbalancer replicated 1/1 traefik:latest *:80->80/tcp, *:8080->8080/tcp</pre> Listázzuk a loadbalancer nevű szolgáltatást. Látható, hogy a '''loadbalancer''' nevű node-ra tette, ahogy azt akartuk. <pre># docker service ps loadbalancer ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTSv524v9oqqpz7 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…" </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.}} <br>A Portainer-ben is meg kell jelenjen a service listában: :[[File:ClipCapIt-180729-085532.PNG]] <br> Most már el kell érjük a Traefik webes konzolt a loadbalancer VM publikus IP címén, a 8080 porton.<pre># docker-machine ip loadbalancer192.168.42.42</pre>Tehát itt: http://192.168.42.42:8080 :[[File:ClipCapIt-180729-085255.PNG]]Ahogy azt már láttuk, a Traeif-kben három lépcsőn jut el a kérés a docker konténerekig. Elsőként az Entry-point megkapja a kérést, majd a Front-end szabályok megmondják, hogy melyik back-end-re menjen tovább a kérés. A Back-end pedig swarm szolgáltatásokat szimbolizál, abban vannak azok a végpontok, amik közül választani fog egyet a Traefik mikor továbbítja a kérést. <br>A Traefik konzolt majd [[Docker_Swarm_Mode#Load_balance_test|Load balancing test]] című fejezetben nézzük meg részletesebben, mikor már lesznek benne szolgáltatások. <br>==Swarm stack készítése== Most definiálni fogunk egy swarm stack-et, amihez a Traefik load-balancer szolgáltatást fog nyújtani. Ehhez elsőként el fogjuk készíteni a stack yml fájlját. (Használhatjuk a '''docker service create''' parancsot is, a lényeg, hogy megadjuk a Traefik-et vezérlő címkéket) ===Stack definiálása===Az új szolgáltatáshoz a '''tutum/hello-world''' image-et fogjuk használni, amiben fut egy apache, és a lending page-en (index.php) kiírja a konténer host nevét (konténer ID-t). Ez azért jó választás, mert remekül tesztelni lehet vele a stick-session kezelést, láthatjuk majd hogy ha egyszer már beestünk egy lábra, végig ott is maradunk, de session törlés után megint egy új lábat kapunk. Ezen felül az index.php-n még egy kép is található, tehát az url rewrite-ot is tesztelhetjük. A szolgáltatás neve '''helloworld''' lesz. A '''helloword.yml''' fájl tartalma az alábbi: <syntaxhighlight lang="C++">version: "3" services: helloworld: image: tutum/hello-world networks: - balancer-net ports: - "80" deploy: restart_policy: condition: any mode: replicated replicas: 5 placement: constraints: - node.role == worker - node.labels.loadbalancer != true update_config: delay: 2s labels: - "traefik.docker.network=balancer-net" - "traefik.port=80" - "traefik.frontend.rule=PathPrefixStrip:/hello/" - "traefik.backend.loadbalancer.sticky=true" networks: balancer-net: external: true</syntaxhighlight> {{note|Ha implicit nem mondjuk meg a compose -nak, hogy a hálózat már létezik, akkor a létre fog mindig hozni egy új hálózatot a '''<service név>_<hálózat név>''' néven. Tehát a fenti compose fájlból a '''helloworld_balancer-net''' hálózat jönne létre. Ha a hálózat mér létezik, akkor ezt az '''external: true''' paraméterrel jelezni kell. Lehetőség van rá, hogy más nevet használjunk a compose fájlban, mint a hálózat valódi neve. Ekkor az external után a name paraméterrel kell megadni a nevét: external: name: balancer-net}}Egy kis magyarázat a compose fájlhoz: <br>A teljes '''deploy''' szekció a '''docker stack'''-nek szól, a '''docker compose''' ezt a részt figyelmen kívül hagyja. Itt kell megadni a swarm specifikus beállításokat a szolgáltatáshoz. * '''networks:balancer-net''': Fontos, hogy a szolgáltatás összes konténere rá legyen kötve a közös overlay hálózatra, amire a Traefik is rá van kötve. Itt minden egyes konténernek egyedi IP címe van, még akkor is, ha egy node-on több konténer is létrejött. A Traefik ezen a közös hálózaton fogja megszólítani a konténereket, így nem lehet port ütközés (minden ip:port egyedi) * '''ports:"80":''' Csak annyit mondunk meg, hogy a konténerekben futó Apache 80-as portájt ki kell ajánlani a konténer interfészein, de nem mondjuk meg melyik portra, a docker majd választ egyet, tehát a külső port random port lesz. Ennek ellenére a Traefik meg fogja találni a portot, mivel le tudja kérdezni a swarm manager-től. * constraints:** '''node.role == worker''': csak worker node-okra fog telepíteni, manager-ekre nem. Ez mindig követendő példa produkciós környezetben! (ezzel ekvivalens a '''node.role != manager''')** '''node.labels.loadbalancer != true''': Olyan node-ra, aminek van '''loadbalancer=true''' címkéje nem fog telepíteni. Ilyenből ugyebár 1 darab van, a dedikált VM-ünk a load-balancing-ra. Ahogy azt már említettem, a Traefik service label-ek segítségével azonosítja és konfigurálja azokat a szolgáltatásokat, amikhez load-balancing szolgáltatást kell hogy nyújtson. Ezeket a címkéket a labels szekcióban kell megadni. Alább a minimum címékék: * '''traefik.docker.network''': itt meg kell adjuk azt a load-balancing-re létrehozott overlay hálózatot, amire egyrészről a Traefik-et is rákötöttük, másrészről az összes load-banace -olandó szolgáltatás konténerei is rá vannak kötve. A fenti példában a '''helloword''' service konténereit kötjük rá a '''balancer-net''' overlay hálózatra. Mikor a Traefik a swarm manager-től eléri a szolgáltatásokat, akkor csak azokkal foglalkozik, aminek a konténerei rá vannak kötve a 'közös' overlay hálózatra. * '''traefik.port'''* '''traefik.frontend.rule=PathPrefixStrip:/hello/''': Na ez itt a legfontosabb. A '''traefik.frontend.rule''' azt mondja meg, hogy hol legyen elérhető a load-balancer-t szolgáltatás. A traefik.frontend.rule lehetséges paramétereit itt nézzük meg: https://docs.traefik.io/basics/#frontends. A '''PathPrefixStrip'''-el megadunk egy path prefix-et. Ha a load-balancer domain neve után olyan URL-t írunk a böngészőbe, ami az itt megadott prefixel kezdődik, akkor a Traefik azt fogja hátraküldeni a konténereknek amit a path-prefix után írtunk, de a path-perfix-et le fogja róla vágnimonitor. Pl a http://exampledockerflow.com/hello/index.php URL-ből a tutum konténerek csak az index.php-t fogják megkapni. Ahogy láttam a válaszban natívan kiegészíti a resource URL-eket az itt megadott path-prefixauto-el. Tehát ha volt egy '''<img src=logo.png/>''' akkor abból '''<img src=hello/logo.png/>''' lesz. * '''traefik.backend.loadbalancer.sticky''': be lehet kapcsolni vele a sticky session-t. Tulajdonképpen ezért csináltuk az egészet, hogy legyen sticky session-ünk. Http session tartás nélkül a natív docker swarm Layer 4 load balancer is kiválóan használható. Körülbelül 40 féle címkével vezérelhetjük a load balancer működését, itt a teljes lsita: https://docs.traefik.io/configuration/backends/docker/ Hozzuk létre az új szolgáltatást (stack-et) a docker stack deploy paranncssal. <pre># docker stack deploy -c helloworld.yml helloserviceCreating service helloservice_helloworld</pre> <br> ===Mi jött létre=== <pre># docker stack lsNAME SERVICEShelloservice 1</pre> <pre># docker stack ps helloservice ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ygigsppmqp1j helloservice_helloworld.1 tutum/hello-world:latest worker0 Running Running about a minute agokv5lvg2g79jn helloservice_helloworld.2 tutum/hello-world:latest worker1 Running Running 59 seconds ago gc1yqgshnhw3 helloservice_helloworld.3 tutum/hello-world:latest worker2 Running Running 59 seconds ago rgoc8uzt354v helloservice_helloworld.4 tutum/hello-world:latest worker1 Running Running 59 seconds ago sofw5w45qyco helloservice_helloworld.5 tutum/hello-world:latest worker2 Running Running 59 seconds ago</pre>Látható, hogy ahogy kértük, csak worker node-ra telepítette a szolgáltatást, és a loadbalancer nevű node-ra nem rakott egy konténert sem. <pre># docker service lsID NAME MODE REPLICAS IMAGE PORTSw31aon1cwm34 helloservice_helloworld replicated 5/5 tutum/hello-world:latest *:30004->80/tcp04cj4vdsu0qu loadbalancer replicated 1/1 traefik:latest *:80->80/tcp, *:8080->8080/tcp</pre> Listázzuk ki, hogy milyen hálózatokban van interfésze helloservice-hez tartozó konténereknek. Láthatjuk, hogy a 10.0.2.0/24 és a 10.255.1.0/24-os hálózatokban van tagsága. # docker service inspect --format='{{.Endpoint.VirtualIPs}}' helloservice_helloworld [ {mzwld5ddadk6tcpio8ytkyhgg 10.255.1.10/16} {o4rhm35gkh24cd25rdt7hsm62 '''10.0.2.11/24'''}] Nézzük meg melyik hálózat micsoda. Ahogy annak lennie kell, az egyik a balancer-net, ami egy közös overlay hálózat a load balancer szolgáltatással. A másik meg a swarm beépített ingress hálózata. Azt most nem fogjuk használni (ezen fut a Layer 4 IPVS). # docker network inspect balancer-net | grep Subnet "Subnet": "'''10.0.2.0/24'''", # docker network inspect 'ingress' | grep Subnet "Subnet": "10.255.0.0/16", ==Load balance test== ===Traefik konzol a végpontokkal===Elsőként nézzük meg, hogy a Traeifk konzolon megjelent e az új szolgáltatás: http://192.168.42.42:8080/dashboard/:[[File:ClipCapIt-180729-112325.PNG]] '''Frontends''': A frontedns listában megjelent a frontend-PathPrefixStrip-hello-0 nevű szolgáltatás. Ez azt a szabályt tartalmazza, ami megmondja, hogy melyik back-ends-re kell továbbítani a kérést. Három fő komponense van: * '''Route Rule: PathPrefixStrip:/hello/''' - ez maga a szabály, amit a compose fájlban megadtunk a label-ek segítségével. Ezt mondja meg, hogy ha olyan URL érkezik a Traefik-hez ami hello/-val kezdődik, akkor azt irányítsa a megadott backend-hez, úgy hogy a hello/-t levágja róla *'''Entry Points: http''' - http-n és nem https-en fogad kéréseket a frontend * '''Backend: backend-helloservice-helloworld''' - Ha a szabály teljesül, akkor erre a backend szolgáltatásra kell küldeni a kérést. '''Backends''': A backend listában egy darab szolgáltatás van: backend-helloservice-helloworld. Ebben a main fülön fel vannak sorolva a szolgáltatáshoz tartozó végpontok. Itt láthatjuk mind az 5 konténert, ami a hellword docker stack-hez tartozik. Láthatjuk az IP címüket, amiket a balancer-net overlay hálózaton kaptak. A Details fülön három értéket láthatunk: :[[File:ClipCapIt-180730-092055.PNG]]* '''Method: wrr''' - Ez az alapértelmezett load-balancer algoritmus (Weight Round Rubin, részletek itt: https://docs.traefik.io/basics/)* '''Stickiness: true''' - Ezt címkékkel mi adtuk meg* '''Cookie Name: _TRAEFIK_BACKEND''' - Ezt nem adtuk meg külön label-el, ez az alapértelmezett session süti név, ezzel tartja fent a sticky session-t. <br> ===Böngésző teszt=== :[[File:ClipCapIt-180728-165011.PNG]] Miért nem jelenik meg a kép?? http://www.littlebigextra.com/how-to-maintain-session-persistence-sticky-session-in-docker-swarm-with-multiple-containers/<br>https://boxboat.com/2017/08/03/deploy-web-app-docker-swarm-sticky-sessions/ :[[File:ClipCapIt-180719-233145.PNG|200px]]https://traefik.io/ <syntaxhighlight lang="C++">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:[</syntaxhighlight> <syntaxhighlight lang="C++">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"</syntaxhighlight> http://192.168.42.79:9090/dashboard/:[[File:ClipCapIt-180719-232503.PNG|900px]] ===cendra/virtualhost===https://hub.docker.com/r/cendra/virtualhost/ ===NGINGX===https://www.nginx.com/blog/docker-swarm-load-balancing-nginx-plus/#nginx-demo <br><br> =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
<br>
<br>