Managing MySQL replication with Ansible

Source: Internet
Author: User
Tags vars ansible playbook saltstack

Known as one of the most popular open source database, MySQL is widely used in various scenarios, ApsaraDB RDS for MySQL of Alibaba Cloud provided critical relief for companies, especially small and medium-sized enterprises affected by novel coronavirus (COVID-19).



Ansible is an emerging IT automation tool. This article will show you how to configure and manage MySQL master through Ansible, automate the deployment process from the replication environment, and experience the thrill of Ansible simple and fast.


Ansible user



Brief introduction: ansible user module



Ansible is a configuration management and application Deployment tool that functions like the current Industry configuration management tool Chef,puppet,saltstack. Ansible is developed through the Python language. The Ansible platform was created by Michael DeHaan, ansible create user who is also the author of the well-known software Cobbler and Func. Ansible's first version was released in February 2012, and Ansible is still very young compared to other similar products, but this does not affect his vigorous development and the love of his people.


Ansible add user

Ansible the machine is managed by default via the SSH protocol, so Ansible does not need to install the client program on the server. You only need to install Ansible on one server, and after the Ansible is installed, you can manage to control other servers. You do not need to configure the database for it, Ansible does not start or remain running in daemons manner. Ansible's objectives are as follows:


    • Automating deployment of applications
    • Automated Management configuration
    • Continuous delivery of automation
    • Automated (AWS) cloud service management.


According to Ansible's official information, users currently using Ansible are: Evernote, Rackspace, NASA, Atlassian, Twitter, etc.


Ansible add user to group


Preparation before installation
Ansible server requirements


The current Ansible can be run on any machine with Python2.6 installed (temporarily does not support the Windows machine-centric control server), which includes Redhat,debian,centos,os X,bsds and so on.

Installing Ansible


If you are a centos/redhat, Debian, Ubuntu user, you can use the System Package Manager yum or Apt-get installation (Centos/redhat need to install Epel package to install via Yum). But here, I strongly recommend that you use PIP to install Ansible. So what is PIP? Pip is a Python package installation and management tool that features a gem of NPM, Ruby, similar to node. js. Pip makes it easy to install, upgrade, delete, and manage Python packages. As described earlier Ansible is to enable Python development, then natural Ansible can also be installed via PIP. For more details on PIP, please visit https://pypi.python.org/pypi/pip/.


Installing Ansible with PIP


Before using PIP, make sure that your system already has the Pthon Setuptools package installed








Yum–y Install Python-setuptools


Install PIP








Easy_install pip


Installing Ansible with PIP



Pip Install Ansbile



What do you think? Installing Ansible via PIP is not very simple, as long as the simple three steps to complete the operation. As long as the Python operating system is supported, you can use PIP installation.



OK, now if you do, you have installed the Ansible on your server.



Described earlier Ansible is the SSH protocol to manage the machine, Ansible the default use of SSH Keys communication, this is Ansible official highly recommended method, but if you want to use the password, of course, is also possible. In order to enable password authentication, using the--ask-pass option, in this article, the author uses the key authentication method to demonstrate, the reader can choose whether to use the password authentication or the key authentication according to the need.




Ansible combat

 use Ansible to execute commands on a remote server

After installing the Ansible, use Ansible to perform a command on the other server to confirm the connectivity of the Ansible server to other servers. Before executing the Ansible Management Server, you need to configure the server information. Ansible uses the file to store the server information you want to manage, this file is called the manifest file in Ansible, the default manifest file is stored in/etc/ansible/hosts, and if the file does not exist, you can create the file. Of course, you can also execute the path to the manifest file when you execute the Ansible command. The format of the manifest file is similar to the INI file, as follows:








[Webserver]  192.168.1.1  192.168.1.2  [databaseserver]  192.168.1.10  192.168.1.11


The bracket symbol is the group name, the group name can be customized, but it is recommended to use a descriptive name, such as Webserver, Databaseserver, the group name is the member IP within each group. The following author executes a command on a remote server via Ansible:








