Ansible automatisiert und vereinfacht sich wiederholende, komplexe und langwierige Vorgänge. Es ist eine IT-Automatisierungs-Engine, die die Cloud-Bereitstellung, das Konfigurationsmanagement, die Anwendungsbereitstellung, die Intra-Service-Orchestrierung und viele andere IT-Anforderungen automatisiert. Es erfordert keine Agenten, sondern verwendet nur SSH, um Änderungen von einer einzigen Quelle an mehrere Remote-Ressourcen ohne zusätzliche benutzerdefinierte Konfiguration der Sicherheitsinfrastruktur zu übertragen, und verwendet ein einfaches Sprachformat (YAML), um die Automatisierungsjobs zu beschreiben.
Die Installation eines eigenständigen MySQL-Servers ist eine einfache, unkomplizierte Aufgabe, aber dies kann problematisch sein, wenn Sie mehrere Datenbankserver, Versionen, Plattformen und Umgebungen unterstützen müssen. Daher ist ein Konfigurationsmanagement-Tool der richtige Weg, um die Effizienz zu verbessern, Wiederholungen zu beseitigen und menschliche Fehler zu reduzieren.
In diesem Blogbeitrag führen wir Sie durch die Grundlagen der Ansible-Automatisierung für MySQL sowie durch das Konfigurationsmanagement mit Beispielen und Erläuterungen. Wir beginnen mit einer einfachen eigenständigen MySQL-Bereitstellung, wie im folgenden Diagramm auf hoher Ebene dargestellt:
Ansible installieren
Für diese exemplarische Vorgehensweise benötigen wir mindestens zwei Hosts - Ein Host ist für Ansible (Sie könnten eine Workstation anstelle eines Servers verwenden) und ein anderer ist der Zielhost, den wir bereitstellen möchten MySQL-Server.
Um Ansible auf CentOS 7 zu installieren, führen Sie einfach die folgenden Befehle aus:
(ansible-host)$ yum install -y epel-release
(ansible-host)$ yum install -y ansible
Informationen zu anderen Betriebssystem-Distributionen finden Sie im Ansible-Installationshandbuch.
Passwortloses SSH einrichten
Die Verwendung von Passwörtern während SSH wird unterstützt, aber passwortlose SSH-Schlüssel mit ssh-agent sind eine der besten Möglichkeiten, Ansible zu verwenden. Der erste Schritt besteht darin, passwortloses SSH zu konfigurieren, da Ansible die Bereitstellung ausschließlich über diesen Kanal durchführt. Generieren Sie zunächst einen SSH-Schlüssel auf dem Ansible-Host:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Sie sollten mindestens die folgenden Dateien generiert bekommen:
(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
Um passwortloses SSH zuzulassen, müssen wir den öffentlichen SSH-Schlüssel (id_rsa.pub) auf den Remote-Host kopieren, auf den wir zugreifen möchten. Wir können ein Tool namens ssh-copy-id verwenden, um diese Aufgabe für uns zu erledigen. Sie müssen jedoch das Passwort des Benutzers des Zielhosts kennen und die Passwortauthentifizierung ist auf dem Zielhost erlaubt:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-copy-id [email protected]
Der obige Befehl fordert zur Eingabe des Root-Passworts 192.168.0.221 auf, geben Sie einfach das Passwort ein und der SSH-Schlüssel für den aktuellen Benutzer des Ansible-Hosts wird auf den Zielhost 192.168.0.221 kopiert in ~/.ssh/authorized_keys, was bedeutet, dass wir diesen bestimmten Schlüssel für den Fernzugriff auf diesen Server autorisieren. Zum Testen sollten Sie in der Lage sein, den folgenden Remote-Befehl ohne Passwort vom Ansible-Host auszuführen:
(ansible-host)$ ssh [email protected] "hostname -I"
192.168.0.221
Falls es Ihnen nicht erlaubt ist, den Root-Benutzer für SSH zu verwenden (z. B. "PermitRootLogin no" in der SSH-Konfiguration), können Sie stattdessen einen sudo-Benutzer verwenden. Im folgenden Beispiel richten wir passwortloses SSH für einen sudo-Benutzer namens „vagrant“ ein:
(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]
Wenn der Zielserver keine Kennwortauthentifizierung über SSH zulässt, kopieren Sie einfach den Inhalt des öffentlichen SSH-Schlüssels unter ~/.ssh/id_rsa.pub manuell in die Datei ~/.ssh/authorized_keys des Zielhosts Datei. Rufen Sie beispielsweise auf dem Ansible-Host den Inhalt des öffentlichen Schlüssels ab:
(ansible-host)$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Verbinden Sie sich mit dem Zielhost und fügen Sie den öffentlichen Schlüssel des Ansible-Hosts in ~/.ssh/authorized_keys:
ein(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]
Sie können jetzt versuchen, einen Remote-Befehl vom Ansible-Host auszuführen, um dies zu überprüfen, und Sie sollten nicht zur Eingabe eines Passworts aufgefordert werden. An diesem Punkt ist unser passwortloses SSH konfiguriert.
Definieren des Zielhosts
Als nächstes müssen wir den Zielhost definieren, den Host, den wir mit Ansible verwalten wollen. Basierend auf unserer Architektur werden wir nur einen MySQL-Server bereitstellen, nämlich 192.168.0.221. Fügen Sie die folgenden Zeilen in /etc/ansible/hosts hinzu:
[db-mysql]
192.168.0.221
Das Obige bedeutet einfach, dass wir eine Gruppe namens "db-mysql" definiert haben, die die Kennung ist, wenn wir auf den Zielhost im Ansible Playbook verweisen. Wir können auch alle IP-Adressen oder Hostnamen der Zielhosts unter dieser Gruppe auflisten. An diesem Punkt müssen wir nur einen MySQL-Server bereitstellen, daher ist nur ein Eintrag vorhanden. Sie können auch eine beliebige Übereinstimmungsregel angeben, um die Hosts in einer Gruppe abzugleichen, zum Beispiel:
[db-mysql]
192.168.0.[221:223]
Die obige Definition bedeutet, dass wir 3 Hosts unter genau dieser Gruppe mit den folgenden IP-Adressen haben:
- 192.168.0.221
- 192.168.0.222
- 192.168.0.223
Es gibt viele Möglichkeiten und Regeln, um die Zielhosts abzugleichen und zu gruppieren, wie im Ansible Inventory Guide gezeigt.
Auswahl einer Ansible-Rolle
Um Ansible mitzuteilen, was bereitgestellt werden soll, müssen wir die Bereitstellungsschritte in einer YML-formatierten Datei namens Playbook definieren. Wie Sie vielleicht wissen, erfordert die Installation eines vollständigen MySQL-Servers mehrere Schritte, um alle MySQL-Abhängigkeiten, die Konfiguration nach der Installation, die Benutzer- und Schemaerstellung usw. zu erfüllen. Ansible hat eine Reihe von MySQL-Modulen bereitgestellt, die uns helfen können, aber wir müssen noch ein Playbook für die Bereitstellungsschritte schreiben.
Um die Bereitstellungsschritte zu vereinfachen, können wir vorhandene Ansible-Rollen verwenden. Die Ansible-Rolle ist eine unabhängige Komponente, die die Wiederverwendung gemeinsamer Konfigurationsschritte ermöglicht. Innerhalb des Playbooks muss eine Ansible-Rolle verwendet werden. Es gibt eine Reihe von MySQL Ansible-Rollen in Ansible Galaxy, einem Repository für Ansible-Rollen, die direkt in Ihre Playbooks eingefügt werden können.
Wenn Sie nach "mysql" suchen, erhalten Sie viele Ansible-Rollen für MySQL:
Wir werden das beliebteste namens "mysql" von geerlingguy verwenden. Sie können sich für andere Rollen entscheiden, aber meistens ist die am häufigsten heruntergeladene für allgemeine Zwecke gedacht, was normalerweise in den meisten Fällen gut funktioniert.
Führen Sie auf dem Ansible-Host den folgenden Befehl aus, um die Ansible-Rolle herunterzuladen:
(ansible-host)$ ansible-galaxy install geerlingguy.mysql
Die Rolle wird in ~/.ansible/roles/geerlingguy.mysql/ des aktuellen Benutzers heruntergeladen.
Schreiben des Ansible-Playbooks
Indem wir uns die Readme-Datei der Ansible-Rolle ansehen, können wir dem bereitgestellten Beispiel-Playbook folgen. Erstellen Sie zunächst eine Playbook-Datei namens deploy-mysql.yml und fügen Sie die folgenden Zeilen hinzu:
(ansible-host)$ vim ~/deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
In den obigen Zeilen definieren wir den Zielhost, bei dem es sich um alle Hosts unter db-mysql-Einträgen in /etc/ansible/hosts handelt. Die nächste Zeile (become) weist Ansible an, das Playbook als Root-Benutzer auszuführen, was für die Rolle notwendig ist (steht dort in der Readme-Datei). Als Nächstes definieren wir den Speicherort der Variablendatei (var_files) unter vars/main.yml relativ zum Playbook-Pfad.
Lassen Sie uns das Variablenverzeichnis und die Datei erstellen und die folgende Zeile spezifizieren:
(ansible-host)$ mkdir vars
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
Weitere Informationen finden Sie im Abschnitt Rollenvariablen in der Readme-Datei dieser Rolle.
Bereitstellung starten
Jetzt können wir mit der MySQL-Bereitstellung beginnen. Verwenden Sie den ansible-playbook-Befehl, um unsere Playbook-Definitionen auszuführen:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Sie sollten eine Reihe von Zeilen in der Ausgabe sehen. Konzentrieren Sie sich auf die letzte Zeile, in der die Bereitstellung zusammengefasst wird:
PLAY RECAP ***************************************************************************************************************************************
192.168.0.221 : ok=36 changed=8 unreachable=0 failed=0 skipped=16 rescued=0 ignored=0
Wenn alles grün und in Ordnung ist, können Sie auf dem Datenbankhost überprüfen, ob unser MySQL-Server bereits installiert ist und läuft:
(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
Wie Sie oben sehen können, ist für CentOS 7 die standardmäßige MySQL-Installation MariaDB 5.5 als Teil des Standardpaket-Repositorys. Zu diesem Zeitpunkt gilt unsere Bereitstellung als abgeschlossen, wir möchten unsere Bereitstellung jedoch weiter anpassen, wie in den nächsten Abschnitten gezeigt.
Anpassen der Bereitstellung
Die einfachste Definition im Playbook gibt uns eine sehr einfache Installation und verwendet alle Standardkonfigurationsoptionen. Wir können die MySQL-Installation weiter anpassen, indem wir das Playbook erweitern/modifizieren/anhängen, um Folgendes zu tun:
- MySQL-Konfigurationsoptionen ändern
- Datenbankbenutzer hinzufügen
- Datenbankschema hinzufügen
- Benutzerrechte konfigurieren
- MySQL-Replikation konfigurieren
- Installieren Sie MySQL von anderen Anbietern
- importieren Sie eine benutzerdefinierte MySQL-Konfigurationsdatei
Installieren von MySQL aus dem Oracle-Repository
Standardmäßig installiert die Rolle das standardmäßige MySQL-Paket, das mit der Betriebssystemverteilung geliefert wird. Bei CentOS 7 wird MariaDB 5.5 standardmäßig installiert. Angenommen, wir möchten MySQL von einem anderen Anbieter installieren, können wir das Playbook um pre_tasks erweitern, eine Aufgabe, die Ansible ausführt, bevor irgendwelche Aufgaben ausgeführt werden, die in einer .yml-Datei erwähnt werden, wie im folgenden Beispiel gezeigt:
(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"
Führen Sie das Playbook aus:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Das Obige installiert stattdessen MySQL aus dem Oracle-Repository. Die Standardversion, die Sie erhalten würden, ist MySQL 5.6. Das Ausführen des obigen Playbooks auf einem Zielhost, auf dem bereits eine ältere Version von MySQL/MariaDB ausgeführt wird, würde aufgrund der Inkompatibilität wahrscheinlich fehlschlagen.
Erstellen von MySQL-Datenbanken und Benutzern
Innerhalb von vars/main.yml können wir die MySQL-Datenbank und Benutzer definieren, die Ansible auf unserem MySQL-Server konfigurieren soll, indem wir die Module mysql_database und mysql_users verwenden, direkt nach unserer vorherigen Definition auf 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"
Die Definition weist Ansible an, zwei Datenbanken zu erstellen, "myshop" und "sysbench", gefolgt von seinem jeweiligen MySQL-Benutzer mit den richtigen Privilegien, erlaubtem Host und Passwort.
Führen Sie das Playbook erneut aus, um die Änderung auf unseren MySQL-Server anzuwenden:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Dieses Mal übernimmt Ansible alle Änderungen, die wir in vars/main.yml vorgenommen haben, um sie auf unseren MySQL-Server anzuwenden. Wir können im MySQL-Server mit den folgenden Befehlen überprüfen:
(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.%' |
+------------------------------------------------------------------------------------------------------------------------+
Protokoll für langsame Abfragen aktivieren
Diese Rolle unterstützt das Aktivieren des langsamen MySQL-Abfrageprotokolls, wir können den Speicherort der Protokolldatei sowie die langsame Abfragezeit definieren. Fügen Sie die erforderlichen Variablen in der Datei vars/main.yml hinzu:
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'
Führen Sie das Playbook erneut aus, um die Änderungen zu übernehmen:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Das Playbook nimmt die notwendigen Änderungen an den MySQL-Optionen für langsame Abfragen vor und startet den MySQL-Server automatisch neu, um die neuen Konfigurationen zu laden. Wir können dann überprüfen, ob die neuen Konfigurationsoptionen korrekt auf den MySQL-Server geladen werden:
(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 |
+------------------+-----------------------+-------------------+
Inklusive benutzerdefinierter MySQL-Konfigurationsdatei
Ansible-Rollenvariablen und MySQL-Variablen sind zwei verschiedene Dinge. Der Autor dieser Rolle hat eine Reihe von MySQL-bezogenen Variablen erstellt, die mit Ansible-Rollenvariablen dargestellt werden können. Aus der Readme-Datei entnommen, hier sind einige davon:
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*
Wenn die generierte Konfiguration unsere MySQL-Anforderungen nicht erfüllt, können wir benutzerdefinierte MySQL-Konfigurationsdateien in die Bereitstellung einschließen, indem wir die Variable mysql_config_include_files verwenden. Es akzeptiert ein Array von Werten, die durch ein Komma getrennt sind, mit einem „src“ als Präfix für den tatsächlichen Pfad auf dem Ansible-Host.
Zunächst müssen wir die benutzerdefinierten Konfigurationsdateien auf dem Ansible-Host vorbereiten. Erstellen Sie ein Verzeichnis und eine einfache MySQL-Konfigurationsdatei:
(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
Nehmen wir an, wir haben eine weitere Konfigurationsdatei speziell für die mysqldump-Konfiguration:
(ansible-host)$ vim /root/custom-config/mysqldump.cnf
[mysqldump]
max_allowed_packet=128M
Um diese Konfigurationsdateien in unsere Bereitstellung zu importieren, definieren Sie sie im Array mysql_config_include_files in der Datei 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'
]
Beachten Sie, dass /root/custom-config/mysqld-severalnines.cnf und /root/custom-config/mysqldump.cnf innerhalb des Ansible-Hosts vorhanden sind.
Führen Sie das Playbook erneut aus:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Das Playbook importiert diese Konfigurationsdateien und legt sie in das Include-Verzeichnis (je nach Betriebssystem) ab, das /etc/my.cnf.d/ für CentOS 7 ist. Das Playbook startet automatisch neu MySQL-Server zum Laden der neuen Konfigurationsoptionen. Wir können dann überprüfen, ob die neuen Konfigurationsoptionen korrekt geladen werden:
(mysql-host)$ mysql -uroot -p -e 'select @@max_connections'
250
(mysql-host)$ mysqldump --help | grep ^max-allowed-packet
max-allowed-packet 134217728
Fazit
Ansible kann verwendet werden, um die Datenbankbereitstellung und das Konfigurationsmanagement mit ein wenig Scripting-Kenntnissen zu automatisieren. In der Zwischenzeit verwendet ClusterControl einen ähnlichen kennwortlosen SSH-Ansatz zum Bereitstellen, Überwachen, Verwalten und Skalieren Ihres Datenbankclusters von A bis Z mit einer Benutzeroberfläche und erfordert keine zusätzlichen Kenntnisse, um dasselbe Ergebnis zu erzielen.