Amilyen gyorsan létrehozható egy konténer, olyan gyorsan el is lehet dobni azt és ezzel törölni a benne tárolt adatokat. A megoldás egyszerű: Ne tároljunk benne adatokat! A megvalósítás viszont ennél már komplexebb. Erről szeretnék most megosztani veletek pár gondolatot.
Első nagyon fontos dolog, amit el kell döntenünk, hogy egy mindig ugyanazon a hoston futtatott konténerről, vagy egy serverless alkalmazásról van-e szó. Megjegyezném, hogy én serveless alkalmazás alatt nem csak az Amazon Lambda vagy Azure/Google Cloud Function megoldásokat értem, hanem minden olyan megvalósítást, aminél nem kell, hogy érdekeljen, hogy milyen, melyik vagy hány szerveren fut az alkalmazás.
Fejlesztői környezet
Amennyiben mindig ugyanazon a hoston fut a konténer, mint például egy fejlesztői környezetnél, akkor viszonylag egyszerű dolgunk van. Első körben hozzunk létre egy volume-ot.
docker volume create myvolume
Majd indítsuk el a server alkalmazásunkat, ami ezt a volume-t fogja használni. Példánkban egy MySQL-t:
docker run -d --name mysql -e MYSQL_ROOT_PASSWORD=titok -p 3306:3306 -v myvolume:/var/lib/mysql mysql:8
Korábbi bejegyzésben tárgyalt parancshoz képest egy újdonság van a -v myvolume:/var/lib/mysql
. Ez nem csinál mást mint az előbb elkészített volume-t csatlakoztatja (mount) a /var/lib/mysql
könyvtár helyére a konténeren belül. Ettől fogva törölhetjük, eldobhatjuk a mysql konténert, az adatok megmaradnak, no persze csak akkor, ha az újonnan indított konténerhez is csatoljuk ezt a megfelelő helyre. (No meg, ha graceful shutdown volt, és nem egy inkonzisztens fájl halmazt hagyott maga után az előző futás)
Ebben az esetben ez a legáltalánosabban használható megoldás.
Fontos megjegyezni, hogy ha egyszerre két mysql (vagy bármilyen) szervert indítunk el és mindegyikhez ugyan ezt a volume-t kapcsoljuk, akkor nem fog működni a dolog. Ekkor olyan, mintha egy gépen két szervert indítunk el, amik ugyanazt a könyvtárat használják.
A legtöbb leírásban, többek között a hivatalos mysql konténer leírásában is egy egyszerűbb megoldást javasolnak. Nem kell volume-t készítenünk, hisz a host gép egy könyvtárát is bind mountolhatjuk a konténerbe a -v /my/own/datadir:/var/lib/mysql
kapcsolóval. Ez ugyan egyszerűbb mint az előbbi, de nem Linux rendszeren én nem javaslom a használatát. A Docker host - Windows/OSX host adatátvitel miatt jelentős teljesítménybeli veszteségeink lesznek.
Serverless alkalmazás
Egy konténerben futó serverless alkalmazás abban különbözik az előbbitől, hogy nem csak a konténeren belül található változások, adatok veszhetnek el, hanem a hoston tároltak is. Képzeljünk el egy három hostból álló cluster-t, ahol az első hoston fut az alkalmazásunk. Az előbb tárgyalt módon a host egy könyvtárában tároljuk az adatokat. Ne legyen félreértés, a fent tárgyalt mindkét módszer az adott host egy könyvtárát használja. Térjünk vissza a példához, az első hoston futó alkalmazáshoz, mely az első host fájlrendszerét használja. Ha valamiért megáll az alkalmazásunk és újraindítva egy másik hoston lesz, akkor nem fog hozzáférni azokhoz az adatokhoz, amiket korábban létrehozott.
Itt van az a pont, hogy eláruljam, hogy nem létezik egyszerű és minden igényt kielégítő, minden szempontból kitűnő megoldás a problémára. Egy adatbázis szervernél, mint amilyen a MySQL két síkon érdemes gondolkodni.
Egyik az adatok rendszeres mentése egy biztonságos helyre, majd automatikus visszatöltése teljes összeomlás esetén, ezt nevezem én minimum szintnek. Ez egy háromkilences (99,9%) rendelkezésre állásnál, 50-100 MB adatnál elég lehet. Hogy konkrétan hogyan, erről majd egy másik bejegyzésben írok.
A második szint amikor magasabb rendelkezésre állást kell biztosítanunk, ilyenkor érdemes az adatbázis szerverek által kínált megoldásokat használni. MySQL-nél ez a Replication és a Galera Cluster.
Természetesen lehetőségünk van arra, hogy egy docker volume plugin segítségével a volume-t egy hálózati meghajtón helyezzük el, vagy a host fájlrendszerében oldjuk meg a hálózatosítást, de adatbázis szervereknél biztos nem fogja hozni azt a teljesítményt amit elvárunk. Azt se kell eltitkolnom, hogy ez egy viszonylag egyszerű és gyors megoldás, bár mint minden általános megoldás épp a konkrét esetekben nem lesz majd jó. Azért egy próbát megér, lehet nálad működni fog.
Mindent összefoglalva, fejlesztői környezetben a docker volume használatával tudsz megőrizni adatokat. Arról, hogy mikor érdemes mount és mikor bind mount csatolást használni többek között a Konténerizált Fejlesztői Környezet Kialakítása workshopon fogok részletesebben beszélni.