Ansible webserver-a "WhoAmI"


From the execution results of Ansible, we know that the Ansible server's connectivity to the remote server is no problem and the execution of the command succeeds. If you want to specify the path to the manifest file, then use the –i parameter, plus the file path, as follows:








Ansible webserver–i/etc/ansible/other-hosts–a "WhoAmI"


The above is a AD-HOC command, that is, the temporary execution of the command. Ad-hoc is a concept in Ansible, using Ad-hoc You can quickly complete the operation of the command, if your operation contains only command operations, but not the content of configuration management, it is highly recommended to use AD-HOC commands, such as file transfer, package management, user and group management, Service management and so on.


Managing MySQL replication with Ansible



Ansible comes with a lot of modules, which Ansible called "Module libraries." The module can be executed directly on the remote server, or it can be executed via playbooks, and the playbooks will be described later. Ansible's modules are very rich, including cloud service management, files, databases, commands, networks and many other aspects. I am here to demonstrate the management of MySQL replication by Ansible one of the modules "Mysql_replication". First, configure the MySQL master server with the slave server's MySQL environment, make it meet the configuration requirements of MySQL replication, and MySQL master and slave server to install the Python mysqldb module, through Ansible on the master, slave server Install MYSQLDB.








Ansible databaseserver-m yum-a "Name=mysql-python state=present"


Create a MySQL replication account on the MySQL master server














mysql -uroot -p 
 mysql > GRANT REPLICATION SLAVE,REPLICATION CLIENT
  ON *.* TO ‘repl‘@‘192.168.1.%‘ IDENTIFIED BY ‘123456‘; 
 mysql > flush privileges; 
 mysql > quit;


On the MySQL master server, open the MySQL binary logging feature and add the following in the [Mysqld] section of the/etc/my.cnf file:



Server-id = 1



Log-bin=mysql-bin



Restart MySQL for the settings to take effect.








/etc/init.d/mysqld restart


Modify the MySQL configuration file for the MySQL slave database and add the following in the [Mysqld] section of the/etc/my.cnf file:



Server-id = 2



Restart MySQL for the settings to take effect.








/etc/init.d/mysqld restart


Get the status of the MySQL master server via the Ansible mysql_replication module














ansible mysql-master -m mysql_replication 
				 -a "login_user=root login_password=123456 mode=getmaster"


The results of Ansible are shown in JSON format, and the result is output of MySQL's used binary log file name and the value of Position, which is recorded for both values.



Specify the MySQL master server and set replication information on the MySQL Slave server via the Ansible mysql_replication module.














ansible mysql-slave -m mysql_replication 
				 – a "login_user=root login_password=123456 
 mode=changemaster master_host=‘172.16.64.147‘ master_user=repl 
 master_password=123456 master_log_file=mysql.000003 master_log_pos=711"


Start replication on MySQL from the server








Ansible mysql-slave-m mysql_replication-a "Login_user=root login_password=123456 mode=startslave"


View MySQL Replication Status








Ansible mysql-slave-m mysql_replication-a "Login_user=root login_password=123456 mode=getslave"


Note that the Red box selection in the figure shows that the values for slave_io_running and slave_sql_running are "Yes", and the Slave_io_state status is "Waiting for master to send event", This means that a copy of the MySQL master-slave server just established via ansible is normal. Now you can try to add some data to the MySQL master server to see if it will sync synchronously from the server.

Manage MySQL replication with Ansible playbooks


It is not easy to use module commands by using Ansible's Ad-hoc command-line directives, but we still have to do a lot of things manually, such as installing MySQL, configuring the MySQL replication environment, and so on. Although these can also be done through the Ad-hoc command line, but if I want to configure MySQL replication on other servers next time, then I have to repeat the instructions again, if so, then this will be the same very bad thing. So Ansible have a way to solve this problem? Of course there is, Ansible playbooks can be a good solution to this problem, playbooks translated into Chinese is the meaning of the script, as the name implies, is all the operation in accordance with the agreed rules in the document definition of what to do, and then play a big play according to the script. The playbooks is ideal for deploying complex applications and configuration reuse. The playbooks statement is configured and you set the configuration push to the specified remote host application. Playbooks is the same as Saltstack's SLS (Salt State Tree) and puppet configuration management.



