sql >> Base de Datos >  >> RDS >> MariaDB

Una introducción a la implementación de MySQL usando un rol de Ansible

Ansible automatiza y simplifica las operaciones repetitivas, complejas y tediosas. Es un motor de automatización de TI que automatiza el aprovisionamiento en la nube, la gestión de la configuración, la implementación de aplicaciones, la orquestación dentro del servicio y muchas otras necesidades de TI. No requiere agentes, usa solo SSH para enviar cambios desde una sola fuente a múltiples recursos remotos sin configuración de infraestructura de seguridad personalizada adicional y usa un formato de lenguaje simple (YAML) para describir los trabajos de automatización.

Instalar un servidor MySQL independiente es una tarea simple y directa, pero esto puede ser problemático si tiene varios servidores de bases de datos, versiones, plataformas y entornos para admitir. Por lo tanto, tener una herramienta de gestión de la configuración es el camino a seguir para mejorar la eficiencia, eliminar la repetitividad y reducir los errores humanos.

En esta publicación de blog, lo guiaremos a través de los conceptos básicos de la automatización de Ansible para MySQL, así como la administración de la configuración con ejemplos y explicaciones. Comenzaremos con una implementación de MySQL independiente simple, como se ilustra en el siguiente diagrama de alto nivel:

Instalación de Ansible

Para este tutorial, necesitamos tener al menos dos hosts:un host es para Ansible (podría usar una estación de trabajo en lugar de un servidor) y otro es el host de destino en el que queremos implementar un servidor mysql

Para instalar Ansible en CentOS 7, simplemente ejecute los siguientes comandos:

(ansible-host)$ yum install -y epel-release

(ansible-host)$ yum install -y ansible

Para otras distribuciones de SO, consulte la guía de instalación de Ansible.

Configuración de SSH sin contraseña

Se admite el uso de contraseña durante SSH, pero las claves SSH sin contraseña con ssh-agent son una de las mejores formas de usar Ansible. El paso inicial es configurar SSH sin contraseña ya que Ansible realizará la implementación únicamente por este canal. En primer lugar, genere una clave SSH en el host de Ansible:

(ansible-host)$ whoami

root

(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa

Debe generar al menos los siguientes archivos:

(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

Para permitir SSH sin contraseña, necesitamos copiar la clave pública SSH (id_rsa.pub) al host remoto al que queremos acceder. Podemos usar una herramienta llamada ssh-copy-id para hacer esta tarea por nosotros. Sin embargo, debe conocer la contraseña de usuario del host de destino y la autenticación de contraseña está permitida en el host de destino:

(ansible-host)$ whoami

root

(ansible-host)$ ssh-copy-id [email protected]

El comando anterior solicitará la contraseña raíz 192.168.0.221, simplemente ingrese la contraseña y la clave SSH para el usuario actual del host Ansible se copiará en el host de destino, 192.168.0.221 en ~/.ssh/authorized_keys, lo que significa que autorizamos esa clave en particular para acceder a este servidor de forma remota. Para probar, debería poder ejecutar el siguiente comando remoto sin ninguna contraseña desde el host de Ansible:

(ansible-host)$ ssh [email protected] "hostname -I"

192.168.0.221

En caso de que no tenga permitido usar el usuario root para SSH (por ejemplo, "PermitRootLogin no" en la configuración de SSH), puede usar un usuario sudo en su lugar. En el siguiente ejemplo, configuramos SSH sin contraseña para un usuario sudo llamado "vagabundo":

(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]

Si el servidor de destino no permite la autenticación de contraseña a través de SSH, simplemente copie el contenido de la clave pública SSH en ~/.ssh/id_rsa.pub manualmente en el servidor de destino ~/.ssh/authorized_keys expediente. Por ejemplo, en el host de Ansible, recupere el contenido de la clave pública:

(ansible-host)$ cat ~/.ssh/id_rsa.pub

ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]

Conéctese al host de destino y pegue la clave pública del host de Ansible en ~/.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]

Ahora puede intentar ejecutar un comando remoto desde el host de Ansible para verificar y no se le debe solicitar ninguna contraseña. En este punto, nuestro SSH sin contraseña está configurado.

Definición del host de destino

A continuación, debemos definir el host de destino, el host que queremos administrar con Ansible. Según nuestra arquitectura, implementaremos solo un servidor MySQL que es 192.168.0.221. Agregue las siguientes líneas en /etc/ansible/hosts:

[db-mysql]

192.168.0.221

Lo anterior simplemente significa que definimos un grupo llamado "db-mysql", que será el identificador cuando nos referimos al host de destino en el libro de jugadas de Ansible. También podemos enumerar todas las direcciones IP o nombres de host de los hosts de destino en este grupo. En este punto, solo tenemos un servidor MySQL para implementar, por lo tanto, solo hay una entrada. También puede especificar cualquier regla de coincidencia para hacer coincidir los hosts de un grupo, por ejemplo:

