Docker Swarm Classic
Warning
Minden amit itt leírok már elavult. A swarm 1.0, vagy swarm classic helyét már átvette a swarm mode. Viszont fontos tudni, hogy mi tartozik a swarm classic-ba és a swarm mode-ba, mivel ezek folyton keveredő fogalmak a fórumokon, fontos tisztán látni.
Contents
Bevezető
https://docs.docker.com/swarm/reference/manage/
- A Swarm classic nem része az alap Docker programnak, ez egy független kiegészítése, amit külön kell telepíteni, ugyan úgy mint pl a docker-machine-t.
- A Swarm classic szabványos docker konténereket hoz létre a master és anode VM-eken. Külön konténert kap a swarm manager és külön konténert kap a swarm agent. Tehát a hagyományos Docker eszközkészletet használtja fel a swarm classic. Ezen konténerek segítségével telepíti aztán a swarm classic a megfelelő service-eket (konténereket) a node VM-eken.
- A swarm kezelésére nincsenek dedikált docker és compose parancsok. Be kell 'jelentkezni' swarm módban a manager VM-re, majd onnantól kezdve minden kiadott docker és compose parancs az egész cluster-re vonatkozik, nem a manager VM-en futó docker démonra. (Swarm mode-ban ez nem így van, ott saját parancs készlete van már a swarm-nak)
- A scheduling stratégiákat a swarm cluster létrehozásakor meg kell adni, a service-ek telepítése közben erre már nincs lehetőség. Tehát a docker-compose.yml fájl deploy szekcióját nem veszi figyelembe a swarm classic, az kizárólag a swarm mode-nak szól.
Kétféleképpen hozhatunk létre swarm classic cluster-t:
- Saját kezűleg hozzuk létre a docker-t futtató virtuális vagy fizikai gépeket. Ezeken manuálisan, docker parancsokkal hozzuk létre a master-t és a swarm node-okat.
- Használhatjuk a 'docker-machin' parancsot a '--swarm' kapcsolóval, hogy a megfelelő swarm cluster-hez is hozzáadja a létrehozott VM-et. Ez a funkció VM driver-től függetlenül működik, ez a funkció be van építve a 'docker-machine' programba, azonban kizárólag swarm classic cluster-t tud kezelni. (Azonban bizonyos driver-ek támogatják, hogy a létrehozott VM swarm mode cluster tagja legyen)
Bármelyik megoldást is választjuk a swarm cluster létrehozására, szükség van egy discovery szolgáltatóra, ahova a node-ok regisztrálják magukat. A master a discovery szolgáltatót folyamatosan poll-ozza, hogy hozzájusson az aktuális member listához.
Note
Ez a swarm mode-ban (swarm 2.0) már nincs így. Discovery service nélkül is képes a master megtalálni a node-okat.
Összesen 6 féle discovery API-t támogat a swarm classic. Kettőre kérnék itt ki részletesebben, amik gyakran keverednek swarm mode leírásokkal.
Forrás1: https://docs.docker.com/swarm/discovery/#docker-hub-as-a-hosted-discovery-service
Forrás2: https://docs.docker.com/swarm/reference/manage/
- token: A DockerHub által nyújtott, ingyenes discovery szolgáltatás. Produkciós környezetbe nagyon nem ajánlott.
- consul: A Consul egy ingyenes, lokálisan futó discovery szolgáltatás, ezt írja magáról: "Consul is a distributed service mesh to connect, secure, and configure services across any runtime platform and public or private cloud Service registry, integrated health checks, and DNS and HTTP interfaces enable any service to discover and be discovered by other services"
Swarm cluster DockerHub discovery service használatával
Ahogy már írtam fentebb, a swarm master-nek mindenképpen szüksége van egy discovery szolgáltatóra, hogy meg tudja találni a node-okat. A DocerkHub egy ingyenes, bárki számára elérhető discovery szolgáltatást nyújt. Ez azonban csak tesztelési és fejlesztési célokra használható, produkciós környezetben nem. Cserébe nagyon egyszerű a használata, mert nem kell hozzá extra szoftver komponenseket telepíteni, össz-vissz annyira van szükségünk, hogy a swarm-ot futtató VM-eknek legyen publikus internet elérése, hogy elérjék a DockerHub-ot.
Swarm cluster 'Consul' használatával
Cluster vizsgálata
# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4d6e01c1b7ce swarm:latest "/swarm join --adver…" 6 minutes ago Up 6 minutes 2375/tcp worker1/swarm-agent 116582ce7e0c swarm:latest "/swarm join --adver…" 9 minutes ago Up 9 minutes 2375/tcp swarm-master/swarm-agent 88440d8e5e1b swarm:latest "/swarm manage --tls…" 9 minutes ago Up 9 minutes 2375/tcp, 192.168.42.35:3376->3376/tcp swarm-master/swarm-agent-master
# docker info Containers: 3 Running: 3 Paused: 0 Stopped: 0 Images: 2 Server Version: swarm/1.2.9 Role: primary Strategy: spread Filters: health, port, containerslots, dependency, affinity, constraint, whitelist Nodes: 2 swarm-master: 192.168.42.35:2376 └ ID: UVDV:W5VI:NRDU:25KM:43GY:2ZL6:AIBL:TKKL:ASEG:JSMM:6DI5:NLLN|192.168.42.35:2376 └ Status: Healthy └ Containers: 2 (2 Running, 0 Paused, 0 Stopped) └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker └ UpdatedAt: 2018-07-04T20:45:47Z └ ServerVersion: 18.05.0-ce worker1: 192.168.42.181:2376 └ ID: SMB3:EZOK:OZJ7:22W6:3PBB:ZLCF:BUFA:VYMU:PLH5:RWBT:2E7D:GAOT|192.168.42.181:2376 └ Status: Healthy └ Containers: 1 (1 Running, 0 Paused, 0 Stopped) └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: kernelversion=4.9.93-boot2docker,
Swarm létrehozása docker-machine-al
Warning
A docker-machine paranccsal csak swarm classic cluster-t tudunk natívan építeni, swarm mode cluster-t nem tud létrehozni a VM legyártásakor, kivéve ha a driver ezt lehetővé teszi. Tehát a docker-machine parancs --swarm kapcsolója kizárólag swarm classic-hoz jó. Pl. az Amazon diver támogatja a swarm mode cluster létrehozását a VM legyártása közben.
Swarm inicializál
# docker run --rm swarm create Token based discovery is now deprecated and might be removed in the future. It will be replaced by a default discovery backed by Docker Swarm Mode. Other mechanisms such as consul and etcd will continue to work as expected. 7b1602e9fc114f1f47ad7ad4df41521c
Swarm ready VM-ek legyártása
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" \ --swarm --swarm-master --swarm-discovery="token://7b1602e9fc114f1f47ad7ad4df41521c" \ swarm-master ... Configuring swarm... Checking connection to Docker...
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" \ --swarm --swarm-discovery="token://7b1602e9fc114f1f47ad7ad4df41521c" node1 ... Configuring swarm... Checking connection to Docker...
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" \ --swarm --swarm-discovery="token://7b1602e9fc114f1f47ad7ad4df41521c" node2 ... Configuring swarm... Checking connection to Docker...
VM-ek ellenőrzése
# docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER node1 - kvm Running tcp://192.168.42.236:2376 swarm-master v18.05.0-ce node2 - kvm Running tcp://192.168.42.152:2376 swarm-master v18.05.0-ce swarm-master * (swarm) kvm Running tcp://192.168.42.54:2376 swarm-master (master) v18.05.0-ce
Note
A docker-machine ls parancsában a SWARM oszlop kizárólag a --swarm kapcsolóval létrehozott swarm classic cluster-re vonatkozik. A Swarm mode-al létrehozott cluster esetében ez az oszlop nem lesz kitöltve.
Láthatjuk a route táblában, hogy két KVM-re vonatkozó route bejegyzés van, ezek a virbr0 és a virbrDocker.
- A virbr0 a KVM docker-machine driver által létrehozott hálózat, amivel a VM-ek egymás között tudnak csak kommunikálni. Ez a default nevű KVM hálózat.
- A virbrDocker pedig az a hálózat amit mi definiáltunk korábban docker-network néven. Ez a hálózat kilát a publikus internetre. Ezt adtuk meg a VM-ek létrehozásakor.
# route Destination Gateway Genmask Flags Metric Ref Use Iface ... 192.168.122.0 0.0.0.0 255.255.255.0 U 0 0 0 virbr0 192.168.123.0 0.0.0.0 255.255.255.0 U 0 0 0 virbrDocker
Nézzük meg, hogy ezek melyik hálózatok a KVM szerint
# virsh net-list Name State Autostart Persistent ---------------------------------------------------------- default active yes yes docker-network active yes yes # virsh net-info default Name: default Bridge: virbr0 # virsh net-info docker-network Name: docker-network Bridge: virbrDocker
Swarm cluster ellenőrzése
Ezt bárhol lefuttathatjuk, nem csak a VM-eken. A swarm konténer le fogja kérdezni a Docker Hub-tol a node-ok listáját. Azért van három node, mert a master VM-en is fut egy swarm agent.
# docker run --rm swarm list token://7b1602e9fc114f1f47ad7ad4df41521c 192.168.42.152:2376 192.168.42.236:2376 192.168.42.54:2376
# eval "$(docker-machine env --swarm swarm-master)"
Innentől kezdve minden kiadott docker parancs az egész cluster-re fog vonatkozni.
# docker info Containers: 5 Running: 4 Paused: 0 Stopped: 1 Images: 4 Server Version: swarm/1.2.9 Role: primary Strategy: spread Filters: health, port, containerslots, dependency, affinity, constraint, whitelist Nodes: 3 node1: 192.168.42.236:2376 └ ID: 7AKJ:NJMX:6OW3:OWNJ:Q2AV:SXPH:SM4S:GY3B:TZMQ:QJIV:4UEB:6O65|192.168.42.236:2376 └ Status: Healthy └ Containers: 1 (1 Running, 0 Paused, 0 Stopped) └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker .. └ UpdatedAt: 2018-07-08T08:15:56Z └ ServerVersion: 18.05.0-ce node2: 192.168.42.152:2376 └ ID: 2K5X:CTUY:VOBF:AF5K:GBWU:3ICY:YJWJ:ALAY:6MDP:HAP4:JYHB:ZGRJ|192.168.42.152:2376 └ Status: Healthy └ Containers: 1 (1 Running, 0 Paused, 0 Stopped) └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker .. └ UpdatedAt: 2018-07-08T08:15:56Z └ ServerVersion: 18.05.0-ce swarm-master: 192.168.42.54:2376 └ ID: LHJT:XZ2H:YAEH:COC7:DQXM:PRCV:O4EA:3BEE:OZXC:R5GV:2DIC:GW75|192.168.42.54:2376 └ Status: Healthy └ Containers: 2 (2 Running, 0 Paused, 0 Stopped) └ Reserved CPUs: 0 / 1 └ Reserved Memory: 0 B / 1.021 GiB └ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Dock.. └ UpdatedAt: 2018-07-08T08:15:35Z └ ServerVersion: 18.05.0-ce
# docker ps -a CONTAINER ID IMAGE COMMAND PORTS NAMES 8d8167f3b9bc swarm:latest "/swarm join --adv..." 2375/tcp node2/swarm-agent 4d5b7b11a8dd swarm:latest "/swarm join --adv..." 2375/tcp node1/swarm-agent ea5bf0ae71e3 swarm:latest "/swarm join --adv..." 2375/tcp swarm-master/swarm-agent 7b135d1f0e64 swarm:latest "/swarm manage --t..." 2375/tcp, 192.168.42.54:3376->3376/tcp swarm-master/swarm-agent-master
Látható, hogy egy-egy swarm agent konténer fut a node nevű gépeken és egy agent és a master fut a swarm-master nevű gépen. Az agent konténerek számára a 2375 (alapértelmezett) port van kinyitva, itt beszélgetnek a master-rel. A master meg a 3376-os porton érhető el.
Nézzünk megy egy agent konténert:
# docker inspect 8d8167f3b9bc ... "IP": "192.168.42.152", "Addr": "192.168.42.152:2376", "Name": "node2", }, "Name": "/swarm-agent", "Config": { "ExposedPorts": { "2375/tcp": {} }, "Env": [ "SWARM_HOST=:2375" ], "Cmd": [ "join", "--advertise", "192.168.42.152:2376", "token://7b1602e9fc114f1f47ad7ad4df41521c" ], "Volumes": { "/.swarm": {}
Láthatjuk hogy az agent-nek a 2375-ös portja van nyitva, a swarm volume van felcsatolva, és hogy a konténer az alábbi argumentumokat kapta meg a docker run parancsban.
join --advertise "192.168.42.152:2376" token://7b1602e9fc114f1f47ad7ad4df41521c
Scheduling
Note
docker classic-ban nem tudjuk még a compose YAML fájlban megadni a kiosztási stratégiát (deploy szekció)!. A példányszámot a compose scale parancsával kell megadni, a kiosztási stratégiát pedig a swarm master létrehozásakor kell definiálni. Ez az egész cluster-re vonatkozni fog, és nem lehet megváltoztatni.
Szolgáltatás konténer száma
Írjunk egy nagyon egyszerű service-t. A compose fájlnak adjuk a flock.yml nevet az alábbi tartalommal
bird:
image: dockerinaction/ch12_painted
command: bird
restart: always
Tehát egy darab bird nevű service-t definiálunk, úgy hogy mindig indítsa újra a docker, ha leáll.
Majd indítsuk el 10 példányban a bird nevű szolgáltatásunkat.
# docker-compose -f flock.yml scale bird=10
Most nézzük meg mi jött létre:
# docker ps CONTAINER ID IMAGE COMMAND NAMES 5606975758f4 painted "/magic.sh bird" node2/bird_bird_4 816db74ca4d5 painted "/magic.sh bird" swarm-master/bird_bird_7 9bec876d658c painted "/magic.sh bird" swarm-master/bird_bird_2 d3481b35d14d painted "/magic.sh bird" node1/bird_bird_9 1e5994ed2820 painted "/magic.sh bird" node2/bird_bird_5 44729be69074 painted "/magic.sh bird" node1/bird_bird_6 f2101718f2ab painted "/magic.sh bird" swarm-master/bird_bird_8 9c42193745e2 painted "/magic.sh bird" node2/bird_bird_1 6c1e97342499 painted "/magic.sh bird" node1/bird_bird_10 aa97325e8cb6 painted "/magic.sh bird" node1/bird_bird_3
Láthatjuk, hogy 10 konténer jött létre, 3-3 a node2-ön és a swarm-master-en, és 4 a node1-en. A konténer neve mindig a node nevével kezdődik, majd jön az image név majd a sorszáma a replikának.
Kiosztási stratégiák
A kiosztási stratégiát a master létrehozásakor kell megadni a --swarm-strategy kapcsolóval. Három stratégia közül választhatunk:
spread
Egyenlően akarja elosztani, mindig a leg kevéssé leterhelt node-ra. Ha két node azonosan van leterhelve, akkor arra rakja, amin kevesebb konténer fut. Akkor hatásos, ha a konténereken limitálva van az erőforrás foglalás, és ha definiált erőforrás limitek nem térnek el nagyban egymástól.
Ez az alapértelmezett, ha nem adunk meg semmit, akkor mindig spread lesz.
docker-machine create -d kvm --kvm-network "docker-network" --kvm-disk-size "5000" \ --swarm --swarm-master \ --swarm-discovery="token://7b1602e9fc114f1f47ad7ad4df41521c" \ --swarm-strategy=spread swarm-master
BinPack
Mindig egy node-ot megpróbál maximálisan kihasználni, mielőtt egy új node-ra tenni az új konténert. Csak akkor tud jól működni, vagy bárhogy működni, ha minden konténert erőforrás megkötésekkel hozunk létre. Akkor hasznos, ha nagyon nagy a különböző erőforrást igénylő konténerek variációja, de ugyanakkor meg van adva az erőforrást megkötés minden konténerhez. Ezzel ellentétben a Spread akkor volt jó, ha hasonló volt az erőforrás igénye az összes konténernek.
Random
Filterek
A filterek hasonlón működnek a swarm cluster-ben mint az itables filterek. Mikor egy újonnan létrehozandó konténernek keresi a swarm a helyét, hogy melyik node-ra rakja, akkor elsőként a szóba jöhető node-okat végig futtatja a filter láncon. Egy node akkor marad bent a lehetséges node-ok listájában, ha a láncon sehol nem akadt fent.
A filter paramétereket a compose vagy a run -ba kell -e <filter név>==<filter érték> formában. pl:
docker run -d -e affinity:image==nginx nginx
Öt gyári filter lánc van:
health, port, containerslots, dependency, affinity, constraint, whitelist
affinity
Egy megkötés már a node-ra telepített konténerekre. Azt mondja meg, hogy csak olyan node-ko jöhetnek szóba, ahol már van ilyen konténer, amit megadtunk az effinity paramétereként.
Azon node-ok, ahova az nginx már fel van rakva:
# docker run -d -e affinity:image==nginx -p 80:80 nginx
Azon node-ok ahova az nginx még nincs felrakva:
# docker run -d -e affinity:image!=nginx -p 8080:8080 haproxy
health
constraint
Megkötés bármilyen VM tulajdonságra. Vagy a beépített tulajdonság változókat használjuk, vagy sajátokat adhatunk meg a docker-machine create --engine- label használatával, amire később hivatkozhatunk.
Van 5 beépített tulajdonság:
- node —The name or ID of the node in the cluster
- storagedriver —The name of the storage driver used by the node
- executiondriver —The name of the execution driver used by the node
- kernelversion —The version of the Linux kernel powering the node
- operatingsystem —The operating system name on the node
Ezeket a docker info parancs minden node-ra megmutatja:
# docker info node1: 192.168.42.236:2376 └ ID: 2K5X:CTUY:VOBF:AF5K:GBWU:3ICY:YJWJ:ALAY:6MDP:HAP4:JYHB:ZGRJ|192.168.42.152:2376 └ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker 18.05.0-ce
A custom címkéket a --engine-label kapcsolóval kell megadni a VM létrehozásakor:
# docker-machine create -d kvm --kvm-network "docker-network" \ --swarm --swarm-discovery token://7b1602e9fc114f1f47ad7ad4df41521c \ --engine-label size=small \ little-machine
Majd így hivatkozhatunk rá a run parancsban:
# docker run -d -e constraint:size==small postgres
Ez azt jelenti, hogy csak olyan node-ok jöhetnek szóba az új konténer futtatására, amik size=small címkével lettek létrehozva.
- port
- dependency