Playbooks uses YAML format, which is simple to use in grammar. The following author uses Ansilbe to implement MySQL installation, MySQL replication environment configuration, MySQL replication settings.



In order to organize and manage the files in Ansible effectively, the author uses the roles feature of Ansible Playbook, which is valid in Ansible version 1.2 or later. In the/etc/ansible directory, the author established a roles directory for the playbooks definition of the various roles, this is the Ansible official definition of the default roles directory, of course, you can add or modify the roles directory path, by modifying the/etc/ans The Roles_path value in the Ible/ansible.cfg file. The roles directory is the directory name for each application, and the name can be customized by applying the name command, but it is best to set a meaningful name, as in this example the Mysql,mysql command includes defaults, handlers, meta, tasks, Templates, VARs directory, respectively, corresponding to different functions, the names of these directories are Ansible the official definition of the good, can not be modified, the description of the directory function is shown in table 1. The default Ansible only handles the actions defined in the file name main.yml in each directory, and if you have multiple files, you can include other files in the Main.yml file.


Table 1. Description of each directory function
Directory name Description
Defaults Default Variable Storage directory
Handlers Handlers (actions to be taken when a change occurs)
Meta Role dependency Processing
Tasks Task action definition for specific execution
Templates Template file storage Directory
VARs Variable file directory
MAIN.YML information for code 1.defaults directories












cat /etc/ansible/roles/mysql/defaults/main.yml 
 --- 
 mysql_port: 3306 
 mysql_bind_address: "0.0.0.0"
 mysql_root_db_pass: 123456 

 mysql_db: 
 - name: foo 
 replicate: yes 
 - name: bar 
 replicate: no 

 mysql_users: 
 - name: jack 
 pass: 123456 
 priv: "*.*:ALL"

 mysql_repl_user: 
 - name: repl 
 pass: 123456 

 mysql_repl_role: master 
 mysql_db_id: 7


This file contains some MySQL-related default variable information, where you set the MySQL port, the binding address, the root user's password, and the new database, user, replication user information.


MAIN.YML information for code 2.handlers directories






CAT/ETC/ANSIBLE/ROLES/MYSQL/HANDLERS/MAIN.YML  ---  -name:restart mysql  service:name={{mysql_service} } state=restarted


The main.yml file in the handlers directory contains operations that are available for invocation after the server changes after the tasks have been performed, in this case restarting the MySQL operation


MAIN.YML information in the Code 3.tasks directory






