Ansible automatyzuje i upraszcza powtarzalne, złożone i żmudne operacje. Jest to silnik automatyzacji IT, który automatyzuje udostępnianie chmury, zarządzanie konfiguracją, wdrażanie aplikacji, orkiestrację wewnątrzusługową i wiele innych potrzeb IT. Nie wymaga agentów, używa tylko SSH do przesyłania zmian z jednego źródła do wielu zdalnych zasobów bez dodatkowej niestandardowej konfiguracji infrastruktury bezpieczeństwa i używa prostego formatu języka (YAML) do opisywania zadań automatyzacji.
Instalacja samodzielnego serwera MySQL jest prostym, prostym zadaniem, ale może to być problematyczne, jeśli masz do obsługi wiele serwerów baz danych, wersji, platform i środowisk. Dlatego posiadanie narzędzia do zarządzania konfiguracją jest sposobem na poprawę wydajności, usunięcie powtarzalności i ograniczenie błędów ludzkich.
W tym poście na blogu omówimy podstawy automatyzacji Ansible dla MySQL, a także zarządzanie konfiguracją z przykładami i wyjaśnieniami. Zaczniemy od prostego samodzielnego wdrożenia MySQL, jak pokazano na poniższym diagramie wysokiego poziomu:
Instalowanie Ansible
W tym przewodniku musimy mieć co najmniej dwa hosty — jeden host jest przeznaczony dla Ansible (można użyć stacji roboczej zamiast serwera), a drugi to host docelowy, na którym chcemy wdrożyć Serwer MySQL.
Aby zainstalować Ansible na CentOS 7, po prostu uruchom następujące polecenia:
(ansible-host)$ yum install -y epel-release
(ansible-host)$ yum install -y ansible
W przypadku innych dystrybucji systemu operacyjnego zapoznaj się z przewodnikiem instalacji Ansible.
Konfigurowanie SSH bez hasła
Używanie hasła podczas SSH jest obsługiwane, ale bezhasłowe klucze SSH z ssh-agent to jeden z najlepszych sposobów korzystania z Ansible. Pierwszym krokiem jest skonfigurowanie SSH bez hasła, ponieważ Ansible wykona wdrożenie wyłącznie przez ten kanał. Najpierw wygeneruj klucz SSH na hoście Ansible:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Powinieneś otrzymać przynajmniej następujące wygenerowane pliki:
(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
Aby zezwolić na SSH bez hasła, musimy skopiować klucz publiczny SSH (id_rsa.pub) na zdalny host, do którego chcemy uzyskać dostęp. Do wykonania tego zadania możemy użyć narzędzia o nazwie ssh-copy-id. Musisz jednak znać hasło użytkownika hosta docelowego, a uwierzytelnianie hasła jest dozwolone na hoście docelowym:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-copy-id [email protected]
Powyższe polecenie wyświetli monit o hasło roota 192.168.0.221, wystarczy wprowadzić hasło, a klucz SSH dla bieżącego użytkownika hosta Ansible zostanie skopiowany do hosta docelowego, 192.168.0.221 do ~/.ssh/authorized_keys, co oznacza, że autoryzujemy ten konkretny klucz do zdalnego dostępu do tego serwera. Aby przetestować, powinieneś być w stanie uruchomić następujące zdalne polecenie bez hasła z hosta Ansible:
(ansible-host)$ ssh [email protected] "hostname -I"
192.168.0.221
W przypadku, gdy nie możesz używać użytkownika root dla SSH (np. „PermitRootLogin no” w konfiguracji SSH), możesz zamiast tego użyć użytkownika sudo. W poniższym przykładzie skonfigurowaliśmy bezhasłowe SSH dla użytkownika sudo o nazwie „wagrant”:
(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]
Jeśli serwer docelowy nie pozwala na uwierzytelnianie hasłem przez SSH, po prostu skopiuj ręcznie zawartość klucza publicznego SSH z ~/.ssh/id_rsa.pub do ~/.ssh/authorized_keys hostów docelowych plik. Na przykład na hoście Ansible pobierz zawartość klucza publicznego:
(ansible-host)$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Połącz się z hostem docelowym i wklej publiczny klucz hosta Ansible do ~/.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]
Możesz teraz spróbować uruchomić zdalne polecenie z hosta Ansible w celu weryfikacji i nie powinno być wyświetlane żadne hasło. W tym momencie skonfigurowany jest nasz bezhasłowy SSH.
Definiowanie hosta docelowego
Następnie musimy zdefiniować hosta docelowego, hosta, którym chcemy zarządzać za pomocą Ansible. W oparciu o naszą architekturę zamierzamy wdrożyć tylko jeden serwer MySQL, którym jest 192.168.0.221. Dodaj następujące wiersze do /etc/ansible/hosts:
[db-mysql]
192.168.0.221
Powyższe oznacza po prostu, że zdefiniowaliśmy grupę o nazwie „db-mysql”, która będzie identyfikatorem, gdy będziemy odnosić się do hosta docelowego w podręczniku Ansible. Możemy również wymienić wszystkie adresy IP lub nazwy hostów docelowych hostów w tej grupie. W tym momencie mamy tylko jeden serwer MySQL do wdrożenia, dlatego jest tam tylko jeden wpis. Możesz także określić dowolną regułę dopasowania, aby dopasować hosty w jednej grupie, na przykład:
[db-mysql]
192.168.0.[221:223]
Powyższa definicja oznacza, że w tej samej grupie mamy 3 hosty z następującymi adresami IP:
- 192.168.0.221
- 192.168.0.222
- 192.168.0.223
Istnieje wiele sposobów i reguł dopasowywania i grupowania hostów docelowych, jak pokazano w przewodniku po zasobach Ansible.
Wybór roli ansibla
Aby poinformować Ansible, co wdrożyć, musimy zdefiniować kroki wdrażania w pliku w formacie YML zwanym playbook. Jak być może wiesz, zainstalowanie kompletnego serwera MySQL wymaga wykonania wielu kroków, aby spełnić wszystkie zależności MySQL, konfigurację poinstalacyjną, tworzenie użytkowników i schematów i tak dalej. Ansible dostarczył wiele modułów MySQL, które mogą nam pomóc, ale nadal musimy napisać podręcznik dotyczący kroków wdrażania.
Aby uprościć kroki wdrażania, możemy użyć istniejących ról Ansible. Rola Ansible jest niezależnym komponentem, który umożliwia ponowne wykorzystanie typowych kroków konfiguracyjnych. W podręczniku należy użyć roli Ansible. Istnieje wiele ról MySQL Ansible dostępnych w Ansible Galaxy, repozytorium ról Ansible, które można wrzucić bezpośrednio do swoich podręczników.
Jeśli wyszukasz „mysql”, otrzymasz wiele ról Ansible dla MySQL:
Użyjemy najpopularniejszego o nazwie "mysql" autorstwa geerlingguy. Możesz zdecydować się na użycie innych ról, ale najczęściej pobierana jest głównie do celów ogólnych, co zwykle działa dobrze w większości przypadków.
Na hoście Ansible uruchom następujące polecenie, aby pobrać rolę Ansible:
(ansible-host)$ ansible-galaxy install geerlingguy.mysql
Rola zostanie pobrana do ~/.ansible/roles/geerlingguy.mysql/ bieżącego użytkownika.
Pisanie Poradnika Ansible
Przeglądając plik Readme roli Ansible, możemy skorzystać z przykładowego podręcznika, który jest dostarczany. Najpierw utwórz plik playbook o nazwie deploy-mysql.yml i dodaj następujące wiersze:
(ansible-host)$ vim ~/deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
W powyższych wierszach definiujemy hosta docelowego, którym są wszystkie hosty we wpisach db-mysql w /etc/ansible/hosts. Następna linia (stać się) mówi Ansible, aby wykonał playbook jako użytkownik root, który jest niezbędny do roli (jest to podane w pliku Readme). Następnie definiujemy położenie pliku zmiennych (var_files) znajdującego się w vars/main.yml, względem ścieżki playbooka.
Utwórzmy katalog zmiennych i plik oraz określmy następujący wiersz:
(ansible-host)$ mkdir vars
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
Aby uzyskać więcej informacji, zapoznaj się z sekcją Zmienne ról w pliku Readme tej roli.
Rozpocznij wdrażanie
Teraz jesteśmy gotowi do rozpoczęcia wdrażania MySQL. Użyj polecenia ansible-playbook, aby wykonać nasze definicje z podręcznika:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Powinieneś zobaczyć kilka linii na wyjściu. Skoncentruj się na ostatnim wierszu, w którym podsumowuje wdrożenie:
PLAY RECAP ***************************************************************************************************************************************
192.168.0.221 : ok=36 changed=8 unreachable=0 failed=0 skipped=16 rescued=0 ignored=0
Jeśli wszystko zmieni kolor na zielony i OK, możesz sprawdzić na hoście bazy danych, czy nasz serwer MySQL jest już zainstalowany i uruchomiony:
(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
Jak widać z powyższego, dla CentOS 7 domyślną instalacją MySQL jest MariaDB 5.5 jako część standardowego repozytorium pakietów. W tym momencie nasze wdrożenie jest uważane za zakończone, jednak chcielibyśmy jeszcze bardziej dostosować nasze wdrożenie, jak pokazano w następnych sekcjach.
Dostosowywanie wdrożenia
Najprostsza definicja w playbooku daje nam bardzo podstawową instalację i wykorzystuje wszystkie domyślne opcje konfiguracyjne. Możemy jeszcze bardziej dostosować instalację MySQL, rozszerzając/modyfikując/dołączając Playbook, aby wykonać następujące czynności:
- zmodyfikuj opcje konfiguracji MySQL
- dodaj użytkownika bazy danych
- dodaj schemat bazy danych
- skonfiguruj uprawnienia użytkownika
- skonfiguruj replikację MySQL
- zainstaluj MySQL od innych dostawców
- importuj niestandardowy plik konfiguracyjny MySQL
Instalowanie MySQL z repozytorium Oracle
Domyślnie rola zainstaluje domyślny pakiet MySQL, który jest dostarczany z dystrybucją systemu operacyjnego. Jeśli chodzi o CentOS 7, domyślnie instalujesz MariaDB 5.5. Załóżmy, że chcemy zainstalować MySQL od innego dostawcy, możemy rozszerzyć podręcznik o pre_tasks, zadanie, które Ansible wykonuje przed wykonaniem jakichkolwiek zadań wymienionych w dowolnym pliku .yml, jak pokazano w poniższym przykładzie:
(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"
Wykonaj instrukcję:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Powyższe zainstaluje MySQL z repozytorium Oracle. Domyślna wersja to MySQL 5.6. Wykonanie powyższego podręcznika na docelowym hoście, na którym jest już uruchomiona starsza wersja MySQL/MariaDB, prawdopodobnie zakończy się niepowodzeniem z powodu niezgodności.
Tworzenie baz danych i użytkowników MySQL
Wewnątrz vars/main.yml możemy zdefiniować bazę danych MySQL i użytkowników, których Ansible ma skonfigurować na naszym serwerze MySQL za pomocą modułów mysql_database i mysql_users, zaraz po naszej poprzedniej definicji w 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"
Definicja instruuje Ansible, aby utworzył dwie bazy danych, "myshop" i "sysbench", podążając za odpowiednim użytkownikiem MySQL z odpowiednimi uprawnieniami, dozwolonym hostem i hasłem.
Uruchom ponownie podręcznik, aby zastosować zmianę na naszym serwerze MySQL:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Tym razem Ansible odbierze wszystkie zmiany, które wprowadziliśmy w vars/main.yml do zastosowania na naszym serwerze MySQL. Możemy zweryfikować na serwerze MySQL za pomocą następujących poleceń:
(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.%' |
+------------------------------------------------------------------------------------------------------------------------+
Włączanie dziennika powolnych zapytań
Ta rola obsługuje włączanie wolnego dziennika zapytań MySQL, możemy zdefiniować lokalizację pliku dziennika, a także czas wolnego zapytania. Dodaj niezbędne zmienne w pliku 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'
Uruchom ponownie podręcznik, aby zastosować zmiany:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Podręcznik wprowadzi niezbędne zmiany w opcjach związanych z wolnymi zapytaniami MySQL i automatycznie zrestartuje serwer MySQL, aby załadować nowe konfiguracje. Następnie możemy zweryfikować, czy nowe opcje konfiguracyjne zostały poprawnie załadowane na serwerze 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 |
+------------------+-----------------------+-------------------+
W tym niestandardowy plik konfiguracyjny MySQL
Zmienne roli Ansible i zmienne MySQL to dwie różne rzeczy. Autor tej roli stworzył wiele zmiennych związanych z MySQL, które mogą być reprezentowane przez zmienne roli Ansible. Oto niektóre z nich zaczerpnięte z pliku Readme:
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*
Jeżeli wygenerowana konfiguracja nie spełnia naszych wymagań MySQL, możemy dołączyć niestandardowe pliki konfiguracyjne MySQL do wdrożenia za pomocą zmiennej mysql_config_include_files. Przyjmuje tablicę wartości oddzielonych przecinkiem, z przedrostkiem „src” jako przedrostkiem rzeczywistej ścieżki na hoście Ansible.
Przede wszystkim musimy przygotować niestandardowe pliki konfiguracyjne na hoście Ansible. Utwórz katalog i prosty plik konfiguracyjny 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
Powiedzmy, że mamy inny plik konfiguracyjny specjalnie dla konfiguracji mysqldump:
(ansible-host)$ vim /root/custom-config/mysqldump.cnf
[mysqldump]
max_allowed_packet=128M
Aby zaimportować te pliki konfiguracyjne do naszego wdrożenia, zdefiniuj je w tablicy mysql_config_include_files w pliku 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'
]
Zauważ, że /root/custom-config/mysqld-severalnines.cnf i /root/custom-config/mysqldump.cnf istnieją na hoście Ansible.
Uruchom ponownie podręcznik:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Playbook zaimportuje te pliki konfiguracyjne i umieści je w katalogu include (w zależności od systemu operacyjnego), którym jest /etc/my.cnf.d/ dla CentOS 7. Playbook automatycznie zrestartuje Serwer MySQL do załadowania nowych opcji konfiguracyjnych. Następnie możemy zweryfikować, czy nowe opcje konfiguracyjne zostały załadowane poprawnie:
(mysql-host)$ mysql -uroot -p -e 'select @@max_connections'
250
(mysql-host)$ mysqldump --help | grep ^max-allowed-packet
max-allowed-packet 134217728
Wnioski
Ansible może być używany do automatyzacji wdrażania bazy danych i zarządzania konfiguracją przy niewielkiej znajomości skryptów. Tymczasem ClusterControl wykorzystuje podobne podejście SSH bez hasła do wdrażania, monitorowania, zarządzania i skalowania klastra bazy danych od A do Z, z interfejsem użytkownika i nie wymaga dodatkowych umiejętności, aby osiągnąć ten sam wynik.