- CoreOS – moderní clusterovaný OS pro datová centra (1) – Úvod a instalace
- CoreOS – moderní clusterovaný OS pro datová centra (2) – Etcd, distribuovaný state
- CoreOS – moderní clusterovaný OS pro datová centra (3) – Etcd a konzistence
- CoreOS – moderní clusterovaný OS pro datová centra (4) – Fleet
- CoreOS – moderní clusterovaný OS pro datová centra (5) – pokročilý Fleet
- CoreOS – moderní clusterovaný OS pro datová centra (6) – je to Docker orchestrátor?
V předchozím povídání o CoreOS Fleet jsme si představili tento cluster init systém, jakousi distribuovanou verzi systemd. Startovali jsme jednu službu na libovolném nodu nebo globálně spouštěli službu na všech nodech. Dnes si zkusíme nějaké pokročilejší věci jako je ovlivňování, kde co je a jak, spouštění více kopií služby apod.
Použijeme teď zase podobnou službu (ve formě spuštěného Docker kontejneru) jako minule, ale tentokrát půjde o šablonu. Soubor pojmenujeme mojesluzba@.service. Následně v parametrech X-Fleet zakážeme plánovači, aby spustil dvě kopie této služby na jednom nodu. Parametr Conflicts říká, že pokud služba s názvem mojesluzba@* (kde * je cokoli) už na nodu běží, není to vhodný uzel pro spuštění další kopie.
[Unit] Description=mojesluzba After=docker.service Requires=docker.service [Service] TimeoutStartSec=0 ExecStartPre=-/usr/bin/docker kill mojesluzba ExecStartPre=-/usr/bin/docker rm mojesluzba ExecStartPre=/usr/bin/docker pull busybox ExecStart=/usr/bin/docker run --name mojesluzba busybox ping 127.0.0.1 ExecStop=/usr/bin/docker stop mojesluzba [X-Fleet] Conflicts=mojesluzba@*.service
Šablonu máme a teď stačí jen spustit její klony jednoduše tím, že za zavináč doplníme nějaké číslo.
core@core-01 ~ $ fleetctl start mojesluzba@1 Unit mojesluzba@1.service inactive Unit mojesluzba@1.service launched on 89a25131.../172.17.8.102 core@core-01 ~ $ fleetctl start mojesluzba@2 Unit mojesluzba@2.service inactive Unit mojesluzba@2.service launched on 9d9f5e11.../172.17.8.101
Máme je spuštěné a jsou na odlišných uzlech.
core@core-01 ~ $ fleetctl list-units UNIT MACHINE ACTIVE SUB mojesluzba@1.service 89a25131.../172.17.8.102 active running mojesluzba@2.service 9d9f5e11.../172.17.8.101 active running
Služba s parťákem
Jeden z problémů distribuovaných aplikací je objevit, kde se služby nacházejí – které jsou naživu a jak je možné je kontaktovat (třeba IP adresa). Vezměte v úvahu, že v kontejnerových (ale i IaaS) platformách nevíte dopředu, kde služba bude, což v případě kontejneru (a v některých modernějších přístupech v IaaS taky) znamená, že nevíte na které IP služby poběží. Na discovery služeb a vyměňování informací v distribuovaném systému znám jedno perfektní řešení – Etcd. Už zase. Můžeme přímo využít Etcd, které je nativně součástí CoreOS clusteru (a které využívá i samotný Fleet) k signalizaci a service discovery. Můžeme se službou spustit jejího parťáka. Tento kolega bude monitorivat jestli služba dobře funguje a zaregistruje ji do Etcd.
V našem případě to uděláme velmi jednoduše (takže o nějakém sofistikovaném monitorování stavu se mluvit nedá). Co kdybychom vytvořili službu, která v pravidelných intervalech 45 vteřin bude zapisovat někam do Etcd název hlavní služby (třeba mojesluzba@1) společně s IP adresou hostitele s tím, že TTL tohoto zápisu je 60 vteřin. Tím se záznam bude obnovovat a když se odmlčíme, záznam se sám vymaže (takže ostatní aplikace budou vědět, že tato instance služby už neexistuje).
Založme si šablonu pro parťáckou službu mojediscovery@.service. Všimněte si některých zásadních nastavení. Parťák nastartuje vždy až po mojesluzba a je s ní přímo svázán (tedy jeho smrt je spojena se smrtí mojesluzba). Současně tato služba (třeba s číslem 1) musí být spuštěna na stejném nodu, kde je mojesluzba stejného čísla (to dělá řádek MachineOf).
[Unit] Description=Zapis hostname hostitele sluzby BindsTo=mojesluzba@%i.service After=mojesluzba@%i.service [Service] ExecStart=/bin/sh -c "while true; do etcdctl set /sluzby/mojesluzba@%i %H --ttl 60;sleep 45;done" ExecStop=/usr/bin/etcdctl rm /sluzby/mojesluzba@%i [X-Fleet] MachineOf=mojesluzba@%i.service
Nastartujte parťáky.
core@core-01 ~ $ fleetctl start mojediscovery@1 mojediscovery@2 Unit mojediscovery@1.service inactive Unit mojediscovery@2.service inactive Unit mojediscovery@2.service launched on 9d9f5e11.../172.17.8.101 Unit mojediscovery@1.service launched on 89a25131.../172.17.8.102
Podívejme se teď do zápisů v Etcd.
core@core-01 ~ $ etcdctl ls /sluzby /sluzby/mojesluzba@1 /sluzby/mojesluzba@2
Záznamy tam máme – a určitě i s krátkým TTL.
core@core-01 ~ $ etcdctl -o extended get /sluzby/mojesluzba@1 Key: /sluzby/mojesluzba@1 Created-Index: 37207 Modified-Index: 37207 TTL: 21 Index: 37266 core@core-01 ~ $ etcdctl -o extended get /sluzby/mojesluzba@2 Key: /sluzby/mojesluzba@2 Created-Index: 37278 Modified-Index: 37278 TTL: 56 Index: 37284
V praxi by byl parťák chytřejší a pokud je naše hlavní služba třeba web server, zkoušel by jeho dostupnost na aplikační rovině. K čemu jsou nám tyto záznamy dobré? Představte si třeba, že další službou by byl load-balancer jako je NGINX nebo haproxy. Tento balancer bude mít virtuální IP a bude balancovat na pool web serverů. Není problém tento pool dynamicky aktualizovat podle záznamů v Etcd! Jednoduše nastartujte další kontejnery a balancer se je sám naučí a začne na ně posílat provoz.