--- 
 - name: Add the OS specific variables 
 include_vars: "{{ ansible_os_family }}.yml"

 - name: Install the mysql packages in Redhat derivatives 
 yum: name={{ item }} state=installed 
 with_items: mysql_pkgs 
 when: ansible_os_family == ‘RedHat‘

 - name: Install the mysql packages in Debian derivatives 
 apt: name={{ item }} state=installed update_cache=yes 
 with_items: mysql_pkgs 
 environment: env 
 when: ansible_os_family == ‘Debian‘

 - name: Copy the my.cnf file 
 template: src=my.cnf.{{ ansible_os_family }}.j2 dest={{ mysql_conf_dir }}/my.cnf 
 notify: 
 - restart mysql 

 - name: Start the mysql services Redhat 
 service: name={{ mysql_service }} state=started enabled=yes 

 - name: update mysql root password for all root accounts 
 mysql_user: name=root host={{ item }} password={{ mysql_root_db_pass }} 
 with_items: 
 - "{{ ansible_hostname }}"
 - 127.0.0.1 
 - ::1 
 - localhost 
 when: ansible_hostname != ‘localhost‘ 

 - name: update mysql root password for all root accounts 
 mysql_user: name=root host={{ item }} password={{ mysql_root_db_pass }} 
 with_items: 
 - 127.0.0.1 
 - ::1 
 - localhost 
 when: ansible_hostname == ‘localhost‘ 


 - name: ensure anonymous users are not in the database 
 mysql_user: name=‘‘ host={{ item }} login_user=root
  login_password={{ mysql_root_db_pass }} state=absent 
 with_items: 
 - localhost 
 - "{{ ansible_hostname }}"

 - name: remove the test database 
 mysql_db: name=test login_user=root 
 login_password={{ mysql_root_db_pass }} state=absent 

 - name: Create the database‘s 
 mysql_db: name={{ item.name }} 
 login_user=root login_password={{ mysql_root_db_pass }} state=present 
 with_items: mysql_db 
 when: mysql_db|lower() != ‘none‘

 - name: Create the database users 
 mysql_user: login_user=root 
 login_password={{ mysql_root_db_pass }}
  name={{ item.name }} password={{ item.pass|default("foobar") }} 
 priv={{ item.priv|default("*.*:ALL") }} 
 state=present host={{ item.host | default("localhost") }} 
 with_items: mysql_users 
 when: mysql_users|lower() != ‘none‘

 - name: Create the replication users 
 mysql_user: login_user=root login_password={{ mysql_root_db_pass }} 
 name={{ item.name }} host="%" password={{ item.pass|default("foobar") }} 
 priv=*.*:"REPLICATION SLAVE" state=present 
 with_items: mysql_repl_user 
 when: mysql_repl_role == ‘master‘

 - name: Check if slave is already configured for replication 
 mysql_replication: login_user=root 
 login_password={{ mysql_root_db_pass }} mode=getslave 
 ignore_errors: true 
 register: slave 
 when: mysql_repl_role == ‘slave‘

 - name: Ensure the hostname entry 
 for master is available for the client. 
 lineinfile: dest=/etc/hosts regexp="{{ mysql_repl_master }}" 
 line="{{ mysql_repl_master + " " +
  hostvars[mysql_repl_master].ansible_default_ipv4.address }}"
   state=present 
 when: slave|failed and mysql_repl_role == ‘slave‘
  and mysql_repl_master is defined 

 - name: Get the current master servers replication status 
 mysql_replication: login_user=root login_password=
 {{ mysql_root_db_pass }} mode=getmaster 
 delegate_to: "{{ mysql_repl_master }}"
 register: repl_stat 
 when: slave|failed and mysql_repl_role == ‘slave‘ 
 and mysql_repl_master is defined 

 - name: Change the master in slave to start the replication 
 mysql_replication: login_user=root 
 login_password={{ mysql_root_db_pass }} mode=changemaster
  master_host={{ mysql_repl_master }}
   master_log_file={{ repl_stat.File }} 
   master_log_pos={{ repl_stat.Position }} 
   master_user={{ mysql_repl_user[0].name }} 
   master_password={{ mysql_repl_user[0].pass }} 
 when: slave|failed and mysql_repl_role == ‘slave‘
  and mysql_repl_master is defined 

 - name: start slave in slave to start the replication 
 mysql_replication: login_user=root login_password={{ mysql_root_db_pass }}
  mode=startslave 
 when: slave|failed and mysql_repl_role == ‘slave‘ 
 and mysql_repl_master is defined


The main.yml in the Tasks directory includes all the actions to be performed in Playbooks, each of which has a name for a simple description of the operation, and the tasks in this example include the following:


    • MySQL installation;
    • MySQL Administrator user root password modification;
    • MySQL configuration file generation;
    • Delete the test library;
    • Deletion of empty users;
    • Creation of the database (if necessary);
    • Creation and empowerment of database users (hardship required);
    • Copy user creation and password settings;
    • Gets the master state;
    • Slave Connect master and turn on replication.


Ansible playbooks Each task is executed sequentially, this can be seen Ansible playbooks execution process.


