Jak jsme viděli v první části tohoto blogu, silně konzistentní databázový cluster, jako je Galera, si nehraje dobře s nástroji pro orchestraci kontejnerů, jako je Kubernetes nebo Swarm. Ukázali jsme vám, jak nasadit Galeru a nakonfigurovat správu procesů pro Docker, abyste si zachovali plnou kontrolu nad chováním. Tento blogový příspěvek je jeho pokračováním, podíváme se na provoz a údržbu clusteru.
Abychom shrnuli některé z hlavních bodů z části 1 tohoto blogu, nasadili jsme tříuzlový cluster Galera s ProxySQL a Keepalived na třech různých hostitelích Docker, kde všechny instance MariaDB běží jako kontejnery Docker. Následující diagram znázorňuje konečné nasazení:
Slušné vypnutí
Chcete-li provést elegantní vypnutí MySQL, nejlepším způsobem je odeslat SIGTERM (signál 15) do kontejneru:
$ docker kill -s 15 {db_container_name}
Pokud byste chtěli cluster vypnout, opakujte výše uvedený příkaz na všech databázových kontejnerech, jeden uzel po druhém. Výše uvedené je podobné provedení „systemctl stop mysql“ ve službě systemd pro MariaDB. Použití příkazu "docker stop" je pro databázovou službu docela riskantní, protože čeká na 10 sekund timeout a Docker vynutí SIGKILL, pokud je tato doba překročena (pokud nepoužijete správný --timeout hodnota).
Poslední uzel, který se elegantně vypne, bude mít seqno nerovná se -1 a safe_to_bootstrap příznak je nastaven na 1 v /{datadir volume}/grastate.dat hostitele Docker, například na hostiteli2:
$ cat /containers/mariadb2/datadir/grastate.dat
# GALERA saved state
version: 2.1
uuid: e70b7437-645f-11e8-9f44-5b204e58220b
seqno: 7099
safe_to_bootstrap: 1
Detekce nejpokročilejšího uzlu
Pokud by se cluster neukončil řádně nebo uzel, který jste se pokoušeli zavést, nebyl posledním uzlem, který opustil cluster, pravděpodobně nebudete moci zavést jeden z uzlu Galera a můžete narazit na následující chybu :
2016-11-07 01:49:19 5572 [ERROR] WSREP: It may not be safe to bootstrap the cluster from this node.
It was not the last one to leave the cluster and may not contain all the updates.
To force cluster bootstrap with this node, edit the grastate.dat file manually and set safe_to_bootstrap to 1 .
Galera respektuje uzel, který má safe_to_bootstrap příznak nastavený na 1 jako první referenční uzel. Toto je nejbezpečnější způsob, jak zabránit ztrátě dat a zajistit, aby byl vždy zaváděn správný uzel.
Pokud se zobrazí chyba, musíme nejprve zjistit nejpokročilejší uzel, než jej vybereme jako první, který má být bootstrapován. Vytvořte přechodný kontejner (pomocí --rm flag), namapujte jej do stejného datadir a konfiguračního adresáře skutečného databázového kontejneru se dvěma příznaky příkazu MySQL, --wsrep_recover a --wsrep_cluster_address . Například, pokud chceme znát poslední potvrzené číslo mariadb1, musíme spustit:
$ docker run --rm --name mariadb-recover \
--env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
--volume /containers/mariadb1/datadir:/var/lib/mysql \
--volume /containers/mariadb1/conf.d:/etc/mysql/conf.d \
mariadb:10.2.15 \
--wsrep_recover \
--wsrep_cluster_address=gcomm://
2018-06-12 4:46:35 139993094592384 [Note] mysqld (mysqld 10.2.15-MariaDB-10.2.15+maria~jessie) starting as process 1 ...
2018-06-12 4:46:35 139993094592384 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
...
2018-06-12 4:46:35 139993094592384 [Note] Plugin 'FEEDBACK' is disabled.
2018-06-12 4:46:35 139993094592384 [Note] Server socket created on IP: '::'.
2018-06-12 4:46:35 139993094592384 [Note] WSREP: Recovered position: e70b7437-645f-11e8-9f44-5b204e58220b:7099
Poslední řádek je to, co hledáme. MariaDB vytiskne UUID clusteru a pořadové číslo poslední potvrzené transakce. Uzel, který má nejvyšší číslo, je považován za nejpokročilejší uzel. Protože jsme zadali --rm , kontejner bude po opuštění automaticky odstraněn. Opakujte výše uvedený krok na každém hostiteli Docker nahrazením --volume cestu k příslušným svazkům databázového kontejneru.
Jakmile porovnáte hodnotu hlášenou všemi databázovými kontejnery a rozhodnete se, který kontejner je nejaktuálnější uzel, změňte safe_to_bootstrap příznak na 1 uvnitř /{svazek datadir}/grastate.dat ručně. Řekněme, že všechny uzly hlásí stejné přesné pořadové číslo, stačí vybrat mariadb3, který bude bootstrapován změnou parametru safe_to_bootstrap hodnotu na 1:
$ vim /containers/mariadb3/datadir/grasate.dat
...
safe_to_bootstrap: 1
Uložte soubor a začněte bootstrapovat cluster z tohoto uzlu, jak je popsáno v další kapitole.
Bootstrapování clusteru
Bootstrapping clusteru je podobný prvnímu příkazu spuštění dockeru, který jsme použili při prvním spuštění clusteru. Pokud je mariadb1 vybraným bootstrapovým uzlem, můžeme jednoduše znovu spustit vytvořený bootstrap kontejner:
$ docker start mariadb0 # on host1
V opačném případě, pokud bootstrap kontejner na zvoleném uzlu neexistuje, řekněme na host2, spusťte příkaz bootstrap container a namapujte existující svazky mariadb2. Jako název kontejneru na hostiteli2 používáme mariadb0, abychom označili, že se jedná o zaváděcí kontejner:
$ docker run -d \
--name mariadb0 \
--hostname mariadb0.weave.local \
--net weave \
--publish "3306" \
--publish "4444" \
--publish "4567" \
--publish "4568" \
$(weave dns-args) \
--env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
--volume /containers/mariadb2/datadir:/var/lib/mysql \
--volume /containers/mariadb2/conf.d:/etc/mysql/mariadb.conf.d \
mariadb:10.2.15 \
--wsrep_cluster_address=gcomm:// \
--wsrep_sst_auth="root:PM7%[email protected]^1" \
--wsrep_node_address=mariadb0.weave.local
Můžete si všimnout, že tento příkaz je o něco kratší ve srovnání s předchozím příkazem bootstrap popsaným v této příručce. Protože již máme uživatele proxysql vytvořeného v našem prvním bootstrap příkazu, můžeme tyto dvě proměnné prostředí přeskočit:
- --env MYSQL_USER=proxysql
- --env MYSQL_PASSWORD=proxysqlpassword
Poté spusťte zbývající kontejnery MariaDB, odeberte kontejner bootstrap a spusťte existující kontejner MariaDB na hostiteli s bootstrapem. V zásadě by pořadí příkazů bylo:
$ docker start mariadb1 # on host1
$ docker start mariadb3 # on host3
$ docker stop mariadb0 # on host2
$ docker start mariadb2 # on host2
V tomto okamžiku je cluster spuštěn a běží na plnou kapacitu.
Kontrola zdrojů
Paměť je v MySQL velmi důležitým zdrojem. Zde jsou uloženy vyrovnávací paměti a mezipaměti a pro MySQL je zásadní snížit dopad příliš častého narážení na disk. Na druhou stranu swapování je špatné pro výkon MySQL. Ve výchozím nastavení nebudou na běžící kontejnery existovat žádná omezení zdrojů. Kontejnery využívají z daného zdroje tolik, kolik dovolí jádro hostitele. Další důležitou věcí je limit deskriptoru souboru. Můžete zvýšit limit otevřeného deskriptoru souboru nebo "nofile" na něco vyššího, abyste pokryli počet souborů, které může server MySQL otevřít současně. Nastavení na vysokou hodnotu neuškodí.
Chcete-li omezit alokaci paměti a zvýšit limit deskriptoru souboru do našeho databázového kontejneru, přidejte --memory , --memory-swap a --ulimit parametry do příkazu "docker run":
$ docker kill -s 15 mariadb1
$ docker rm -f mariadb1
$ docker run -d \
--name mariadb1 \
--hostname mariadb1.weave.local \
--net weave \
--publish "3306:3306" \
--publish "4444" \
--publish "4567" \
--publish "4568" \
$(weave dns-args) \
--memory 16g \
--memory-swap 16g \
--ulimit nofile:16000:16000 \
--env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
--volume /containers/mariadb1/datadir:/var/lib/mysql \
--volume /containers/mariadb1/conf.d:/etc/mysql/mariadb.conf.d \
mariadb:10.2.15 \
--wsrep_cluster_address=gcomm://mariadb0.weave.local,mariadb1.weave.local,mariadb2.weave.local,mariadb3.weave.local \
--wsrep_sst_auth="root:PM7%[email protected]^1" \
--wsrep_node_address=mariadb1.weave.local
Vezměte na vědomí, že pokud --memory-swap je nastavena na stejnou hodnotu jako --memory a --memory je nastaveno na kladné celé číslo, kontejner nebude mít přístup ke swapu. Pokud --memory-swap není nastaveno, výměna kontejneru bude výchozí --memory vynásobte 2. Pokud --memory a --memory-swap jsou nastaveny na stejnou hodnotu, zabrání to kontejnerům používat jakýkoli swap. Důvodem je --memory-swap je množství kombinované paměti a swapu, které lze použít, zatímco --memory je pouze množství fyzické paměti, které lze použít.
Některé prostředky kontejneru, jako je paměť a CPU, lze ovládat dynamicky pomocí příkazu „docker update“, jak je znázorněno v následujícím příkladu pro upgrade paměti kontejneru mariadb1 na 32G za běhu:
$ docker update \
--memory 32g \
--memory-swap 32g \
mariadb1
Nezapomeňte vyladit soubor my.cnf tak, aby vyhovoval novým specifikacím. Správa konfigurace je vysvětlena v další části.
Správa konfigurace
Většinu konfiguračních parametrů MySQL/MariaDB lze změnit za běhu, což znamená, že pro použití změn nemusíte restartovat. Podrobnosti najdete na stránce dokumentace MariaDB. Parametr uvedený u „Dynamic:Yes“ znamená, že proměnná se načte okamžitě po změně bez nutnosti restartovat server MariaDB. Jinak nastavte parametry uvnitř vlastního konfiguračního souboru v hostiteli Docker. Například na mariadb3 proveďte změny v následujícím souboru:
$ vim /containers/mariadb3/conf.d/my.cnf
A potom restartujte kontejner databáze, abyste použili změnu:
$ docker restart mariadb3
Ověřte, zda kontejner spouští proces, a to tak, že se podíváte na protokoly dockeru. Chcete-li provést změny v celém clusteru, proveďte tuto operaci vždy na jednom uzlu.
Záloha
Provedení logické zálohy je docela jednoduché, protože obraz MariaDB také přichází s binárním souborem mysqldump. Jednoduše použijete příkaz "docker exec" ke spuštění mysqldump a odeslání výstupu do souboru vzhledem k hostitelské cestě. Následující příkaz provede zálohu mysqldump na mariadb2 a uloží ji do /backups/mariadb2 uvnitř hostitele2:
$ docker exec -it mariadb2 mysqldump -uroot -p --single-transaction > /backups/mariadb2/dump.sql
Binární zálohování jako Percona Xtrabackup nebo MariaDB Backup vyžaduje proces pro přímý přístup k datovému adresáři MariaDB. Tento nástroj musíte buď nainstalovat do kontejneru, nebo prostřednictvím hostitele počítače, nebo pro tento účel použít vyhrazený obraz, jako je obraz „perconalab/percona-xtrabackup“ k vytvoření zálohy a uložit ji do /tmp/backup na hostiteli Docker:
$ docker run --rm -it \
-v /containers/mariadb2/datadir:/var/lib/mysql \
-v /tmp/backup:/xtrabackup_backupfiles \
perconalab/percona-xtrabackup \
--backup --host=mariadb2 --user=root --password=mypassword
Kontejner můžete také zastavit pomocí innodb_fast_shutdown nastavte na 0 a zkopírujte přes svazek datadir do jiného umístění ve fyzickém hostiteli:
$ docker exec -it mariadb2 mysql -uroot -p -e 'SET GLOBAL innodb_fast_shutdown = 0'
$ docker kill -s 15 mariadb2
$ cp -Rf /containers/mariadb2/datadir /backups/mariadb2/datadir_copied
$ docker start mariadb2
Obnovit
Obnovení je pro mysqldump docela jednoduché. Můžete jednoduše přesměrovat stdin do kontejneru z fyzického hostitele:
$ docker exec -it mariadb2 mysql -uroot -p < /backups/mariadb2/dump.sql
Můžete také použít standardní příkazový řádek klienta mysql vzdáleně se správným názvem hostitele a hodnotou portu namísto použití tohoto příkazu "docker exec":
$ mysql -uroot -p -h127.0.0.1 -P3306 < /backups/mariadb2/dump.sql
Pro Percona Xtrabackup a MariaDB Backup musíme zálohu připravit předem. Tím se záloha posune dopředu na čas, kdy byla záloha dokončena. Řekněme, že naše soubory Xtrabackup jsou umístěny pod /tmp/backup hostitele Docker, stačí je připravit:
$ docker run --rm -it \
-v mysql-datadir:/var/lib/mysql \
-v /tmp/backup:/xtrabackup_backupfiles \
perconalab/percona-xtrabackup \
--prepare --target-dir /xtrabackup_backupfiles
Připravenou zálohu pod /tmp/backup hostitele Dockeru pak lze použít jako datadir MariaDB pro nový kontejner nebo cluster. Řekněme, že chceme pouze ověřit obnovu na samostatném kontejneru MariaDB, spustili bychom:
$ docker run -d \
--name mariadb-restored \
--env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
-v /tmp/backup:/var/lib/mysql \
mariadb:10.2.15
Pokud jste provedli zálohu pomocí přístupu stop and copy, můžete jednoduše duplikovat datadir a použít duplicitní adresář jako mapu svazku do MariaDB datadir pro spuštění v jiném kontejneru. Řekněme, že záloha byla zkopírována do /backups/mariadb2/datadir_copied, můžeme spustit nový kontejner spuštěním:
$ mkdir -p /containers/mariadb-restored/datadir
$ cp -Rf /backups/mariadb2/datadir_copied /containers/mariadb-restored/datadir
$ docker run -d \
--name mariadb-restored \
--env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
-v /containers/mariadb-restored/datadir:/var/lib/mysql \
mariadb:10.2.15
MYSQL_ROOT_PASSWORD musí odpovídat skutečnému heslu root pro danou zálohu.
Několik nines MySQL na Dockeru:Jak kontejnerizovat databáziZjistěte vše, co potřebujete pochopit, když zvažujete spuštění služby MySQL nad virtualizací kontejnerů DockerStáhněte si dokumentUpgrade verze databáze
Existují dva typy upgradu – upgrade na místě nebo logický upgrade.
Upgrade na místě zahrnuje vypnutí serveru MariaDB, nahrazení starých binárních souborů novými binárními soubory a následné spuštění serveru ve starém datovém adresáři. Po spuštění musíte spustit mysql_upgrade skript ke kontrole a aktualizaci všech systémových tabulek a také ke kontrole uživatelských tabulek.
Logický upgrade zahrnuje export SQL z aktuální verze pomocí logického zálohovacího nástroje, jako je mysqldump, spuštění nového kontejneru s binárními soubory upgradované verze a následné použití SQL na novou verzi MySQL/MariaDB. Je podobný přístupu k zálohování a obnově popsanému v předchozí části.
Přesto je dobrý přístup vždy zálohovat databázi před provedením jakýchkoli destruktivních operací. Při upgradu z aktuální bitové kopie MariaDB 10.1.33 na jinou hlavní verzi, MariaDB 10.2.15 na mariadb3 umístěnou na hostiteli3, jsou vyžadovány následující kroky:
-
Zálohujte databázi. Nezáleží na fyzickém nebo logickém zálohování, ale doporučujeme použít mysqldump.
-
Stáhněte si nejnovější obrázek, na který bychom chtěli upgradovat:
$ docker pull mariadb:10.2.15
-
Nastavte innodb_fast_shutdown na 0 pro náš databázový kontejner:
$ docker exec -it mariadb3 mysql -uroot -p -e 'SET GLOBAL innodb_fast_shutdown = 0'
-
Poctivě vypněte kontejner databáze:
$ docker kill --signal=TERM mariadb3
-
Vytvořte nový kontejner s novým obrázkem pro náš databázový kontejner. Zbývající parametry ponechte nedotčené kromě použití nového názvu kontejneru (jinak by došlo ke konfliktu):
$ docker run -d \ --name mariadb3-new \ --hostname mariadb3.weave.local \ --net weave \ --publish "3306:3306" \ --publish "4444" \ --publish "4567" \ --publish "4568" \ $(weave dns-args) \ --env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \ --volume /containers/mariadb3/datadir:/var/lib/mysql \ --volume /containers/mariadb3/conf.d:/etc/mysql/mariadb.conf.d \ mariadb:10.2.15 \ --wsrep_cluster_address=gcomm://mariadb0.weave.local,mariadb1.weave.local,mariadb2.weave.local,mariadb3.weave.local \ --wsrep_sst_auth="root:PM7%[email protected]^1" \ --wsrep_node_address=mariadb3.weave.local
-
Spusťte skript mysql_upgrade:
$ docker exec -it mariadb3-new mysql_upgrade -uroot -p
-
Pokud nedošlo k žádné chybě, odstraňte starý kontejner mariadb3 (nový je mariadb3-new):
$ docker rm -f mariadb3
-
V opačném případě, pokud proces upgradu mezitím selže, můžeme se vrátit k předchozímu kontejneru:
$ docker stop mariadb3-new $ docker start mariadb3
Upgrade hlavní verze lze provést podobně jako upgrade vedlejší verze, ale musíte mít na paměti, že MySQL/MariaDB podporuje pouze větší upgrade z předchozí verze. Pokud používáte MariaDB 10.0 a chcete upgradovat na 10.2, musíte nejprve upgradovat na MariaDB 10.1 a poté následovat další krok upgradu na MariaDB 10.2.
Všimněte si změn konfigurace, které jsou zaváděny a zastaralé mezi hlavními verzemi.
Přepnutí při selhání
V Galeře jsou všechny uzly hlavními a mají stejnou roli. S ProxySQL na obrázku budou připojení, která procházejí touto bránou, automaticky přerušena, pokud bude pro Galera Cluster spuštěna primární komponenta (to znamená, že většina uzlů bude aktivní). Aplikace nezaznamená žádný rozdíl, pokud dojde k výpadku jednoho databázového uzlu, protože ProxySQL jednoduše přesměruje připojení na ostatní dostupné uzly.
Pokud se aplikace připojuje přímo k MariaDB a obchází ProxySQL, je třeba provést převzetí služeb při selhání na straně aplikace ukázáním na další dostupný uzel za předpokladu, že uzel databáze splňuje následující podmínky:
- Stav wsrep_local_state_comment je synchronizován (stav „Desynchroned/Donor“ je také možný, pouze pokud wsrep_sst_method je xtrabackup, xtrabackup-v2 nebo mariabackup).
- Stav wsrep_cluster_status je primární.
V Galeře dostupný uzel neznamená, že je v pořádku, dokud není ověřen výše uvedený stav.
Změna velikosti
Chcete-li škálovat, můžeme vytvořit nový kontejner ve stejné síti a použít stejný vlastní konfigurační soubor pro existující kontejner na tomto konkrétním hostiteli. Řekněme například, že chceme přidat čtvrtý kontejner MariaDB na hostitele3, můžeme použít stejný konfigurační soubor připojený pro mariadb3, jak je znázorněno na následujícím diagramu:
Spusťte následující příkaz na hostiteli3 pro zmenšení:
$ docker run -d \
--name mariadb4 \
--hostname mariadb4.weave.local \
--net weave \
--publish "3306:3307" \
--publish "4444" \
--publish "4567" \
--publish "4568" \
$(weave dns-args) \
--env MYSQL_ROOT_PASSWORD="PM7%[email protected]^1" \
--volume /containers/mariadb4/datadir:/var/lib/mysql \
--volume /containers/mariadb3/conf.d:/etc/mysql/mariadb.conf.d \
mariadb:10.2.15 \
--wsrep_cluster_address=gcomm://mariadb1.weave.local,mariadb2.weave.local,mariadb3.weave.local,mariadb4.weave.local \
--wsrep_sst_auth="root:PM7%[email protected]^1" \
--wsrep_node_address=mariadb4.weave.local
Jakmile je kontejner vytvořen, připojí se ke clusteru a provede SST. Lze k němu přistupovat na portu 3307 externě nebo mimo síť Weave, nebo na portu 3306 v rámci hostitele nebo v rámci sítě Weave. Již není nutné zahrnout mariadb0.weave.local do adresy clusteru. Jakmile je cluster škálován, musíme přidat nový kontejner MariaDB do sady pro vyrovnávání zátěže ProxySQL prostřednictvím administrátorské konzole:
$ docker exec -it proxysql1 mysql -uadmin -padmin -P6032
mysql> INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (10,'mariadb4.weave.local',3306);
mysql> INSERT INTO mysql_servers(hostgroup_id,hostname,port) VALUES (20,'mariadb4.weave.local',3306);
mysql> LOAD MYSQL SERVERS TO RUNTIME;
mysql> SAVE MYSQL SERVERS TO DISK;
Opakujte výše uvedené příkazy na druhé instanci ProxySQL.
Nakonec pro poslední krok (tuto část můžete přeskočit, pokud jste již spustili příkaz „SAVE .. TO DISK“ v ProxySQL), přidejte následující řádek do proxysql.cnf, aby byl trvalý po restartování kontejneru na hostiteli1 a hostiteli2:
$ vim /containers/proxysql1/proxysql.cnf # host1
$ vim /containers/proxysql2/proxysql.cnf # host2
A přidejte řádky související s mariadb4 pod direktivou mysql_server:
mysql_servers =
(
{ address="mariadb1.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="mariadb2.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="mariadb3.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="mariadb4.weave.local" , port=3306 , hostgroup=10, max_connections=100 },
{ address="mariadb1.weave.local" , port=3306 , hostgroup=20, max_connections=100 },
{ address="mariadb2.weave.local" , port=3306 , hostgroup=20, max_connections=100 },
{ address="mariadb3.weave.local" , port=3306 , hostgroup=20, max_connections=100 },
{ address="mariadb4.weave.local" , port=3306 , hostgroup=20, max_connections=100 }
)
Uložte soubor a při příštím restartu kontejneru bychom měli být v pořádku.
Zmenšení
Pro zmenšení stačí nádobu elegantně vypnout. Nejlepší příkaz by byl:
$ docker kill -s 15 mariadb4
$ docker rm -f mariadb4
Pamatujte, že pokud databázový uzel opustil klastr bez chybičky, nebylo to součástí zmenšení a ovlivnilo by to výpočet kvora.
Chcete-li odebrat kontejner z ProxySQL, spusťte následující příkazy na obou kontejnerech ProxySQL. Například na proxysql1:
$ docker exec -it proxysql1 mysql -uadmin -padmin -P6032
mysql> DELETE FROM mysql_servers WHERE hostname="mariadb4.weave.local";
mysql> LOAD MYSQL SERVERS TO RUNTIME;
mysql> SAVE MYSQL SERVERS TO DISK;
Poté můžete buď odstranit odpovídající položku v proxysql.cnf, nebo ji nechat tak. Stejně bude detekován jako OFFLINE z pohledu ProxySQL.
Shrnutí
S Dockerem se věci trochu liší od konvenčního způsobu práce se servery MySQL nebo MariaDB. Práce se stavovými službami, jako je Galera Cluster, není tak snadná jako bezstavové aplikace a vyžaduje řádné testování a plánování.
V našem příštím blogu na toto téma zhodnotíme klady a zápory spuštění Galera Cluster na Dockeru bez jakýchkoli nástrojů pro orchestraci.