Puppet je open source nástroj pro správu systémů pro centralizaci a automatizaci správy konfigurace. Automatizační nástroje pomáhají minimalizovat manuální a opakující se úkoly a mohou ušetřit spoustu času.
Puppet standardně funguje v modelu server/agent. Agenti získají svůj „katalog“ (konečný požadovaný stav) od hlavního serveru a aplikují jej lokálně. Poté podají zprávu serveru. Katalog se vypočítává v závislosti na „faktech“, které stroj posílá na server, uživatelském vstupu (parametrech) a modulech (zdrojovém kódu).
V tomto blogu vám ukážeme, jak nasadit a spravovat instance MySQL/MariaDB prostřednictvím Puppet. Kolem MySQL/MariaDB existuje řada technologií, jako je replikace (master-slave, Galera nebo skupinová replikace pro MySQL), nástroje pro vyrovnávání zátěže s vědomím SQL, jako je ProxySQL a MariaDB MaxScale, nástroje pro zálohování a obnovu a mnoho dalších, kterým se budeme věnovat v tomto blogová série. V Puppet Forge je také k dispozici mnoho modulů vytvořených a spravovaných komunitou, které nám mohou pomoci zjednodušit kód a vyhnout se znovuobjevování kola. V tomto blogu se zaměříme na replikaci MySQL.
puppetlabs/mysql
Toto je momentálně nejpopulárnější modul Puppet pro MySQL a MariaDB (a pravděpodobně nejlepší na trhu). Tento modul spravuje jak instalaci a konfiguraci MySQL, tak i rozšíření Puppet o možnost správy zdrojů MySQL, jako jsou databáze, uživatelé a granty.
Modul je oficiálně spravován týmem Puppet (prostřednictvím repozitáře puppetlabs Github) a podporuje všechny hlavní verze Puppet Enterprise 2019.1.x, 2019.0.x, 2018.1.x, Puppet>=5.5.10 <7.0.0 na RedHat, Ubuntu, Platformy Debian, SLES, Scientific, CentOS, OracleLinux. Uživatel má možnost nainstalovat MySQL, MariaDB a Percona Server přizpůsobením úložiště balíčků
Následující příklad ukazuje, jak nasadit server MySQL. Na loutkové předloze nainstalujte modul MySQL a vytvořte soubor manifestu:
(puppet-master)$ puppet module install puppetlabs/mysql
(puppet-master)$ vim /etc/puppetlabs/code/environments/production/manifests/mysql.pp
Přidejte následující řádky:
node "db1.local" {
class { '::mysql::server':
root_password => 't5[sb^D[+rt8bBYu',
remove_default_accounts => true,
override_options => {
'mysqld' => {
'log_error' => '/var/log/mysql.log',
'innodb_buffer_pool_size' => '512M'
}
'mysqld_safe' => {
'log_error' => '/var/log/mysql.log'
}
}
}
}
Poté v uzlu loutkového agenta spusťte následující příkaz pro použití konfiguračního katalogu:
(db1.local)$ puppet agent -t
Při prvním spuštění se může zobrazit následující chyba:
Info: Certificate for db1.local has not been signed yet
K podpisu certifikátu stačí spustit následující příkaz na Puppet master:
(puppet-master)$ puppetserver ca sign --certname=db1.local
Successfully signed certificate request for db1.local
Zkuste to znovu pomocí příkazu "puppet agent -t" pro opětovné zahájení připojení s podepsaným certifikátem.
Výše uvedená definice nainstaluje standardní balíčky související s MySQL dostupné v úložišti distribuce OS. Například na Ubuntu 18.04 (Bionic) byste si nainstalovali balíčky MySQL 5.7.26:
(db1.local) $ dpkg --list | grep -i mysql
ii mysql-client-5.7 5.7.26-0ubuntu0.18.04.1 amd64 MySQL database client binaries
ii mysql-client-core-5.7 5.7.26-0ubuntu0.18.04.1 amd64 MySQL database core client binaries
ii mysql-common 5.8+1.0.4 all MySQL database common files, e.g. /etc/mysql/my.cnf
ii mysql-server 5.7.26-0ubuntu0.18.04.1 all MySQL database server (metapackage depending on the latest version)
ii mysql-server-5.7 5.7.26-0ubuntu0.18.04.1 amd64 MySQL database server binaries and system database setup
ii mysql-server-core-5.7 5.7.26-0ubuntu0.18.04.1 amd64 MySQL database server binaries
Můžete se rozhodnout pro jiné dodavatele, jako je Oracle, Percona nebo MariaDB s extra konfigurací na úložišti (podrobnosti najdete v sekci README). Následující definice nainstaluje balíčky MariaDB z úložiště MariaDB apt (vyžaduje modul apt Puppet):
$ puppet module install puppetlabs/apt
$ vim /etc/puppetlabs/code/environments/production/manifests/mariadb.pp
# include puppetlabs/apt module
include apt
# apt definition for MariaDB 10.3
apt::source { 'mariadb':
location => 'http://sgp1.mirrors.digitalocean.com/mariadb/repo/10.3/ubuntu/',
release => $::lsbdistcodename,
repos => 'main',
key => {
id => 'A6E773A1812E4B8FD94024AAC0F47944DE8F6914',
server => 'hkp://keyserver.ubuntu.com:80',
},
include => {
src => false,
deb => true,
},
}
# MariaDB configuration
class {'::mysql::server':
package_name => 'mariadb-server',
service_name => 'mysql',
root_password => 't5[sb^D[+rt8bBYu',
override_options => {
mysqld => {
'log-error' => '/var/log/mysql/mariadb.log',
'pid-file' => '/var/run/mysqld/mysqld.pid',
},
mysqld_safe => {
'log-error' => '/var/log/mysql/mariadb.log',
},
}
}
# Deploy on db2.local
node "db2.local" {
Apt::Source['mariadb'] ->
Class['apt::update'] ->
Class['::mysql::server']
}
Všimněte si hodnoty key->id, kde existuje speciální způsob, jak získat 40znakové id, jak je uvedeno v tomto článku:
$ sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
$ apt-key adv --list-public-keys --with-fingerprint --with-colons
uid:-::::1459359915::6DC53DD92B7A8C298D5E54F950371E2B8950D2F2::MariaDB Signing Key <[email protected]>::::::::::0:
sub:-:4096:1:C0F47944DE8F6914:1459359915::::::e::::::23:
fpr:::::::::A6E773A1812E4B8FD94024AAC0F47944DE8F6914:
Kde je hodnota id v řádku začínajícím „fpr“, což je „A6E773A1812E4B8FD94024AAC0F47944DE8F6914“.
Po použití katalogu Puppet můžete přímo přistupovat ke konzoli MySQL jako root bez explicitního hesla, protože modul konfiguruje a spravuje ~/.my.cnf automaticky. Pokud bychom chtěli resetovat heslo uživatele root na něco jiného, jednoduše změňte hodnotu root_password v definici Puppet a aplikujte katalog na uzel agenta.
Nasazení replikace MySQL
Chcete-li nasadit nastavení replikace MySQL, musíte vytvořit alespoň dva typy konfigurace pro oddělení hlavní a podřízené konfigurace. Master bude mít zakázáno pouze pro čtení, aby bylo možné čtení/zápis, zatímco podřízené jednotky budou nakonfigurovány s povoleným pouze pro čtení. V tomto příkladu použijeme replikaci založenou na GTID pro zjednodušení konfigurace (protože konfigurace všech uzlů by byla velmi podobná). Budeme chtít inicializovat replikační linku na master hned poté, co bude slave spuštěn.
Předpokládejme, že máme 3 uzly replikace MySQL master-slave:
- db1.local – hlavní
- db2.local – slave #1
- db3.local – otrok č. 2
Abychom splnili výše uvedené požadavky, můžeme zapsat náš manifest do něčeho takového:
# Puppet manifest for MySQL GTID-based replication MySQL 5.7 on Ubuntu 18.04 (Puppet v6.4.2)
# /etc/puppetlabs/code/environments/production/manifests/replication.pp
# node's configuration
class mysql {
class {'::mysql::server':
root_password => '[email protected]#',
create_root_my_cnf => true,
remove_default_accounts => true,
manage_config_file => true,
override_options => {
'mysqld' => {
'datadir' => '/var/lib/mysql',
'bind_address' => '0.0.0.0',
'server-id' => $mysql_server_id,
'read_only' => $mysql_read_only,
'gtid-mode' => 'ON',
'enforce_gtid_consistency'=> 'ON',
'log-slave-updates' => 'ON',
'sync_binlog' => 1,
'log-bin' => '/var/log/mysql-bin',
'read_only' => 'OFF',
'binlog-format' => 'ROW',
'log-error' => '/var/log/mysql/error.log',
'report_host' => ${fqdn},
'innodb_buffer_pool_size' => '512M'
},
'mysqld_safe' => {
'log-error' => '/var/log/mysql/error.log'
}
}
}
# create slave user
mysql_user { "${slave_user}@192.168.0.%":
ensure => 'present',
password_hash => mysql_password("${slave_password}")
}
# grant privileges for slave user
mysql_grant { "${slave_user}@192.168.0.%/*.*":
ensure => 'present',
privileges => ['REPLICATION SLAVE'],
table => '*.*',
user => "${slave_user}@192.168.0.%"
}
# /etc/hosts definition
host {
'db1.local': ip => '192.168.0.161';
'db2.local': ip => '192.169.0.162';
'db3.local': ip => '192.168.0.163';
}
# executes change master only if $master_host is defined
if $master_host {
exec { 'change master':
path => '/usr/bin:/usr/sbin:/bin',
command => "mysql --defaults-extra-file=/root/.my.cnf -e \"CHANGE MASTER TO MASTER_HOST = '$master_host', MASTER_USER = '$slave_user', MASTER_PASSWORD = '$slave_password', MASTER_AUTO_POSITION = 1; START SLAVE;\"",
unless => "mysql --defaults-extra-file=/root/.my.cnf -e 'SHOW SLAVE STATUS\G' | grep 'Slave_SQL_Running: Yes'"
}
}
}
## node assignment
# global vars
$master_host = undef
$slave_user = 'slave'
$slave_password = 'Replicas123'
# master
node "db1.local" {
$mysql_server_id = '1'
$mysql_read_only = 'OFF'
include mysql
}
# slave1
node "db2.local" {
$mysql_server_id = '2'
$mysql_read_only = 'ON'
$master_host = 'db1.local'
include mysql
}
# slave2
node "db3.local" {
$mysql_server_id = '3'
$mysql_read_only = 'ON'
$master_host = 'db1.local'
include mysql
}
Vynutit agentovi použití katalogu:
(all-mysql-nodes)$ puppet agent -t
Na masteru (db1.local) můžeme ověřit všechny připojené slave:
mysql> SHOW SLAVE HOSTS;
+-----------+-----------+------+-----------+--------------------------------------+
| Server_id | Host | Port | Master_id | Slave_UUID |
+-----------+-----------+------+-----------+--------------------------------------+
| 3 | db3.local | 3306 | 1 | 2d0b14b6-8174-11e9-8bac-0273c38be33b |
| 2 | db2.local | 3306 | 1 | a9dfa4c7-8172-11e9-8000-0273c38be33b |
+-----------+-----------+------+-----------+--------------------------------------+
Věnujte zvýšenou pozornost sekci "exec { 'change master':", kde to znamená, že pokud je podmínka splněna, bude proveden příkaz MySQL k zahájení replikačního spojení. Všechny prostředky "exec" prováděné Puppetem musí být idempotentní, což znamená operaci, která bude mít stejný účinek, ať už ji spustíte jednou nebo 10 001krát. Existuje řada atributů stavu, které můžete použít jako „pokud není“, „pouzeif“ a „vytvořit“, abyste zajistili správný stav a zabránili tomu, aby Puppet zpackal vaše nastavení. Pokud chcete spustit replikační odkaz ručně, můžete tuto sekci smazat/komentovat.
Správa MySQL
Tento modul lze použít k provádění řady úloh správy MySQL:
- možnosti konfigurace (upravit, použít, vlastní konfigurace)
- zdroje databáze (databáze, uživatel, granty)
- záloha (vytvoření, plánování, zálohování uživatele, úložiště)
- jednoduché obnovení (pouze mysqldump)
- instalace/aktivace pluginů
Zdroj databáze
Jak můžete vidět ve výše uvedeném příkladu manifestu, definovali jsme dva zdroje MySQL – mysql_user a mysql_grant – pro vytvoření uživatele a udělení oprávnění pro daného uživatele. Můžeme také použít třídu mysql::db, abychom zajistili přítomnost databáze s přiřazeným uživatelem a oprávněními, například:
# make sure the database and user exist with proper grant
mysql::db { 'mynewdb':
user => 'mynewuser',
password => 'passw0rd',
host => '192.168.0.%',
grant => ['SELECT', 'UPDATE']
}
Vezměte na vědomí, že při replikaci MySQL musí být všechny zápisy prováděny pouze na hlavním serveru. Ujistěte se tedy, že výše uvedený prostředek je přiřazen k hlavnímu serveru. Jinak by mohlo dojít k chybné transakci.
Zálohování a obnovení
Obvykle je pro celý cluster vyžadován pouze jeden záložní hostitel (pokud nereplikujete podmnožinu dat). K přípravě záložních zdrojů můžeme použít třídu mysql::server::backup. Předpokládejme, že máme v manifestu následující prohlášení:
# Prepare the backup script, /usr/local/sbin/mysqlbackup.sh
class { 'mysql::server::backup':
backupuser => 'backup',
backuppassword => 'passw0rd',
backupdir => '/home/backup',
backupdirowner => 'mysql',
backupdirgroup => 'mysql',
backupdirmode => '755',
backuprotate => 15,
time => ['23','30'], #backup starts at 11:30PM everyday
include_routines => true,
include_triggers => true,
ignore_events => false,
maxallowedpacket => '64M',
optional_args => ['--set-gtid-purged=OFF'] #extra argument if GTID is enabled
}
Puppet nakonfiguruje všechny předpoklady před spuštěním zálohování – vytvoření zálohovacího uživatele, příprava cílové cesty, přiřazení vlastnictví a oprávnění, nastavení úlohy cron a nastavení možností příkazu pro zálohování, které se mají použít v poskytnutém zálohovacím skriptu umístěném na /usr/local. /sbin/mysqlbackup.sh. Je pak na uživateli, zda skript spustí nebo naplánuje. Chcete-li provést okamžitou zálohu, jednoduše vyvolejte:
$ mysqlbackup.sh
Pokud na základě výše uvedeného extrahujeme skutečný příkaz mysqldump, vypadá takto:
$ mysqldump --defaults-extra-file=/tmp/backup.NYg0TR --opt --flush-logs --single-transaction --events --set-gtid-purged=OFF --all-databases
Pro ty, kteří chtějí používat další zálohovací nástroje, jako je Percona Xtrabackup, MariaDB Backup (pouze MariaDB) nebo MySQL Enterprise Backup, modul poskytuje následující soukromé třídy:
- mysql::backup::xtrabackup (Percona Xtrabackup a MariaDB Backup)
- mysql::backup::mysqlbackup (MySQL Enterprise Backup)
Příklad deklarace s Percona Xtrabackup:
class { 'mysql::backup::xtrabackup':
xtrabackup_package_name => 'percona-xtrabackup',
backupuser => 'xtrabackup',
backuppassword => 'passw0rd',
backupdir => '/home/xtrabackup',
backupdirowner => 'mysql',
backupdirgroup => 'mysql',
backupdirmode => '755',
backupcompress => true,
backuprotate => 15,
include_routines => true,
time => ['23','30'], #backup starts at 11:30PM
include_triggers => true,
maxallowedpacket => '64M',
incremental_backups => true
}
Výše uvedené naplánuje dvě zálohy, jednu plnou zálohu každou neděli ve 23:30 a jednu přírůstkovou zálohu každý den kromě neděle ve stejnou dobu, jak ukazuje výstup úlohy cron po použití výše uvedeného manifestu:
(db1.local)$ crontab -l
# Puppet Name: xtrabackup-weekly
30 23 * * 0 /usr/local/sbin/xtrabackup.sh --target-dir=/home/backup/mysql/xtrabackup --backup
# Puppet Name: xtrabackup-daily
30 23 * * 1-6 /usr/local/sbin/xtrabackup.sh --incremental-basedir=/home/backup/mysql/xtrabackup --target-dir=/home/backup/mysql/xtrabackup/`date +%F_%H-%M-%S` --backup
Další podrobnosti a možnosti dostupné pro tuto třídu (a další třídy) najdete v odkazu na možnost zde.
Pokud jde o aspekt obnovy, modul podporuje pouze obnovu pomocí metody zálohování mysqldump, a to importem souboru SQL přímo do databáze pomocí třídy mysql::db, například:
mysql::db { 'mydb':
user => 'myuser',
password => 'mypass',
host => 'localhost',
grant => ['ALL PRIVILEGES'],
sql => '/home/backup/mysql/mydb/backup.gz',
import_cat_cmd => 'zcat',
import_timeout => 900
}
Soubor SQL bude načten pouze jednou a ne při každém spuštění, pokud není použito force_sql => true.
Možnosti konfigurace
V tomto příkladu jsme použili manage_config_file => true s override_options ke strukturování našich konfiguračních řádků, které později vytlačí Puppet. Jakákoli úprava souboru manifestu bude odrážet pouze obsah cílového konfiguračního souboru MySQL. Tento modul po vložení změn do konfiguračního souboru ani nenačte konfiguraci do runtime, ani nerestartuje službu MySQL. Je odpovědností správce systému restartovat službu, aby se změny aktivovaly.
Chcete-li přidat vlastní konfiguraci MySQL, můžeme umístit další soubory do "includedir", výchozí do /etc/mysql/conf.d. To nám umožňuje přepsat nastavení nebo přidat další, což je užitečné, pokud nepoužíváte override_options ve třídě mysql::server. Zde se důrazně doporučuje použití šablony Puppet. Umístěte vlastní konfigurační soubor do adresáře šablony modulu (výchozí je /etc/puppetlabs/code/environments/production/modules/mysql/templates) a poté do manifestu přidejte následující řádky:
# Loads /etc/puppetlabs/code/environments/production/modules/mysql/templates/my-custom-config.cnf.erb into /etc/mysql/conf.d/my-custom-config.cnf
file { '/etc/mysql/conf.d/my-custom-config.cnf':
ensure => file,
content => template('mysql/my-custom-config.cnf.erb')
}
Chcete-li implementovat parametry specifické pro verzi, použijte direktivu version, například [mysqld-5.5]. To umožňuje jednu konfiguraci pro různé verze MySQL.
Puppet vs ClusterControl
Věděli jste, že můžete také automatizovat nasazení replikace MySQL nebo MariaDB pomocí ClusterControl? Modul ClusterControl Puppet můžete použít k instalaci nebo jednoduše stažením z našich webových stránek.
Ve srovnání s ClusterControl můžete očekávat následující rozdíly:
- Trochu křivka učení, abyste porozuměli syntaxi, formátování a strukturám Puppet, než budete moci psát manifesty.
- Manifest je nutné pravidelně testovat. Je velmi běžné, že se u kódu zobrazí chyba kompilace, zejména pokud je katalog použit poprvé.
- Puppet předpokládá, že kódy jsou idempotentní. Stav testu/kontroly/ověření spadá do odpovědnosti autora, aby nedošlo k záměně s běžícím systémem.
- Puppet vyžaduje agenta na spravovaném uzlu.
- Zpětná nekompatibilita. Některé staré moduly by v nové verzi nefungovaly správně.
- Monitorování databáze/hostitele musí být nastaveno samostatně.
Průvodce nasazením ClusterControl vede proces nasazení:
Alternativně můžete k dosažení podobných výsledků použít rozhraní příkazového řádku ClusterControl nazvané „s9s“. Následující příkaz vytvoří tříuzlový replikační cluster MySQL (za předpokladu, že bylo předem nakonfigurováno bez hesla pro všechny uzly):
$ s9s cluster --create \
--cluster-type=mysqlreplication \
--nodes=192.168.0.41?master;192.168.0.42?slave;192.168.0.43?slave;192.168.0.44?master; \
--vendor=oracle \
--cluster-name='MySQL Replication 8.0' \
--provider-version=8.0 \
--db-admin='root' \
--db-admin-passwd='$ecR3t^word' \
--log
Související zdroje Puppet Modul pro ClusterControl – Přidání správy a monitorování do vašich stávajících databázových clusterů Jak automatizovat nasazení clusteru MySQL Galera pomocí s9s CLI a Chef Příručka DevOps k automatizaci databázové infrastruktury pro eCommerce – přehrávání a prezentace Jsou podporována následující nastavení replikace MySQL/MariaDB:
- Replikace master-slave (založená na souboru/poloze)
- Replikace master-slave s GTID (MySQL/Percona)
- Replikace master-slave s MariaDB GTID
- Replikace master-master (polosynchronní/asynchronní)
- Replikace řetězce master-slave (polosynchronní/asynchronní)
Po nasazení mohou být uzly/klastry monitorovány a plně spravovány pomocí ClusterControl, včetně automatické detekce selhání, master failover, slave promotion, automatické obnovy, správy zálohování, správy konfigurace atd. To vše je spojeno v jednom produktu. Komunitní edice (zdarma navždy!) nabízí nasazení a monitorování. V průměru bude váš databázový cluster v provozu do 30 minut. Potřebuje pouze SSH bez hesla do cílových uzlů.
V další části vás provedeme nasazením Galera Cluster pomocí stejného modulu Puppet. Zůstaňte naladěni!