My.cnf.RedHat.j2 in the Code 4.templates directory












cat /etc/ansible/roles/mysql/templates/my.cnf.RedHat.j2 
 [mysqld] 
 datadir=/var/lib/mysql 
 socket=/var/lib/mysql/mysql.sock 
 user=mysql 
 # Disabling symbolic-links is recommended to 
 prevent assorted security risks 
 symbolic-links=0 
 port={{ mysql_port }} 
 bind-address={{ mysql_bind_address }} 
 log_bin = mysql-bin 
 server-id = {{ mysql_db_id }} 

 {% if mysql_repl_role == ‘master‘ %} 
 #log_bin = mysql-bin 
 expire_logs_days = 10 
 max_binlog_size = 100M 

 {% for i in mysql_db %} 
 {% if i.replicate|default(1) %} 
 binlog_do_db = {{ i.name }} 
 {% endif %} 
 {% endfor %} 

 {% for i in mysql_db %} 
 {% if not i.replicate|default(1) %} 
 binlog_ignore_db = {{ i.name }} 
 {% endif %} 
 {% endfor %} 
 {% endif %} 

 [mysqld_safe] 
 log-error=/var/log/mysqld.log 
 pid-file=/var/run/mysqld/mysqld.pid


A sample MySQL configuration file is included in the Templates directory.


Main.yml in the Code 5.vars directory






CAT/ETC/ANSIBLE/ROLES/MYSQL/VARS/MAIN.YML  ---  env:  runlevel:1
Redhat.yml in the Code 6.vars directory












cat /etc/ansible/roles/mysql/vars/RedHat.yml 
 --- 
 mysql_pkgs: 
 - libselinux-python 
 - mysql-server 
 - MySQL-python 

 mysql_service: mysqld 

 mysql_conf_dir: "/etc/"


The VARs directory is the variable information involved in this operation.


Code 7.ansible playbook configuration file to perform MySQL replication configuration mysql_repl.yml












cat /etc/ansible/mysql_repl.yml 
 - hosts: mysql-master 
 roles: 
 - {role: mysql, mysql_db: none,mysql_users: 
 [{name: jack, pass: 123456, priv: "*.*:ALL"}],mysql_db_id: 1008 } 

 - hosts: mysql-slave 
 roles: 
 - {role: mysql, mysql_db: none, 
 mysql_users: none,mysql_repl_role: slave,
  mysql_repl_master: 192.168.1.10,mysql_db_id:1009,
   mysql_repl_user: [{name: repl, pass: 123456}] }


Install and configure the MySQL server and complete the MySQL master-slave replication settings.



Adding server information in the/etc/ansible/hosts file














cat /etc/ansible/hosts 
 [mysql-master] 
 192.168.1.10 
 [mysql-slave] 
 192.168.1.11


Configuring MySQL replication with Ansible Playbook








