Ansible automatizza e semplifica le operazioni ripetitive, complesse e noiose. È un motore di automazione IT che automatizza il provisioning del cloud, la gestione della configurazione, l'implementazione delle applicazioni, l'orchestrazione all'interno dei servizi e molte altre esigenze IT. Non richiede agenti, utilizza solo SSH per inviare le modifiche da un'unica fonte a più risorse remote senza alcuna configurazione dell'infrastruttura di sicurezza personalizzata aggiuntiva e utilizza un formato di linguaggio semplice (YAML) per descrivere i lavori di automazione.
L'installazione di un server MySQL autonomo è un'operazione semplice e immediata, ma può essere problematica se si dispone di più server di database, versioni, piattaforme e ambienti da supportare. Pertanto, disporre di uno strumento di gestione della configurazione è la strada da percorrere per migliorare l'efficienza, rimuovere la ripetitività e ridurre gli errori umani.
In questo post del blog, ti guideremo attraverso le basi dell'automazione di Ansible per MySQL, oltre alla gestione della configurazione con esempi e spiegazioni. Inizieremo con una semplice distribuzione indipendente di MySQL, come illustrato nel seguente diagramma di alto livello:
Installazione di Ansible
Per questa procedura dettagliata, dobbiamo avere almeno due host:un host è per Ansible (potresti usare una workstation invece di un server) e un altro è l'host di destinazione che vogliamo distribuire a Server MySQL.
Per installare Ansible su CentOS 7, esegui semplicemente i seguenti comandi:
(ansible-host)$ yum install -y epel-release
(ansible-host)$ yum install -y ansible
Per altre distribuzioni di sistemi operativi, consulta la guida all'installazione di Ansible.
Configurazione di SSH senza password
L'utilizzo della password durante SSH è supportato, ma le chiavi SSH senza password con ssh-agent sono uno dei modi migliori per utilizzare Ansible. Il passaggio iniziale consiste nel configurare SSH senza password poiché Ansible eseguirà la distribuzione esclusivamente tramite questo canale. Innanzitutto, genera una chiave SSH sull'host Ansible:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Dovresti ottenere almeno i seguenti file generati:
(ansible-host)$ ls -al ~/.ssh/
-rw-------. 1 root root 1679 Jan 14 03:40 id_rsa
-rw-r--r--. 1 root root 392 Jan 14 03:40 id_rsa.pub
Per consentire SSH senza password, dobbiamo copiare la chiave pubblica SSH (id_rsa.pub) sull'host remoto a cui vogliamo accedere. Possiamo usare uno strumento chiamato ssh-copy-id per svolgere questo compito per noi. Tuttavia, devi conoscere la password dell'utente dell'host di destinazione e l'autenticazione della password è consentita sull'host di destinazione:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-copy-id [email protected]
Il comando precedente richiederà la password di root 192.168.0.221, è sufficiente inserire la password e la chiave SSH per l'utente corrente dell'host Ansible verrà copiata nell'host di destinazione, 192.168.0.221 in ~/.ssh/authorized_keys, il che significa che autorizziamo quella particolare chiave ad accedere a questo server in remoto. Per eseguire un test, dovresti essere in grado di eseguire il seguente comando remoto senza alcuna password dall'host Ansible:
(ansible-host)$ ssh [email protected] "hostname -I"
192.168.0.221
Nel caso in cui non ti sia consentito utilizzare l'utente root per SSH (ad es. "PermitRootLogin no" nella configurazione SSH), puoi invece utilizzare un utente sudo. Nell'esempio seguente, impostiamo SSH senza password per un utente sudo chiamato "vagrant":
(ansible-host)$ whoami
vagrant
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
(ansible-host)$ ls -al ~/.ssh/
-rw-------. 1 vagrant vagrant 1679 Jan 14 03:45 id_rsa
-rw-r--r--. 1 vagrant vagrant 392 Jan 14 03:45 id_rsa.pub
(ansible-host)$ ssh-copy-id [email protected]
Se il server di destinazione non consente l'autenticazione della password tramite SSH, copia semplicemente il contenuto della chiave pubblica SSH in ~/.ssh/id_rsa.pub manualmente nei ~/.ssh/authorized_keys degli host di destinazione file. Ad esempio, sull'host Ansible, recupera il contenuto della chiave pubblica:
(ansible-host)$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Connettiti all'host di destinazione e incolla la chiave pubblica dell'host di Ansible in ~/.ssh/authorized_keys:
(target-host)$ whoami
root
(target-host)$ vi ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Ora puoi provare a eseguire un comando remoto dall'host Ansible per verificare e non ti dovrebbe essere richiesta alcuna password. A questo punto, il nostro SSH senza password è configurato.
Definizione dell'host di destinazione
Successivamente dobbiamo definire l'host di destinazione, l'host che vogliamo gestire utilizzando Ansible. Sulla base della nostra architettura, implementeremo un solo server MySQL che è 192.168.0.221. Aggiungi le seguenti righe in /etc/ansible/hosts:
[db-mysql]
192.168.0.221
Quanto sopra significa semplicemente che abbiamo definito un gruppo chiamato "db-mysql", che sarà l'identificatore quando ci riferiremo all'host di destinazione nel playbook di Ansible. Possiamo anche elencare tutti gli indirizzi IP o i nomi host degli host di destinazione in questo gruppo. A questo punto, abbiamo solo un server MySQL da distribuire, quindi c'è solo una voce. Puoi anche specificare una regola di corrispondenza qualsiasi per abbinare gli host in un gruppo, ad esempio:
[db-mysql]
192.168.0.[221:223]
La definizione di cui sopra significa che abbiamo 3 host in questo stesso gruppo con i seguenti indirizzi IP:
- 192.168.0.221
- 192.168.0.222
- 192.168.0.223
Esistono molti modi e regole per abbinare e raggruppare gli host di destinazione, come mostrato nella guida dell'inventario Ansible.
Scelta di un ruolo Ansible
Per dire ad Ansible cosa distribuire, dobbiamo definire i passaggi di distribuzione in un file formattato YML chiamato playbook. Come forse saprai, l'installazione di un server MySQL completo richiede più passaggi per soddisfare tutte le dipendenze MySQL, la configurazione post-installazione, la creazione di utenti e schemi e così via. Ansible ha fornito una serie di moduli MySQL che possono aiutarci, ma dobbiamo ancora scrivere un playbook per le fasi di distribuzione.
Per semplificare i passaggi di distribuzione, possiamo utilizzare i ruoli Ansible esistenti. Il ruolo Ansible è un componente indipendente che consente il riutilizzo dei passaggi di configurazione comuni. Un ruolo Ansible deve essere utilizzato all'interno del playbook. Ci sono diversi ruoli MySQL Ansible disponibili in Ansible Galaxy, un repository per i ruoli Ansible che possono essere inseriti direttamente nei tuoi playbook.
Se cerchi "mysql", otterrai molti ruoli Ansible per MySQL:
Useremo quello più popolare chiamato "mysql" di geerlingguy. Puoi scegliere di utilizzare altri ruoli, ma per lo più quello più scaricato tende ad essere per scopi generici che di solito funziona bene nella maggior parte dei casi.
Sull'host Ansible, esegui il comando seguente per scaricare il ruolo Ansible:
(ansible-host)$ ansible-galaxy install geerlingguy.mysql
Il ruolo verrà scaricato in ~/.ansible/roles/geerlingguy.mysql/ dell'utente corrente.
Scrivere il Playbook Ansible
Guardando il Readme del ruolo Ansible, possiamo seguire il playbook di esempio che viene fornito. Innanzitutto, crea un file di playbook chiamato deploy-mysql.yml e aggiungi le seguenti righe:
(ansible-host)$ vim ~/deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
Nelle righe precedenti, definiamo l'host di destinazione che è tutti gli host sotto le voci db-mysql in /etc/ansible/hosts. La riga successiva (diventa) dice ad Ansible di eseguire il playbook come utente root, che è necessario per il ruolo (è indicato lì nel file Leggimi). Successivamente, definiamo la posizione del file delle variabili (var_files) che si trova in vars/main.yml, rispetto al percorso del playbook.
Creiamo la directory e il file della variabile e specifichiamo la seguente riga:
(ansible-host)$ mkdir vars
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
Per ulteriori informazioni, consulta la sezione Variabili del ruolo nel file Leggimi di questo ruolo.
Avvia la distribuzione
Ora siamo pronti per iniziare la distribuzione di MySQL. Usa il comando ansible-playbook per eseguire le nostre definizioni di playbook:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Dovresti vedere apparire un mucchio di righe nell'output. Concentrati sull'ultima riga in cui riassume la distribuzione:
PLAY RECAP ***************************************************************************************************************************************
192.168.0.221 : ok=36 changed=8 unreachable=0 failed=0 skipped=16 rescued=0 ignored=0
Se tutto diventa verde e OK, puoi verificare sull'host del database che il nostro server MySQL sia già installato e funzionante:
(mysql-host)$ rpm -qa | grep -i maria
mariadb-server-5.5.64-1.el7.x86_64
mariadb-libs-5.5.64-1.el7.x86_64
mariadb-5.5.64-1.el7.x86_64
(mysql-host)$ mysqladmin -uroot -p ping
Enter password:
mysqld is alive
Come puoi vedere da quanto sopra, per CentOS 7, l'installazione predefinita di MySQL è MariaDB 5.5 come parte del repository di pacchetti standard. A questo punto, la nostra distribuzione è considerata completa, tuttavia, vorremmo personalizzare ulteriormente la nostra distribuzione come mostrato nelle sezioni successive.
Personalizzazione della distribuzione
La definizione più semplice nel playbook ci offre un'installazione molto semplice e utilizza tutte le opzioni di configurazione predefinite. Possiamo personalizzare ulteriormente l'installazione di MySQL estendendo/modificando/aggiungendo il playbook per fare quanto segue:
- modifica le opzioni di configurazione di MySQL
- aggiungi utente del database
- aggiungi lo schema del database
- configura i privilegi utente
- configura la replica MySQL
- installa MySQL da altri fornitori
- importa un file di configurazione MySQL personalizzato
Installazione di MySQL dal repository Oracle
Per impostazione predefinita, il ruolo installerà il pacchetto MySQL predefinito fornito con la distribuzione del sistema operativo. Per quanto riguarda CentOS 7, dovresti installare MariaDB 5.5 per impostazione predefinita. Supponiamo di voler installare MySQL da un altro fornitore, possiamo estendere il playbook con pre_tasks, un'attività che Ansible esegue prima di eseguire qualsiasi attività menzionata in qualsiasi file .yml, come mostrato nel seguente esempio:
(ansible-host)$ vim deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
pre_tasks:
- name: Install the MySQL repo.
yum:
name: http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
state: present
when: ansible_os_family == "RedHat"
- name: Override variables for MySQL (RedHat).
set_fact:
mysql_daemon: mysqld
mysql_packages: ['mysql-server']
mysql_log_error: /var/lib/mysql/error.log
mysql_syslog_tag: mysqld
mysql_pid_file: /var/run/mysqld/mysqld.pid
mysql_socket: /var/lib/mysql/mysql.sock
when: ansible_os_family == "RedHat"
Esegui il playbook:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Quello sopra installerà invece MySQL dal repository Oracle. La versione predefinita che otterresti è MySQL 5.6. L'esecuzione del playbook di cui sopra su un host di destinazione che ha già una versione precedente di MySQL/MariaDB in esecuzione potrebbe non riuscire a causa dell'incompatibilità.
Creazione di database e utenti MySQL
All'interno di vars/main.yml, possiamo definire il database MySQL e gli utenti che vogliamo che Ansible configuri sul nostro server MySQL utilizzando i moduli mysql_database e mysql_users, subito dopo la nostra precedente definizione su mysql_root_password:
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
mysql_databases:
- name: myshop
encoding: latin1
collation: latin1_general_ci
- name: sysbench
encoding: latin1
collation: latin1_general_ci
mysql_users:
- name: myshop_user
host: "%"
password: mySh0pPassw0rd
priv: "myshop.*:ALL"
- name: sysbench_user
host: "192.168.0.%"
password: sysBenchPassw0rd
priv: "sysbench.*:ALL"
La definizione indica ad Ansible di creare due database, "myshop" e "sysbench", seguiti dal rispettivo utente MySQL con privilegi appropriati, host e password consentiti.
Esegui nuovamente il playbook per applicare la modifica al nostro server MySQL:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Questa volta, Ansible raccoglierà tutte le modifiche apportate in vars/main.yml per applicarle al nostro server MySQL. Possiamo verificare nel server MySQL con i seguenti comandi:
(mysql-host)$ mysql -uroot -p -e 'SHOW DATABASES'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| myshop |
| mysql |
| performance_schema |
| sysbench |
+--------------------+
(mysql-host)$ mysql -uroot -p -e 'SHOW GRANTS FOR [email protected]"192.168.0.%"'
Enter password:
+------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected]% |
+------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'sysbench_user'@'192.168.0.%' IDENTIFIED BY PASSWORD '*4AC2E8AD02562E8FAAF5A958DC2AEA4C47451B5C' |
| GRANT ALL PRIVILEGES ON `sysbench`.* TO 'sysbench_user'@'192.168.0.%' |
+------------------------------------------------------------------------------------------------------------------------+
Abilitazione del registro delle query lente
Questo ruolo supporta l'abilitazione del log di query lente di MySQL, possiamo definire la posizione del file di registro e il tempo di query lento. Aggiungi le variabili necessarie all'interno del file vars/main.yml:
mysql_root_password: "theR00tP455w0rd"
mysql_databases:
- name: example_db
encoding: latin1
collation: latin1_general_ci
- name: sysbench
encoding: latin1
collation: latin1_general_ci
mysql_users:
- name: example_user
host: "%"
password: similarly-secure-password
priv: "example_db.*:ALL"
- name: sysbench_user
host: "192.168.0.%"
password: sysBenchPassw0rd
priv: "sysbench.*:ALL"
mysql_slow_query_log_enabled: true
mysql_slow_query_log_file: 'slow_query.log'
mysql_slow_query_time: '5.000000'
Esegui nuovamente il playbook per applicare le modifiche:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Il playbook apporterà le modifiche necessarie alle opzioni relative alle query lente di MySQL e riavvierà automaticamente il server MySQL per caricare le nuove configurazioni. Possiamo quindi verificare se le nuove opzioni di configurazione sono caricate correttamente sul server MySQL:
(mysql-host)$ mysql -uroot -p -e 'SELECT @@slow_query_log, @@slow_query_log_file, @@long_query_time'
+------------------+-----------------------+-------------------+
| @@slow_query_log | @@slow_query_log_file | @@long_query_time |
+------------------+-----------------------+-------------------+
| 1 | slow_query.log | 5.000000 |
+------------------+-----------------------+-------------------+
Incluso il file di configurazione MySQL personalizzato
Le variabili ruolo Ansible e le variabili MySQL sono due cose diverse. L'autore di questo ruolo ha creato una serie di variabili correlate a MySQL che possono essere rappresentate con variabili di ruolo Ansible. Tratti dal file Leggimi, eccone alcuni:
mysql_port: "3306"
mysql_bind_address: '0.0.0.0'
mysql_datadir: /var/lib/mysql
mysql_socket: *default value depends on OS*
mysql_pid_file: *default value depends on OS*
mysql_log_file_group: mysql *adm on Debian*
mysql_log: ""
mysql_log_error: *default value depends on OS*
mysql_syslog_tag: *default value depends on OS*
Se la configurazione generata non soddisfa i nostri requisiti MySQL, possiamo includere file di configurazione MySQL personalizzati nella distribuzione utilizzando la variabile mysql_config_include_files. Accetta una matrice di valori separati da una virgola, con un "src" come prefisso per il percorso effettivo sull'host Ansible.
Prima di tutto, dobbiamo preparare i file di configurazione personalizzati sull'host Ansible. Crea una directory e un semplice file di configurazione MySQL:
(ansible-host)$ mkdir /root/custom-config/
(ansible-host)$ vim /root/custom-config/my-severalnines.cnf
[mysqld]
max_connections=250
log_bin=binlog
expire_logs_days=7
Diciamo di avere un altro file di configurazione specifico per la configurazione di mysqldump:
(ansible-host)$ vim /root/custom-config/mysqldump.cnf
[mysqldump]
max_allowed_packet=128M
Per importare questi file di configurazione nella nostra distribuzione, definiscili nell'array mysql_config_include_files nel file vars/main.yml:
mysql_root_password: "theR00tP455w0rd"
mysql_databases:
- name: example_db
encoding: latin1
collation: latin1_general_ci
- name: sysbench
encoding: latin1
collation: latin1_general_ci
mysql_users:
- name: example_user
host: "%"
password: similarly-secure-password
priv: "example_db.*:ALL"
- name: sysbench_user
host: "192.168.0.%"
password: sysBenchPassw0rd
priv: "sysbench.*:ALL"
mysql_slow_query_log_enabled: true
mysql_slow_query_log_file: slow_query.log
mysql_slow_query_time: 5
mysql_config_include_files: [
src: '/root/custom-config/my-severalnines.cnf',
src: '/root/custom-config/mysqldump.cnf'
]
Nota che /root/custom-config/mysqld-diverselnines.cnf e /root/custom-config/mysqldump.cnf esistono all'interno dell'host Ansible.
Esegui nuovamente il playbook:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Il playbook importerà quei file di configurazione e li inserirà nella directory include (a seconda del sistema operativo) che è /etc/my.cnf.d/ per CentOS 7. Il playbook riavvierà automaticamente il Server MySQL per caricare le nuove opzioni di configurazione. Possiamo quindi verificare se le nuove opzioni di configurazione sono state caricate correttamente:
(mysql-host)$ mysql -uroot -p -e 'select @@max_connections'
250
(mysql-host)$ mysqldump --help | grep ^max-allowed-packet
max-allowed-packet 134217728
Conclusione
Ansible può essere utilizzato per automatizzare la distribuzione del database e la gestione della configurazione con una piccola conoscenza degli script. Nel frattempo, ClusterControl utilizza un approccio SSH senza password simile per distribuire, monitorare, gestire e ridimensionare il cluster di database dalla A alla Z, con un'interfaccia utente e non necessita di competenze aggiuntive per ottenere lo stesso risultato.