Ansible automatiserer og forenkler gentagne, komplekse og kedelige operationer. Det er en IT-automatiseringsmotor, der automatiserer cloud-provisionering, konfigurationsadministration, applikationsimplementering, intra-service-orkestrering og mange andre it-behov. Det kræver ingen agenter, bruger kun SSH til at skubbe ændringer fra en enkelt kilde til flere eksterne ressourcer uden yderligere brugerdefineret sikkerhedsinfrastrukturkonfiguration og brug et simpelt sprogformat (YAML) til at beskrive automatiseringsjob.
Installation af en selvstændig MySQL-server er en simpel og ligetil opgave, men dette kan være problematisk, hvis du har flere databaseservere, versioner, platforme og miljøer at understøtte. At have et konfigurationsstyringsværktøj er således vejen at gå for at forbedre effektiviteten, fjerne gentagelser og reducere menneskelige fejl.
I dette blogindlæg vil vi guide dig gennem det grundlæggende i Ansibles automatisering til MySQL, samt konfigurationsstyring med eksempler og forklaringer. Vi starter med en simpel selvstændig MySQL-implementering, som illustreret i følgende diagram på højt niveau:
Installation af Ansible
For denne gennemgang skal vi have mindst to værter - En vært er for Ansible (du kan bruge en arbejdsstation i stedet for en server), og en anden er den målvært, som vi vil implementere en MySQL server.
For at installere Ansible på CentOS 7 skal du blot køre følgende kommandoer:
(ansible-host)$ yum install -y epel-release
(ansible-host)$ yum install -y ansible
For andre OS-distributioner, se Ansible installationsvejledningen.
Opsætning af SSH uden adgangskode
Brug af adgangskode under SSH er understøttet, men adgangskodeløse SSH-nøgler med ssh-agent er en af de bedste måder at bruge Ansible på. Det første trin er at konfigurere adgangskodefri SSH, da Ansible vil udføre implementeringen udelukkende af denne kanal. Generer først en SSH-nøgle på Ansible-værten:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Du bør som minimum få genereret følgende filer:
(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
For at tillade adgangskodefri SSH skal vi kopiere den offentlige SSH-nøgle (id_rsa.pub) til den fjernvært, som vi ønsker at få adgang til. Vi kan bruge et værktøj kaldet ssh-copy-id til at udføre denne opgave for os. Du skal dog kende brugerens adgangskode til målværten, og adgangskodegodkendelsen er tilladt på målværten:
(ansible-host)$ whoami
root
(ansible-host)$ ssh-copy-id [email protected]
Ovenstående kommando vil bede om root-adgangskoden 192.168.0.221, indtast blot adgangskoden og SSH-nøglen for den aktuelle bruger af Ansible-værten vil blive kopieret over til målværten, 192.168.0.221 ind i ~/.ssh/authorized_keys, hvilket betyder, at vi autoriserer den pågældende nøgle til at få fjernadgang til denne server. For at teste, bør du være i stand til at køre følgende fjernkommando uden adgangskode fra Ansible-vært:
(ansible-host)$ ssh [email protected] "hostname -I"
192.168.0.221
I tilfælde hvor du ikke har tilladelse til at bruge root-bruger til SSH (f.eks. "PermitRootLogin no" i SSH-konfiguration), kan du bruge en sudo-bruger i stedet. I det følgende eksempel opsætter vi adgangskodefri SSH for en sudo-bruger kaldet "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]
Hvis målserveren ikke tillader adgangskodegodkendelse via SSH, skal du blot kopiere indholdet af den offentlige SSH-nøgle på ~/.ssh/id_rsa.pub manuelt ind i målværternes ~/.ssh/authorized_keys fil. På Ansible-værten skal du f.eks. hente det offentlige nøgleindhold:
(ansible-host)$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Opret forbindelse til målværten, og indsæt Ansibles offentlige værtsnøgle i ~/.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]
Du kan nu prøve at køre en fjernkommando fra Ansible-vært for at bekræfte, og du skal ikke blive bedt om en adgangskode. På dette tidspunkt er vores adgangskodeløse SSH konfigureret.
Definition af målværten
Derefter skal vi definere målværten, den vært, som vi vil administrere ved hjælp af Ansible. Baseret på vores arkitektur vil vi kun implementere én MySQL-server, som er 192.168.0.221. Tilføj følgende linjer i /etc/ansible/hosts:
[db-mysql]
192.168.0.221
Ovenstående betyder simpelthen, at vi definerede en gruppe kaldet "db-mysql", som vil være identifikatoren, når vi henviser til målværten i Ansible playbook. Vi kan også liste alle IP-adresser eller værtsnavne på målværterne under denne gruppe. På dette tidspunkt har vi kun én MySQL-server at implementere, så der er kun én indgang. Du kan også angive en matchende regel for at matche værterne under én gruppe, for eksempel:
[db-mysql]
192.168.0.[221:223]
Ovenstående definition betyder, at vi har 3 værter under netop denne gruppe med følgende IP-adresser:
- 192.168.0.221
- 192.168.0.222
- 192.168.0.223
Der er mange måder og regler til at matche og gruppere målværterne som vist i Ansible inventory guide.
Valg af en ansible rolle
For at fortælle Ansible, hvad der skal implementeres, skal vi definere implementeringstrinnene i en YML-formateret fil kaldet playbook. Som du måske ved, kræver installation af en komplet MySQL-server flere trin for at tilfredsstille alle MySQL-afhængigheder, konfiguration efter installation, oprettelse af bruger og skema og så videre. Ansible har leveret en række MySQL-moduler, der kan hjælpe os, men vi er stadig nødt til at skrive en håndbog for implementeringstrinnene.
For at forenkle implementeringstrinnene kan vi bruge eksisterende Ansible-roller. Ansible rolle er en uafhængig komponent, som tillader genbrug af almindelige konfigurationstrin. En Ansible-rolle skal bruges i spillebogen. Der er en række MySQL Ansible-roller tilgængelige i Ansible Galaxy, et opbevaringssted for Ansible-roller, som er tilgængelige for at falde direkte ind i dine playbooks.
Hvis du slår "mysql" op, får du masser af Ansible-roller til MySQL:
Vi vil bruge den mest populære kaldet "mysql" af geerlingguy. Du kan vælge at bruge andre roller, men for det meste har den mest downloadede en tendens til at være til generelle formål, hvilket normalt fungerer fint i de fleste tilfælde.
På Ansible-værten skal du køre følgende kommando for at downloade Ansible-rollen:
(ansible-host)$ ansible-galaxy install geerlingguy.mysql
Rollen vil blive downloadet til ~/.ansible/roles/geerlingguy.mysql/ for den aktuelle bruger.
Skrivelse af Ansible Playbook
Ved at se på Readme of the Ansible-rollen kan vi følge den eksempel-playbook, der bliver leveret. Først skal du oprette en playbook-fil kaldet deploy-mysql.yml og tilføje følgende linjer:
(ansible-host)$ vim ~/deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
I ovenstående linjer definerer vi målværten, som er alle værter under db-mysql-indgange i /etc/ansible/hosts. Den næste linje (bliv) fortæller Ansible at udføre playbook som en root-bruger, hvilket er nødvendigt for rollen (det står der i Readme-filen). Dernæst definerer vi placeringen af variabelfilen (var_files) placeret på vars/main.yml, i forhold til playbook-stien.
Lad os oprette den variable mappe og fil og specificere følgende linje:
(ansible-host)$ mkdir vars
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
For mere information se afsnittet Rollevariabler i Readme-filen for denne rolle.
Start implementeringen
Nu er vi klar til at starte MySQL-implementeringen. Brug kommandoen ansible-playbook til at udføre vores playbook-definitioner:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Du skulle se en masse linjer vises i outputtet. Fokuser på den sidste linje, hvor den opsummerer implementeringen:
PLAY RECAP ***************************************************************************************************************************************
192.168.0.221 : ok=36 changed=8 unreachable=0 failed=0 skipped=16 rescued=0 ignored=0
Hvis alt bliver grønt og OK, kan du bekræfte på databaseværten, at vores MySQL-server allerede er installeret og kører:
(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
Som du kan se fra ovenstående, for CentOS 7 er standard MySQL-installationen MariaDB 5.5 som en del af standardpakkelageret. På dette tidspunkt betragtes vores implementering som afsluttet, men vi vil gerne tilpasse vores implementering yderligere som vist i de næste afsnit.
Tilpasning af implementeringen
Den enkleste definition i Playbook giver os en meget grundlæggende installation og bruger alle standardkonfigurationsmuligheder. Vi kan yderligere tilpasse MySQL-installationen ved at udvide/ændre/tilføje afspilningsbogen for at gøre følgende:
- rediger MySQL-konfigurationsindstillinger
- tilføj databasebruger
- tilføj databaseskema
- konfigurere brugerrettigheder
- konfigurer MySQL-replikering
- installer MySQL fra andre leverandører
- importér en tilpasset MySQL-konfigurationsfil
Installation af MySQL fra Oracle-lageret
Som standard vil rollen installere standard MySQL-pakken, der følger med OS-distributionen. Hvad angår CentOS 7, ville du få MariaDB 5.5 installeret som standard. Antag, at vi ønsker at installere MySQL fra en anden leverandør, kan vi udvide playbook med pre_tasks, en opgave, som Ansible udfører før udførelsen af opgaver nævnt i en .yml-fil, som vist i følgende eksempel:
(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"
Kør afspilningsbogen:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Ovenstående vil i stedet installere MySQL fra Oracle-lageret. Standardversionen du ville få er MySQL 5.6. At udføre ovenstående afspilningsbog på en målvært, der allerede har en kørende ældre version af MySQL/MariaDB, vil sandsynligvis mislykkes på grund af inkompatibiliteten.
Oprettelse af MySQL-databaser og -brugere
Inde i vars/main.yml kan vi definere MySQL-databasen og brugere, som vi ønsker, at Ansible skal konfigurere på vores MySQL-server ved at bruge modulerne mysql_database og mysql_users, lige efter vores tidligere definition på 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"
Definitionen instruerer Ansible om at oprette to databaser, "myshop" og "sysbench", efterfulgt dens respektive MySQL-bruger med de rette privilegier, tilladt vært og adgangskode.
Genudfør afspilningsbogen for at anvende ændringen på vores MySQL-server:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Denne gang vil Ansible hente alle de ændringer, vi har lavet i vars/main.yml, for at blive anvendt på vores MySQL-server. Vi kan verificere i MySQL-serveren med følgende kommandoer:
(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.%' |
+------------------------------------------------------------------------------------------------------------------------+
Aktivering af langsom forespørgselslog
Denne rolle understøtter aktivering af MySQL langsom forespørgselslog, vi kan definere placeringen af logfilen såvel som den langsomme forespørgselstid. Tilføj de nødvendige variabler i filen 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'
Kør afspilningsbogen igen for at anvende ændringerne:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Playbook vil foretage de nødvendige ændringer af MySQL langsomme forespørgsler relaterede muligheder og genstarte MySQL serveren automatisk for at indlæse de nye konfigurationer. Vi kan derefter kontrollere, om de nye konfigurationsmuligheder er indlæst korrekt på MySQL-serveren:
(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 brugerdefineret MySQL-konfigurationsfil
Ansible rollevariabler og MySQL-variabler er to forskellige ting. Forfatteren af denne rolle har oprettet en række MySQL-relaterede variabler, der kan repræsenteres med Ansible-rollevariabler. Taget fra Readme-filen, her er nogle af dem:
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*
Hvis den genererede konfiguration ikke opfylder vores MySQL-krav, kan vi inkludere brugerdefinerede MySQL-konfigurationsfiler i implementeringen ved at bruge variabelen mysql_config_include_files. Den accepterer en række værdier adskilt af et komma med et "src" som præfiks for den faktiske sti på Ansible-værten.
Først og fremmest skal vi forberede de brugerdefinerede konfigurationsfiler på Ansible-værten. Opret en mappe og en simpel MySQL-konfigurationsfil:
(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
Lad os sige, at vi har en anden konfigurationsfil specifikt til mysqldump-konfiguration:
(ansible-host)$ vim /root/custom-config/mysqldump.cnf
[mysqldump]
max_allowed_packet=128M
For at importere disse konfigurationsfiler til vores implementering skal du definere dem i mysql_config_include_files-arrayet i filen 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'
]
Bemærk, at /root/custom-config/mysqld-severalnines.cnf og /root/custom-config/mysqldump.cnf findes inde i Ansible-værten.
Kør afspilningsbogen igen:
(ansible-host)$ ansible-playbook deploy-mysql.yml
Afspilningsbogen importerer disse konfigurationsfiler og sætter dem i mappen include (afhængigt af operativsystemet), som er /etc/my.cnf.d/ for CentOS 7. Afspilningsbogen genstarter automatisk MySQL-server for at indlæse de nye konfigurationsmuligheder. Vi kan derefter kontrollere, om de nye konfigurationsmuligheder er indlæst korrekt:
(mysql-host)$ mysql -uroot -p -e 'select @@max_connections'
250
(mysql-host)$ mysqldump --help | grep ^max-allowed-packet
max-allowed-packet 134217728
Konklusion
Ansible kan bruges til at automatisere databaseimplementeringen og konfigurationsstyringen med lidt viden om scripting. I mellemtiden bruger ClusterControl en lignende adgangskodefri SSH-tilgang til at implementere, overvåge, administrere og skalere din databaseklynge fra A til Z med en brugergrænseflade og behøver ingen yderligere færdigheder for at opnå det samme resultat.