[db-mysql]

192.168.0.[221:223]

La definición anterior significa que tenemos 3 hosts en este mismo grupo con las siguientes direcciones IP:

  • 192.168.0.221
  • 192.168.0.222
  • 192.168.0.223

Hay muchas formas y reglas para hacer coincidir y agrupar los hosts de destino, como se muestra en la guía de inventario de Ansible.

Elegir un rol de Ansible

Para decirle a Ansible qué implementar, debemos definir los pasos de implementación en un archivo con formato YML llamado playbook. Como sabrá, la instalación de un servidor MySQL completo requiere varios pasos para satisfacer todas las dependencias de MySQL, la configuración posterior a la instalación, la creación de usuarios y esquemas, etc. Ansible ha proporcionado una serie de módulos de MySQL que pueden ayudarnos, pero aún tenemos que escribir un libro de jugadas para los pasos de implementación.

Para simplificar los pasos de implementación, podemos usar roles de Ansible existentes. El rol de Ansible es un componente independiente que permite la reutilización de pasos de configuración comunes. Se debe usar un rol de Ansible dentro del libro de jugadas. Hay una serie de roles de MySQL Ansible disponibles en Ansible Galaxy, un repositorio para los roles de Ansible que están disponibles para colocarlos directamente en sus playbooks.

Si busca "mysql", obtendrá muchos roles de Ansible para MySQL:

Usaremos el más popular llamado "mysql" por geerlingguy. Puede optar por usar otras funciones, pero la mayoría de las veces, la más descargada tiende a ser de uso general, lo que generalmente funciona bien en la mayoría de los casos.

En el host de Ansible, ejecute el siguiente comando para descargar la función de Ansible:

(ansible-host)$ ansible-galaxy install geerlingguy.mysql

El rol se descargará en ~/.ansible/roles/geerlingguy.mysql/ del usuario actual.

Escribir el libro de jugadas de Ansible

Al consultar el archivo Léame de la función de Ansible, podemos seguir el manual de estrategias de ejemplo que se proporciona. En primer lugar, cree un archivo de guía llamado deployment-mysql.yml y agregue las siguientes líneas:

(ansible-host)$ vim ~/deploy-mysql.yml

- hosts: db-mysql

  become: yes

  vars_files:

    - vars/main.yml

  roles:

    - { role: geerlingguy.mysql }

En las líneas anteriores, definimos el host de destino, que son todos los hosts bajo las entradas de db-mysql en /etc/ansible/hosts. La siguiente línea (convertirse) le dice a Ansible que ejecute el libro de jugadas como usuario raíz, lo cual es necesario para el rol (se indica allí en el archivo Léame). A continuación, definimos la ubicación del archivo de variables (var_files) ubicado en vars/main.yml, en relación con la ruta del libro de jugadas.

Vamos a crear el directorio y archivo de variables y especificar la siguiente línea:

(ansible-host)$ mkdir vars

(ansible-host)$ vim vars/main.yml

mysql_root_password: "theR00tP455w0rd"

Para obtener más información, consulte la sección Variables del rol en el archivo Léame de este rol.

Iniciar la implementación

Ahora estamos listos para iniciar la implementación de MySQL. Use el comando ansible-playbook para ejecutar nuestras definiciones de libro de jugadas:

(ansible-host)$ ansible-playbook deploy-mysql.yml

Debería ver aparecer un montón de líneas en la salida. Concéntrese en la última línea donde resume la implementación:

PLAY RECAP ***************************************************************************************************************************************

192.168.0.221              : ok=36 changed=8 unreachable=0    failed=0 skipped=16 rescued=0 ignored=0

Si todo se vuelve verde y está bien, puede verificar en el host de la base de datos que nuestro servidor MySQL ya está instalado y ejecutándose:

(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

Como puede ver en lo anterior, para CentOS 7, la instalación predeterminada de MySQL es MariaDB 5.5 como parte del repositorio de paquetes estándar. En este punto, nuestra implementación se considera completa; sin embargo, nos gustaría personalizar aún más nuestra implementación como se muestra en las siguientes secciones.

Personalización de la implementación

La definición más simple en el libro de jugadas nos brinda una instalación muy básica y usa todas las opciones de configuración predeterminadas. Podemos personalizar aún más la instalación de MySQL extendiendo/modificando/agregando el libro de jugadas para hacer lo siguiente:

  • modificar las opciones de configuración de MySQL
  • añadir usuario de base de datos
  • añadir esquema de base de datos
  • configurar privilegios de usuario
  • configurar la replicación de MySQL
  • instalar MySQL de otros proveedores
  • importar un archivo de configuración de MySQL personalizado

Instalación de MySQL desde el repositorio de Oracle

De forma predeterminada, la función instalará el paquete MySQL predeterminado que viene con la distribución del sistema operativo. En cuanto a CentOS 7, tendría instalado MariaDB 5.5 de forma predeterminada. Supongamos que queremos instalar MySQL de otro proveedor, podemos extender el playbook con pre_tasks, una tarea que Ansible ejecuta antes de ejecutar cualquier tarea mencionada en cualquier archivo .yml, como se muestra en el siguiente ejemplo:

(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"

Ejecutar el libro de jugadas:

(ansible-host)$ ansible-playbook deploy-mysql.yml

Lo anterior instalará MySQL desde el repositorio de Oracle en su lugar. La versión predeterminada que obtendría es MySQL 5.6. Ejecutar el libro de jugadas anterior en un host de destino que ya tiene una versión anterior de MySQL/MariaDB en ejecución probablemente fallaría debido a la incompatibilidad.

Creación de bases de datos y usuarios MySQL

Dentro de vars/main.yml, podemos definir la base de datos MySQL y los usuarios que queremos que Ansible configure en nuestro servidor MySQL usando los módulos mysql_database y mysql_users, justo después de nuestra definición anterior en 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"

La definición le indica a Ansible que cree dos bases de datos, "myshop" y "sysbench", seguido de su respectivo usuario de MySQL con los privilegios adecuados, host permitido y contraseña.

Vuelva a ejecutar el libro de jugadas para aplicar el cambio en nuestro servidor MySQL:

(ansible-host)$ ansible-playbook deploy-mysql.yml

Esta vez, Ansible recogerá todos los cambios que hicimos en vars/main.yml para aplicarlos a nuestro servidor MySQL. Podemos verificar en el servidor MySQL con los siguientes comandos:

(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.%'                                                  |

+------------------------------------------------------------------------------------------------------------------------+

Habilitación del registro de consultas lentas

Este rol admite habilitar el registro de consultas lentas de MySQL, podemos definir la ubicación del archivo de registro, así como el tiempo de consulta lenta. Agregue las variables necesarias dentro del archivo 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'

Vuelva a ejecutar el libro de jugadas para aplicar los cambios:

(ansible-host)$ ansible-playbook deploy-mysql.yml

El libro de jugadas realizará los cambios necesarios en las opciones relacionadas con la consulta lenta de MySQL y reiniciará el servidor MySQL automáticamente para cargar las nuevas configuraciones. Entonces podemos verificar si las nuevas opciones de configuración se cargan correctamente en el servidor 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 |

+------------------+-----------------------+-------------------+

Incluyendo archivo de configuración de MySQL personalizado

Las variables de rol de Ansible y las variables de MySQL son dos cosas diferentes. El autor de este rol ha creado una serie de variables relacionadas con MySQL que se pueden representar con variables de roles de Ansible. Tomados del archivo Léame, estos son algunos de ellos:

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*

Si la configuración generada no cumple con nuestro requisito de MySQL, podemos incluir archivos de configuración de MySQL personalizados en la implementación usando la variable mysql_config_include_files. Acepta una matriz de valores separados por una coma, con un "src" como prefijo para la ruta real en el host de Ansible.

En primer lugar, tenemos que preparar los archivos de configuración personalizados en el host de Ansible. Cree un directorio y un archivo de configuración simple de 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

Digamos que tenemos otro archivo de configuración específicamente para la configuración de mysqldump:

(ansible-host)$ vim /root/custom-config/mysqldump.cnf

[mysqldump]

max_allowed_packet=128M

Para importar estos archivos de configuración a nuestra implementación, defínalos en la matriz mysql_config_include_files en el archivo 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'

]

Tenga en cuenta que /root/custom-config/mysqld-severalnines.cnf y /root/custom-config/mysqldump.cnf existen dentro del host de Ansible.

Vuelva a ejecutar el libro de jugadas:

(ansible-host)$ ansible-playbook deploy-mysql.yml

El libro de jugadas importará esos archivos de configuración y los colocará en el directorio de inclusión (dependiendo del sistema operativo) que es /etc/my.cnf.d/ para CentOS 7. El libro de jugadas reiniciará automáticamente el Servidor MySQL para cargar las nuevas opciones de configuración. Entonces podemos verificar si las nuevas opciones de configuración se cargan correctamente:

(mysql-host)$ mysql -uroot -p -e 'select @@max_connections'

250

(mysql-host)$ mysqldump --help | grep ^max-allowed-packet

max-allowed-packet                134217728

Conclusión

Ansible se puede utilizar para automatizar la implementación de la base de datos y la gestión de la configuración con un poco de conocimiento de secuencias de comandos. Mientras tanto, ClusterControl utiliza un enfoque SSH sin contraseña similar para implementar, monitorear, administrar y escalar su clúster de base de datos de la A a la Z, con una interfaz de usuario y no necesita habilidades adicionales para lograr el mismo resultado.