ansible-playbook mysql_repl.yml 
 PLAY [mysql-master] *********************************************************** 

 GATHERING FACTS *************************************************************** 
 ok: [192.168.1.10] 

 TASK: [mysql | Add the OS specific variables] ********************************* 
 ok: [192.168.1.10] 

 TASK: [mysql | Install the mysql packages in Redhat derivatives] ************** 
 changed: [192.168.1.10] => (item=libselinux-python,mysql-server,MySQL-python) 

 TASK: [mysql | Install the mysql packages in Debian derivatives] ************** 
 skipping: [192.168.1.10] 

 TASK: [mysql | Copy the my.cnf file] ****************************************** 
 ok: [192.168.1.10] 

 TASK: [mysql | Start the mysql services Redhat] ******************************* 
 changed: [192.168.1.10] 

 TASK: [mysql | update mysql root password for all root accounts] ************** 
 changed: [192.168.1.10] => (item=client001) 
 changed: [192.168.1.10] => (item=127.0.0.1) 
 changed: [192.168.1.10] => (item=::1) 
 changed: [192.168.1.10] => (item=localhost) 

 TASK: [mysql | update mysql root password for all root accounts] ************** 
 skipping: [192.168.1.10] => (item=127.0.0.1) 
 skipping: [192.168.1.10] => (item=::1) 
 skipping: [192.168.1.10] => (item=localhost) 

 TASK: [mysql | ensure anonymous users are not in the database] **************** 
 changed: [192.168.1.10] => (item=localhost) 
 ok: [192.168.1.10] => (item=client001) 

 TASK: [mysql | remove the test database] ************************************** 
 changed: [192.168.1.10] 

 TASK: [mysql | Create the database‘s] ***************************************** 
 changed: [192.168.1.10] => (item={‘name‘: ‘benz‘}) 
 changed: [192.168.1.10] => (item={‘name‘: ‘benz2‘}) 

 TASK: [mysql | Create the database users] ************************************* 
 changed: [192.168.1.10] => (item={‘pass‘: ‘foobar‘, ‘name‘: ‘ben3‘, ‘priv‘: ‘*.*:ALL‘}) 
 changed: [192.168.1.10] => (item={‘name‘: ‘ben2‘, ‘pass‘: ‘foo‘}) 

 TASK: [mysql | Create the replication users] ********************************** 
 changed: [192.168.1.10] => (item={‘name‘: ‘repl‘, ‘pass‘: ‘foobar‘}) 

 TASK: [mysql | Check if slave is already configured for replication] ********** 
 skipping: [192.168.1.10] 

 TASK: [mysql | Ensure the hostname entry for master is available for the client.] *** 
 skipping: [192.168.1.10] 

 TASK: [mysql | Get the current master servers replication status] ************* 
 skipping: [192.168.1.10] 

 TASK: [mysql | Change the master in slave to start the replication] *********** 
 skipping: [192.168.1.10] 

 TASK: [mysql | start slave in slave to start the replication] ***************** 
 skipping: [192.168.1.10] 
 #### Limited to space, part of the output is omitted ####### 

 PLAY RECAP ******************************************************************** 
 192.168.1.10 : ok=12 changed=8 unreachable=0 failed=0 
 192.168.1.11 : ok=17 changed=8 unreachable=0 failed=0


When you look at the output, you'll see that the ansible task is executed sequentially, each of which displays the name and state of the task, which is a good way to see the status of the task execution. Then at the end of the task (that is, PLAY RECAP) is a summary of the status statistics for each task, including the execution of each task, such as the number of successful executions, the number of changes, and the number of errors. Here you can tell if the task completed successfully.




Comparison of Ansible and other configuration management


The author chooses the current several mainstream and Ansible function similar configuration management software Puppet, Saltstack, here The contrast does not target each software performance to compare, only to each software characteristic makes a contrast. The specific contents are shown in Table 1:


Table 2.Ansible vs. Puppet vs. Saltstack comparison
Puppet saltstack Ansible
Development language Ruby Python Python
Whether there is a client Yes Yes No
Two Development support Not supported Support Support
Whether the server and the remote machine authenticate each other Is Is Is
Whether the server communicates with the remote machine for encryption Yes, Standard SSL protocol Yes, use AES encryption Yes, use OpenSSH
Platform Support Supports AIX, BSD, HP-UX, Linux, MacOSX, Solaris, Windows Support for BSD, Linux, Mac OS X, Solaris, Windows Supports AIX, BSD, HP-UX, Linux, Mac OSX, Solaris
Whether to provide a Web UI Provide Provide Available, but commercial version
Configuration file format Ruby syntax format Yaml Yaml
Command line execution Not supported, but can be implemented by configuring the module Support Support



Conclusion:


Ansible is an emerging IT automation management tool. It now has more than 1 million downloads. On GitHub, it is the top 10 Python project. It can be foreseen that the development of Ansible is limitless. In this article, I use anaible to manage MySQL replication to introduce Ansible some usage methods and application scenarios, hoping that this article will allow everyone to fall in love with this super Energy system automation management tool.



Managing MySQL replication with Ansible


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.