Usa Ansible para automatizar la creación de una replicación Master - Slave en Mysql 8 en Ubunto - Debian
Cuando tienes una base de datos grande y con bastante tráfico y quieres mejorar el rendimiento (sea para realizar backups, para realizar análisis de tus datos o mejorar el tiempo de respuesta), llega un momento en el que el escalado vertical (aumentar las prestaciones de la máquina) no te va a funcionar. Tienes que irte al escalado horizontal (meter más máquinas "clon" en el mismo nivel).
La opción que vamos a ver hoy es la de replicación mysql en modo Master - Slave. Vamos a tener un servidor mysql master (nuestr aplicación por ejemplo) y otro servidor mysql slave en otra máquina que será una réplica del master donde podemos ejecutar los backups y consultas.
Configurarlo es bastante sencillo y lo vamos a mejorar aún porque lo vamos a integrar con Ansible y así ya lo tenemos automatizado! (claramente no voy a escribir los roles de ansible ya que sería una duplicación de código de las tareas. Te diré los pasos manuales y algunos comandos Ansible para que te lo puedas montar tú mismo :P).
Replicación Master - Slave
Supongamos que tenemos estas dos máquinas:
- Servidor mysql master: 192.168.100.1
- Servidor mysql slave: 192.168.100.2
- Tenemos instalada el componente community.mysql de Ansible
Los pasos generales serían:
- Instala en ambas máquinas mysql:
# Suponiendo que es un ubuntu sudo apt install mysql-client mysql-server mysql-common
- Si estás en Debian, debes añadir el repositorio o el paquete directamente si quieres. Aquí te lo dejo!
- En ambas máquinas, configura mysql para que "escuche" peticiones del exterior:
- Para ello modifica el fichero mysqld.conf
# Suponiendo que estamos en el mysql master #SIN ESPACIOS DESPUÉS DE LA , bind-address = 127.0.0.1,192.168.100.1
- Reinicia mysql para aplicar los cambios
- Vamos a la máquina "master" para crear un usuario con rol "replication slave" para poder acceder a ella desde el servidor slave:
- En este caso te dejo una porción de Ansible para que lo tengas como base!
# Crea un usuario usarndo las variables que tienes en el rol - name: Creating default {{ default_slave_user_on_master }} user on Mysql master server mysql_user: name: "{{ default_slave_user_on_master }}" password: "{{ default_slave_paassword_master }}" host: "{{ default_slave_host }}" priv: "*.*:replication slave,GRANT" login_host : "{{ master_db_host }}" login_port: "{{ master_db_port }}" login_user: "{{ master_db_user }}" login_password: "{{ master_db_password }}" state: present
- Como ya te había comentado, mysql ya crea unos certificados ssl propios que ya nos sirven perfectamente para poder acceder desde cualquier sitio. Los vamos a descargar a nuestro equipo (o directamente los podríamos copiar en la máquina slave directamente!)
- Por defecto están en /var/lib/mysql
- Nos descargamos: ca.pem, client-cert.pem y client-key.pem
- Nos vamos ahora a la máquina slave. Lo que haremos será subir los SSL del master y configurar la replicación:
- Subimos los ssl nuestra máquina. Yo los subo a un directorio diferente para tenerlo organizado. Te dejo otros comandos Ansible para que los de refencia :)
- name: Create Master ssl certs ansible.builtin.file: path: "{{ mysql_master_ssl_certs_dir }}" owner: mysql group: mysql recurse: yes mode: '0750' - name: Upload Master ca cert ansible.builtin.copy: src: "{{ local_master_ssl_certs_dir }}/ca.pem" dest: "{{ mysql_master_ssl_certs_dir }}/ca.pem" owner: mysql group: mysql mode: '0644' - name: Upload Master client cert ansible.builtin.copy: src: "{{ local_master_ssl_certs_dir }}/client-cert.pem" dest: "{{ mysql_master_ssl_certs_dir }}/client-cert.pem" owner: mysql group: mysql mode: '0644' - name: Upload Master client key ansible.builtin.copy: src: "{{ local_master_ssl_certs_dir }}/client-key.pem" dest: "{{ mysql_master_ssl_certs_dir }}/client-key.pem" owner: mysql group: mysql mode: '0644'
- Ahora debemos configurar la replicación y el método de replicación. En mi caso lo que quiero es comenzar la replicación entonces usaré la opción "CHANGE MASTER TO". Sería:
# Dentro de mysql CHANGE MASTER TO MASTER_HOST='192.168.100.1', MASTER_USER='usuario_creado_en_master_slave', MASTER_PASSWORD='pass_creada_en_master_slave', MASTER_LOG_FILE='mysql-bin.[numero_bin], MASTER_LOG_POS=[POSICION], SOURCE_SSL_CA="path/ca.pem", SOURCE_SSL_CAPATH = 'path/nuevos_certs', SOURCE_SSL_CERT = 'path/client-cert.pem', SOURCE_SSL_KEY = 'path/client-key.pem', MASTER_SSL=1;
- Reinicia el servidor mysql esclavo y listo!!
- Para comprobar que están funcionando muy sencillo. Accede al master y ejecuta un insert y comprueba en el el slave se ha ejecutado el mismo insert