O tym jak kontenery Docker poprzez RexRay mieszkają na ScaleIO
Jak wiemy Docker dorobił się jak na razie 2 natywnych mechanizmów HA – Swarm klasyczny (do wersji 1.11) i Swarm wbudowany (od 1.12). Obydwa działają bardzo sprawnie i potrafią po awarii jednego z węzłów uruchomić kontenery na innym żyjącym węźle. Jeśli kontenery reprezentowały usługi tymczasowe, takie jak np. mikroserwisy, lub stanowiły ogniwa łączące inne komponenty, to zazwyczaj ich tzw. „dane” ograniczają się do tego co zawierają ich Dockerfile. Obydwa Swarmy, stary i nowy, poradzą sobie z ich ponownym uruchomieniem i jeśli kontenery faktycznie były stateless, to użytkownik nie zauważy zbyt długiej przerwy w działaniu usługi. Wszystko ładnie się uruchomi i będzie dalej działać jak gdyby nigdy nic.
Problem pojawia się gdy działający kontener posiadał w środku jakieś ważne dane. Najgorzej gdy przy uruchamianiu nie użyto opcji „-v” – wtedy po awarii hardware dane z kontenera są bezpowrotnie utracone. Jeśli przy uruchamianiu zmapowano volumen z hosta wtedy jest jakaś szansa że nasze dane są gdzieś w backupach hosta. Pytanie tylko jak często ten backup był wykonywany oraz czy admin backupu przez przypadek „nie pominął” zamapowanego katalogu/filesystemu. Niestety nawet jeśli mamy trochę szczęścia i nasze dane są do odzyskania to nadal mamy problem. Opcja z długotrwałym oraz co gorsze ręcznym restore to nie jest przecież HA. Nasi użytkownicy na pewno zauważą że nasza usługa zaliczyła awarię. Co więcej – pewna część danych na pewno ucieknie – a już na pewno te zapisy które były realizowane po ostatnim backupie.
Dla przypomnienia krótka podstawowa teoria o dockerowym mapowaniu wolumenów:
Wersja z podaniem volumenu
HARDWARE# docker run -ti -v /dane –name=ubuntu02 ubuntu:14.04
root@4789861ae201:/# ls -l /dane
total 0
root@4789861ae201:/# touch /dane/PLIK
root@4789861ae201:/# exit
kontener umiera ale na hoście dane nadal są w /var/lib/docker/volumes/ID_KONTENERA :
HARDWARE # ls -l
/var/lib/docker/volumes/e48a58edc4c47f6fea5bec4b80cfb00bf7ceb9d16872401469d7e475941a864c/_data/
-rw-r–r–. 1 root root 0 Sep 9 11:34 PLIK
Po awarii da się jakoś pozbierać to do kupy pod warunkiem że gdzieś mamy w backupach nasze dane.
Wersja jeszcze lepsza – podanie gdzie na nasz HARDWARE mają trafiać dane z katalogu kontenera
HARDWARE # docker run -ti -v /katalog:/dane –name=ubuntu03 ubuntu:14.04
root@d9b31b8dadd9:/# ls -l /dane
total 0
root@d9b31b8dadd9:/# touch /dane/PLIK
root@d9b31b8dadd9:/# exit
exit
kontener umiera ale na hoście dane nadal są w folderze „/katalog” :
HARDWARE # ls -l /katalog/
-rw-r–r–. 1 root root 0 Sep 9 11:41 PLIK
Patrząc na powyższe idealnym byłoby rozwiązanie podające swarmowi na tacy wszystkie ważne dane na każdym jego węźle (czyli w powyższym przykładzie fajnie jakby na każdym węźle był folder „/katalog”). W sumie jeszcze lepiej by było gdyby te dane nie były montowane na każdym węźle swarma (bo i po co) ale tylko tam gdzie jest to potrzebne. I żeby swarm się nie musiał tym bezpośrednio zajmować tylko wysyłał rozkaz do jakiegoś mechanizmu który za niego to załatwi. I najlepiej żeby gadał RESTem (skoro wszystko w dockerze gada RESTem). No i ważne żeby było w miarę wydajnie i zarządzalnie. Oczywiście – jasne – można by to zrobić NFSem, koniec artykułu.
Na powyższe wyzwanie środowisko dockera odpowiedziało całą batalią storage-driverów. Co więcej – w temat zaangażowali się nawet wielcy gracze (SolidFire od Netappa , rex-ray od EMC) ale również mniejsi (np. Convoy od Ranchera czy Flocker z Clusterhq).
Moją uwagę zwrócił rex-ray ponieważ z racji pochodzenia znakomicie integruje się z EMC scale-io – twórcy drajwera czyli grupa EMC-code to część programistów z EMC. A scale-io to już świat niemal równy z legendarnym i kultowym CEPH… a skoro CEPH to już nie ma żartów, proszę zapiąć pasy. Zresztą EMC twierdzi że scaleio jest groźnym konkurentem dla CEPHa w kontekście wydajności, pozycjonowanie zatem mają idealne. Jako przyjemny dodatek – rexray integruje się też z virtualboxem, co jest bardzo fajnym podejściem. Zwykły użytkownik chciałby przecież najpierw potestować sobie rozwiązanie w domowym labie zanim wrzuci drajwer na te 500+ maszyn w DC.
Na początek trochę o samym scale-io – wycięte wprost z dokumentacji czym to w ogóle jest:
W olbrzymim skrócie – scaleio to taka storagowa „spółdzielnia”. Każdy może przystąpić do niej ale fajnie jakby jako wpisowe wniósł do spółdzielni dysk minimum 100GB, co oczywiście da się obejść. Do wspólnego worka można zatem powrzucać wszystkie stare serwery – byle miały jakieś dyski. Dyski te wspólnie stworzą wielką pulę wolnego miejsca, im więcej serwerów tym lepiej. Serwer wnoszący jako wpisowe swój dysk to Scaleio Data Server (SDS). Komponent SDS zatem instaluje się na każdej maszynie która chce/musi oddać trochę swojego storage dla spółdzielni. Z drugiej strony są „biorcy storage” – czyli klienci spółdzielni – tzw. Scaleio Data Clients (SDC). Komponent SDC instaluje się zatem na każdej maszynie która chciałaby korzystać z dobrodziejstwa naszej wielkiej puli wolnego miejsca. Całość komunikacji między siecią SDS a siecią SDC odbywa się mechanizmami scaleio i robiona jest oczywiście po TCP/IP. Zarządzanie spółdzielnią spoczywa w rękach 3 managerów (MDM) Główny to master, zastępca to slave i ten trzeci który nie zarządza ale bierze udział w wyborze managera głównego, tzw. tie-breaker.
Idealnym modelem implementacji scaleio jest olbrzymia sieć serwerów gdzie na każdym pracuje po kilka SDS + kilka SDC. Dodatkowo na 3 (lub nawet 5) z nich jest MDM. Poniższy rysunek znalazłem w dokumentacji i świetnie obrazuje podręcznikowe wdrożenie scale-io:
Powyższe to już raczej duża instalacja. Ale że węzły SDS i SDC można zawsze dodać potem, mój LAB opiera się na 3 serwerach. Na każdym z nich jest 1 SDS, 1 SDC i 1 MDM. Oto zatem uproszczony schemat:
Scale-io instaluje się bardzo prosto specjalnym webowym narzędziem (IM) który zaciąga odpowiednie paczki i instaluje je na wszystkich komponentach. Dokumentacja jest dobra a instalacja nie przysparza większych problemów. Wspierane jest centos/rhel i ubuntu (odradzam). Efekt końcowy w IM jawi się następująco:
Jak widać mamy 3 maszyny – na każdej SDS+SDC oraz MDM.
Po zakończonej instalacji można odpalić pierwsze komendy i utworzyć sobie pierwsze urządzenia i wolumeny (poleceniem do wszystkiego – czyli scli):
Krok 1 – zalogowanie do MDM-master
[root@centos04 ~]# scli –login –username admin –password XXXXXX
Krok 2 – dodanie do wspólnego worka dysków minimum 100GB na każdej z maszyn (na moich 3 maszynach to wykrojone na szybko dodatkowe małe dyski /dev/sdb) :
[root@centos04 ~]# scli –add_sds_device –sds_ip 192.168.56.105 –protection_domain_name default –storage_pool_name default –device_path /dev/sdb
Successfully added device /dev/sdb to SDS. New device ID: 0589894700020000
[root@centos04 ~]# scli –add_sds_device –sds_ip 192.168.56.106 –protection_domain_name default –storage_pool_name default –device_path /dev/sdb
Successfully added device /dev/sdb to SDS. New device ID: 0589894800010000
[root@centos04 ~]# scli –add_sds_device –sds_ip 192.168.56.107 –protection_domain_name default –storage_pool_name default –device_path /dev/sdb
Successfully added device /dev/sdb to SDS. New device ID: 0589894900000000
Krok 3 – utworzenie pierwszego wolumenu:
[root@centos04 ~]# scli –add_volume –protection_domain_name default –storage_pool_name default –size_gb 10 –volume_name scale_vol_01
Warning: Rounding up the volume size to 16 GB
Successfully created volume of size 16 GB. Object ID 1148690400000000
Krok 4 – finalny – zamapowanie wolumenu do jednego z SDC:
[root@centos04 ~]# scli –map_volume_to_sdc –volume_name scale_vol_01 –sdc_ip 192.168.56.106
Successfully mapped volume scale_vol_01 to SDC 192.168.56.106
Po tych czynnościach otrzymujemy efekt końcowy – na maszynie 192.168.56.106 pojawiło się nowe urządzenie blokowe (scaleio nazywa je /dev/scinia,b,c itd.) :
[root@centos04 tmp]# ls -l /dev/scinia
brw-rw—-. 1 root disk 252, 0 Sep 9 04:46 /dev/scinia
Oczywiście miejmy świadomość że jest to emulacja i że to urządzenie jest niby blokowe ale tak naprawdę przyszło do nas na maszynę mechanizmami TCP/IP poprzez mechanizmy scale-io.
Bardzo przydatnym (i w miarę ładnym) narzędziem jest graficzne GUI które instaluje się jako osobną paczkę (gdziekolwiek – byle miało połączenie z MDM’ami) – jest to GUI X-owe a więc trzeba jakiś desktop manager sobie niestety zainstalować. Po wywołaniu GUI (via /opt/emc/scaleio/gui/run.sh) otrzymujemy aplikację:
Dashboard pokazuje kondycję całego systemu. Zielona część kółka po lewej to miejsce zajęte (nasz wolumen ma 16 GB ale scale-io robi redundancję 2N stąd 32 GB), niebieska część to spare capacity a szara to miejsce do wykorzystania. A że moje 3 maszyny wniosły do puli dyski po ok. 109 GB każda to mamy w całości 325 GB. W systemie mamy oczywiście 3 x SDS, 3 x SDC i 1 Volumen (który jest w stanie „mapped” gdyż parę poleceń wcześniej zamapowaliśmy go do hosta 192.168.56.106).
Oprócz tego możemy obejrzeć wolumeny:
Lista SDC:
A najlepsza jest zakładka „BACKEND” gdzie mamy wszystko kawę na ławę:
No dobra , scaleio tworzy nam urządzenia, zarządza wspólną przestrzenią, ma ładne GUI itd. Teraz trzeba by to jakoś zintegrować z dockerem. I właśnie do tego służy rex-ray.
Jak widać na poniższym wycinku z dokumentacji metod sterowania scale-io jest kilka – pierwszy i drugi mamy przećwiczony, trzeci dotyczy jakiejś zmurszałej technologii (he he) , czwarty jest do cindera, a oczywiście ten ostatni (REST) interesuje nas najbardziej.
Rest Gateway instaluje się z automatu razem z webowym installation managerem (IM), tyle że ma nieco inny URL gdyż zamiast:
https://IP_MASZYNY_Z_IM/maintain.jsp
jest:
https:// IP_MASZYNY_Z_IM /api
Już za chwilę będziemy się dobierać do tegoż REST Gatewaya z poziomu dockera ale najpierw słowo o rex-ray. Otóż jest to projekt open source kierowany przez grupę zapaleńców z EMC-code. Oto strona projektu na githubie:
https://github.com/emccode/rexray
Czym jest rexray? Najlepiej zacytować chyba z githubowej strony projektu:
“REX-Ray provides a vendor agnostic storage orchestration engine. The primary design goal is to provide persistent storage forDocker containers as well as Mesos frameworks and tasks.”
A tu nagłówek z dokumentacji:
“REX-Ray is a storage orchestration tool that provides a set of common commands for managing multiple storage platforms. Built on top of the libStorage framework, REX-Ray enables persistent storage for container runtimes such as Docker and Mesos.”
Ogólnie chłopaki z emc-code naprawdę dają radę i jak się przejrzy ich repozytoria to produkują kilkadziesiąt różnych fajnych lub bardzo fajnych platform:
Dodatkowo należy podkreślić że poświęcają swój czas również na ułatwiacze dla potencjalnego klienta, gdyż większość swoich zabawek udostępniają via vagrant (tak aby sobie jednym poleceniem postawić całe środowisko i potestować). Przykładowo polecam poniższe repozytorium:
https://github.com/emccode/vagrant/tree/master/scaleio
Wystarczy mieć virtualboxa i vagranta a następnie zrobić git clone a potem vagrant up i mamy po dłuższej chwili wszystko na swoim laptopie. W wyniku tego stawiane są z automatu 3 centosy, na nich klaster scaleio wraz z driverem rex-ray a na końcu docker. Oczywiście jak to w automatach – wtedy nie wiemy zupełnie co się stało na naszych systemach i jak to wszystko działa jedno z drugim J
Dlatego jednak polecam metodę krok po kroku czyli stawianie ręczne, ewentualnie można zdoktoryzować się z zawartości Vagrantfile’a żeby obejrzeć jak emc-code to robią i potem co najwyżej powtórzyć ręcznie ich instalacje.
Wracając do rex-ray – instalacja jest realizowana poprzez curla:
curl -sSL https://dl.bintray.com/emccode/rexray/install | sh –
w wyniku tego w systemie pojawia się usługa rex-raya, trzeba tylko dorobić dla niej konfigurację. Konfiguracja jest w YAMLu, jeśli nie chce nam się jej tworzyć ręcznie to na stronie jest generator :
http://rexrayconfig.emccode.com
Tzn jeszcze pod koniec sierpnia był ale potem w wyniku merge DELL z EMC pojawił się pod innym adresem:
http://rexrayconfig.codedellemc.com/
Inne adresy URL podane w tym artykule też mogły przemigrować na tę nową domenę.
Oto mój konfig rexraya, jest on na wszystkich 3 maszynach taki sam:
[root@centos04 tmp]# cat /etc/rexray/config.yml
rexray:
logLevel: error
libstorage:
logging:
level: error
service: scaleio
scaleio:
insecure: true
thinOrThick: ThinProvisioned
endpoint: https://192.168.56.100/api
password: XXXXXX
userName: admin
protectionDomainName: default
storagePoolName: default
apiVersion: 2.0
Przed sprawdzeniem czy rexray rozmawia ze scaleio-rest-gatewayem należy przetestować połączenie scaleio-rest-gateway’a do scaleio-MDM – najlepiej curlem:
curl –insecure –user admin:XXXX https://adres-scaleio-rest-gatewaya/api/login
“YWRtaW46MNTI0NTpmMjU2M2Q1OGEwNzZmMTk0NWRiNjBlMTdhNTYyNw”
Jak nam się wygeneruje ten długi token to dobrze, jak nie – to znaczy że coś poszło nie tak i trzeba poczytać issues na githubie. Krok z curlem to w sumie finalny test całości środowiska – czy wszystkie komponenty gadają ze sobą, czy się widzą, czy wszystko działa, czy nie ma błędów itd.
Curl należy wykonać z każdego węzła na którym będzie docker – czyli z każdego węzła gdzie jest rexray (a zatem z każdego SDC).
Mechanizm działania polega na komunikacji serwisu rexray ze scale-io-rest-gateway’em. Następnie tenże rest-gateway rozmawia z jednym z MDM jakie ma na liście. MDM oczywiście steruje pracą klastra scaleio (czyli grupą N x SDC i N x SDS). Rest Gateway potrafi pracować w HA.
Po poprawnej weryfikacji curlem należy zweryfikować działanie samego rexray – na razie bez dockera. Sprawdzamy na każdym węźle czy rexray łączy się z rest-gatewyem i czy zobaczy konfigurację scale-io:
[root@cent03 tmp]# rexray volume
– attachments:
– instanceID:
id: d9ce935400000001
driver: scaleio
volumeID: “1148690400000000”
availabilityZone: default
name: scale_vol_01
size: 16
id: “1148690400000000”
type: default
[root@cent04 ~]# rexray volume
– attachments:
– instanceID:
id: d9ce935400000001
driver: scaleio
volumeID: “1148690400000000”
availabilityZone: default
name: scale_vol_01
size: 16
id: “1148690400000000”
type: default
[root@cent05 ~]# rexray volume
– attachments:
– instanceID:
id: d9ce935400000001
driver: scaleio
volumeID: “1148690400000000”
availabilityZone: default
name: scale_vol_01
size: 16
id: “1148690400000000”
type: default
Volumen był jeden (scale_vol_01) – widać go na każdym węźle, weryfikacja się udała.
Skoro można sterować klastrem scale-io za pomocą rexray to sprawdźmy czy da się założyć wolumen:
[root@cent05 ~]# rexray volume create –size=16 –volumename=”scale_vol_02″ –availabilityzone=”default”
availabilityZone: default
name: scale_vol_02
size: 16
id: 1148de3100000001
type: default
Sprawdźmy czy go widać:
[root@cent05 ~]# rexray volume
– attachments:
– instanceID:
id: d9ce935400000001
driver: scaleio
volumeID: “1148690400000000”
availabilityZone: default
name: scale_vol_01
size: 16
id: “1148690400000000”
type: default
– availabilityZone: default
name: scale_vol_02
size: 16
id: 1148de3100000001
type: default
Jak widać udało się rexrayem stworzyć kolejny wolumen – w GUI też już go widać:
Co ciekawe nasze 2 wolumeny są widoczne z poziomu wszystkich dockerów na 3 węzłach:
Docker jak widać rozmawia z serwisem rexray, co więcej – gdy wyłączy się usługę rexray, docker zaczyna mieć problemy z obsługą wolumenów:
[root@cent03 ~]# docker volume ls
list rexray: Post http://%2Frun%2Fdocker%2Fplugins%2Frexray.sock/VolumeDriver.List: dial unix /run/docker/plugins/rexray.sock: connect: connection refused
Oczywiście docker nadal potrafi zarządzać lokalnymi zwykłymi wolumenami:
[root@cent03 ~]# docker volume create –name=test01
test01
[root@cent03 ~]# docker volume ls
DRIVER VOLUME NAME
rexray scale_vol_01
rexray scale_vol_02
local test01
Oczywiście takich zwykłych wolumenów nie widać na pozostałych hostach:
Stwórzmy zatem teraz kolejny wolumen ale już rexrayem licząc na to że pojawi się on w całym klastrze scale-io:
Jak widać na każdym węźle docker pokazuje obecność tego wolumenu, pojawił się także w scale-io-GUI:
Wolumen został zamapowany – oczywiście tylko do tego węzła gdzie uruchomiliśmy kontener (centos03 – 192.168.56.105)
Co zatem tu zaszło? Wydaliśmy dla przypomnienia polecenie:
docker run -tdi -v docker_vol_01:/dane –volume-driver=rexray ubuntu:14.04
A zatem przy tworzeniu kontenera silnik dockera połączył się z serwisem rexray i zlecił mu utworzenie wolumenu. Serwis rexray połączył się z scale-io-rest-gatewayem który zlecił resztę prac do warstwy MDM. MDM oczywiście utworzył wszystko w warstwie SDC i SDS. W SDC pojawiło się urządzenie blokowe (/dev/sciniX) które teraz służy jako storage dla wolumenu nowo powołanego kontenera.
To może dla podsumowania jeszcze jedna próba – tym razem na węźle gdzie jeszcze nie ma żadnych urządzeń blokowych SDC.
Takim węzłem jest jak widać maszyna 192.168.56.107 – co prawda ma SDC ale nie ma jeszcze żadnych zamapowanych wolumenów (co widać w GUI jako 0 w kolumnie Mapped Volumes).
Pojawiło się nowe blokowe urządzenie /dev/scinia.
Rexray jako tako po sobie sprząta (co w świecie dockera wcale nie jest takie oczywiste) – jak widać usuwa urządzenie blokowe z SDC:
Niestety ale z defaultu nie usuwa wolumenów w samym scale-io – jedynie odmapowuje je od węzłów:
Czas na swarma i swarm-service który wykorzysta całą funkcjonalność jaką do tej pory omawialiśmy. Zacznijmy od porządków – usuwamy wszystko co do tej pory było tworzone aby mieć czyste systemy. W wyniku tego na żadnym node nie ma wolumenów. W międzyczasie tworzymy też 3 węzłowy klaster swarma:
Tworzymy usługę (w swarm tzw. „service”) ze specjalną opcją do wolumenów (w service nie ma przełącznika „-v”) – czyli „–mount” (z całą batalią dodatkowych opcji ad punkty montowania, nazwa wolumenu i wskazanie drivera raxray):
[root@cent03 ~]# docker service create –replicas 1 –name service_1 \
–mount type=volume,source=service_1_vol,target=/data,volume-driver=rexray \
ubuntu:14.04 tail -f /dev/null
4m1i3uj6pkrpngl165sxnxokm
[root@cent03 ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
4m1i3uj6pkrp service_1 0/1 ubuntu:14.04 tail -f /dev/null
[root@cent03 ~]# docker service ps service_1
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
1qnqbt5zg1x6sy7wlbkes9pbd service_1.1 ubuntu:14.04 cent04 Running Running 1 minute ago
Utworzył się volumen:
[root@cent03 ~]# docker volume ls
DRIVER VOLUME NAME
rexray service_1_vol
Widoczny również na pozostałych węzłach:
[root@cent03 ~]# ssh 192.168.56.107 “hostname; docker volume ls”
cent05
DRIVER VOLUME NAME
rexray service_1_vol
[root@cent03 ~]# ssh 192.168.56.106 “hostname; docker volume ls”
cent04
DRIVER VOLUME NAME
rexray service_1_vol
Service posiada liczbę replik = 1 , więc reprezentowany jest przez 1 kontener – w naszym przypadku trafił on na maszynę cent04:
[root@cent03 ~]# docker service ps service_1
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
1qnqbt5zg1x6sy7wlbkes9pbd service_1.1 ubuntu:14.04 cent04 Running Running 5 minutes ago
I oczywiście tylko na tej maszynie pojawiło się urządzenie /dev/sciniX (w tym wypadku X=a):
Po wywołaniu awarii otrzymujemy :
[root@cent04 ~]# service docker stop
[root@cent04 ~]# ls -l /dev/scini*
crw-r–r–. 1 root root 248, 0 Sep 16 10:31 /dev/scini
Swarm zmigrował usługę na inny węzeł
[root@cent03 ~]# docker service ps service_1
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
6xtmldgw1k9fsqgwgarwu8d01 service_1.1 ubuntu:14.04 cent05 Running Running about a minute ago
ebj93548ugs7213i2pmhf2n9l \_ service_1.1 ubuntu:14.04 cent04 Shutdown Running 2 minutes ago
na którym to węźle oczywiście utworzyło się urządzenie /dev/scinia:
Stwórzmy zatem jakiś plik w kontenerze i wywołajmy kolejną awarię, a następnie sprawdźmy czy dane ocalały:
Co stało się powyżej? Sprawdziliśmy istnienie urządzenia /dev/scinia na węźle cent05, wywołaliśmy awarię (via service docker stop), sprawdziliśmy że urządzenie blokowe nagle znikło. Usługa (kontener) została przemigrowana na ostatni żyjący węzeł (cent03) i na nim pojawiło się urządzenie blokowe /dev/scinia . Po zalogowaniu do kontenera okazało się że całą awarię przeżyły nasze dane (czyli PLIK_000). Czyli HA pełną gębą! No prawie…
Na chwilę obecną infrastruktura niestety nie przechodzi testu na awarię hosta.
Zróbmy teraz test całej farmy swarmowej. Na wejściu będą stały ingresowe swarmload-balancery które będą rozmawiały z produkcyjnym kontenerem – niezależnie na którym węźle ten kontener będzie pracował. Podczas symulacji awarii kontener będzie migrował między węzłami ale dane “biznesowe” będzie serwował wciąż te same – end-user nie odczuje różnicy. Dane statyczne (czyli te “biznesowo-ważne”) się nie zmienią (storage pod spodem je przemigruje – jedynie co się zmieni to identyfikator web-serwera (w naszym labie będzie to hostname kontenera)
Najpierw jednak przygotujmy sobie wolumen rexrayowy (nazwijmy go vol_dane) z “danymi biznesowymi” w środku. Potem zrobimy z niego katalog mapowany do każdego kontenera.
Na początku odpalamy w tym celu obraz z ubuntu i w środku tworzymy nasze dane
[root@cent03 tmp]# docker run -ti -v vol_dane:/data –volume-driver=rexray ubuntu:14.04
root@07619eca55e0:/# cd /data/
root@07619eca55e0:/data# echo “WAZNE i KRYTYCZNE DANE” > plik
root@07619eca55e0:/data# exit
Weryfikujemy czy kolejny kontener z ubuntu widzi dane
[root@cent03 ~]# docker run -ti -v vol_dane:/data –volume-driver=rexray ubuntu:14.04
root@a2e0a2ea2332:/# cat /data/plik
WAZNE i KRYTYCZNE DANE
root@a2e0a2ea2332:/# exit
Oczywiście wolumen pojawił się na każdym węźle (widoczny z poziomu rexray) :
[root@cent03 ~]# rexray volume ls
– availabilityZone: default
name: vol_dane
size: 16
id: 11497a7100000000
type: default
—
[root@cent05 ~]# rexray volume ls
– availabilityZone: default
name: vol_dane
size: 16
id: 11497a7100000000
type: default
—
[root@cent04 ~]# rexray volume ls
– availabilityZone: default
name: vol_dane
size: 16
id: 11497a7100000000
type: default
Sprawdźmy na wszelki wypadek czy dane są widoczne na innym węźle
[root@cent05 ~]# docker run -ti -v vol_dane:/data –volume-driver=rexray ubuntu:14.04
root@a83136dbbb5b:/# cat /data/plik
WAZNE i KRYTYCZNE DANE
root@a83136dbbb5b:/# exit
Jak widać wszytko gra. Wróćmy zatem do naszego web-serwera który ma realizować całą usługę
Musi to być image serwujący po www jakieś “ważne biznesowe dane” które będą migrowane swarmem między węzłami. Oprócz widocznych via www danych biznesowych będzie również widać hostname kontenera który je serwuje. Trzeba zatem stworzyć kontenery które mają zamapowany wolumen z scaleio oraz oprócz jego zawartości pokazują również swój hostname
Oto Dockerfile:
FROM ubuntu:14.04
RUN apt-get -y update && apt-get install -y apache2
CMD apachectl start && hostname > /var/www/html/index.html && cat /data/plik >> /var/www/html/index.html ; tail -f /dev/null
Budujemy obraz (i np. kopiujemy go na każdy węzeł swarma lub jeśli ktoś ma czas stawiamy private-repo):
[root@cent03 tmp]# docker build -t test_apache .
uruchamiamy kontener z apache mapując wolumen tak aby jego zawartość trafiła do katalogu gdzie apache ma index.html
[root@cent03 tmp]# docker run -tdi -v vol_dane:/data –volume-driver=rexray test_apache
Sprawdzamy czy faktycznie kontener wrzucił do index.html swój hostname i nasze “biznesowe dane”
[root@cent03 tmp]# docker exec -ti 8e4dfdcc74ef bash
root@8e4dfdcc74ef:/# hostname
8e4dfdcc74ef
root@8e4dfdcc74ef:/# cat /var/www/html/index.html
8e4dfdcc74ef
WAZNE i KRYTYCZNE DANE
Jest ok 🙂
Co tu zaszło ? Odpalony kontener z apache zamapował sobie nasz wolumen jako /data i zaraz po wrzuceniu do index.html swojego hostname skopiował także (tak jak jest zlecone w Dockerfile) zwartość pliku “plik” do tegoż index.html
Udało się stworzyć mechanizm który uruchamia kolejne kontenery z zachowaniem danych w środku. Oczywiście to zwykłe dockery, migrować po awarii się nie będą. A zatem trzeba przejść na konfigurację w swarmie. Celem jest stworzenie serwisu który zmapuje nasz scaleio-raxray’owy wolumen i zacznie serwować jego dane.
[root@cent03 tmp]# docker service create –replicas 1 –name www –publish 8088:80 –mount type=volume,source=vol_dane,target=/data,volume-driver=rexray test_apache
57j6dtlrp38avacl6kac4fhxp
[root@cent03 ~]# docker service ls
ID NAME REPLICAS IMAGE COMMAND
b4fag0y6brsj www 1/1 test_apache
[root@cent03 ~]# docker service ps www
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
b7tq1p3a0ch056v96wr3qvrqq www.1 test_apache cent05 Running Running 2 minutes ago
[root@cent03 ~]#
Na węźle cent05 faktycznie uruchomił się kontener:
[root@cent05 tmp]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
88839d1ef279 test_apache:latest “/bin/sh -c ‘apachect” 3 minutes ago Up 3 minutes www.1.b7tq1p3a0ch056v96wr3qvrqq
Jak wiadomo z teorii na każdym węźle swarm otworzył port 8088 i można przez ten port sięgać po dane:
[root@cent04 tmp]# curl 127.0.0.1:8088
88839d1ef279
WAZNE i KRYTYCZNE DANE
[root@cent04 tmp]#
[root@cent05 tmp]# curl 127.0.0.1:8088
88839d1ef279
WAZNE i KRYTYCZNE DANE
[root@cent05 tmp]#
Serwuje je jednakowoż jeden kontener – ten z węzła cent05 (jego hostname to 88839d1ef279). Czas wyłączyć węzeł cent05 (via “service docker stop”). Po chwili widzimy że swarm przerzucił usługę na węzeł cent04:
[root@cent03 ~]# docker service ps www
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
70fxd74x6ckryl3x71yr8x6og www.1 test_apache cent04 Running Starting 1 seconds ago
b7tq1p3a0ch056v96wr3qvrqq \_ www.1 test_apache cent05 Shutdown Running 5 minutes ago
Gdy sprawdzimy curlem (obojętnie z którego węzła byle nie z tego który zaliczył “awarię”) zawartość www otrzymujemy:
[root@cent04 tmp]# curl 127.0.0.1:8088
1c843995943c
WAZNE i KRYTYCZNE DANE
Jak widać hostname kontenera serwującego dane się zmienił ale nasze dane biznesowe zostały przerzucone na inną maszynę. Oczywiście rexray i scale-io przemapowały wolumen z danymi na węzeł który teraz świadczy usługę (ip końcówka 106):
Podsumowanie
Jak do tej pory docker dorobił się całkiem sprawnych i nowoczesnych mechanizmów dla load-balancingu, service-discovery czy networkingu. Jeśli chodzi o storage niestety bardzo dużo jeszcze brakuje. Jednak jeśli zastosujemy driver rex-ray który pod spodem wysteruje farmą SDS i SDC scale-io jesteśmy w stanie osiągnąć w miarę kuloodporny i pancerny landscape. Pozostaje moim zdaniem jednam zaczekać co powie docker w którejś z przyszłych wersji silnika, myślę że pojawienie się natywnego drivera do storage-HA to tylko kwestia czasu.
Mały dodatek – celem zbudowania pancernego HA (tak aby rexray przełączał się po padzie węzła) i aby nie mieć sytuacji opisywanej tu:
https://github.com/codedellemc/rexray/issues/560#issuecomment-260683490
Należy mieć konfig rexray następujący
rexray:
logLevel: error
libstorage:
integration:
volume:
operations:
mount:
preempt: true
[…]
@gi_mbu:disqus : Mógłbys wrzucić jakieś statystyki? Ile trwa stworzenie kontenera (wolumenu)? Jaki jest downtime? Masz takie metryki?
Pingback: Bare-metal klaster z Kubernetes w 10 minut…? | inleo – wirtualizacja, datacenter, cloud computing, storage, serwery, it
Bardzo ciekawy artykuł. Sławku powiedz, a jak według Ciebie sprawdza się rozwiązanie oparte o Flocker plugin? Mam też pytanie dodatkowe, czy interesowałeś może stateful containers w AWS w oparciu o EFS?Pytam z czystej ciekawości, bo może masz swoją opinię na ten temat.
flocker poszedł do piachu (niestety) 🙁
Kamil, na chwilę obecną nie posiadam ale jak będę robił testy pre live to Ci wyślę