Automate
MariaDB Galera clusters
deployments with Ansible
How To and Best Practices
Federico Razzoli
$ whoami
Hi, I’m Federico Razzoli from Vettabase Ltd
Database consultant, open source supporter,
long time MariaDB and MySQL user.
● vettabase.com
● Federico-Razzoli.com
MariaDB KB
Vettabase is a MariaDB Foundation technology partner that contributes contents to
the MariaDB KnowledgeBase:
Automated MariaDB Deployment and Administration
https://mariadb.com/kb/en/automated-mariadb-deployment-and-administration/
Examples
Examples from this talk are from:
github.com/Vettabase/ansible-mariadb-cluster-example
● It is a working example
● We install everything you need in a real-life server
● It is based on Vettabase recommendations / my opinions
● In this talk we'll only have the time to explain some general ideas and some
highlights
Inventories and Plays
General structure
● We have two inventories:
○ production
○ staging
Inventories look like this:
[pmm]
pmm-1 ansible_host=pmm-host
[mariadb_1]
mariadb-main-1-1 ansible_host=100.200.111.1
mariadb-main-1-2 ansible_host=100.200.111.2
mariadb-main-1-3 ansible_host=100.200.111.3
[mariadb_1:vars]
pmm_server_host=pmm_host
pmm_server_port=80
Play (db.yml)
---
- hosts: pmm
roles:
- pmm-server
- hosts: mariadb_1
roles:
- role: mariadb-galera-complete
Roles
The metarole
● mariadb-galera-complete is a metarole that "includes":
○ linux-for-mariadb
○ chrony
○ mariadb-galera
○ mariadb-permissions
○ mydumper
○ pmm-client
○ cronjobs
● It actually depends on them, see
roles/mariadb-galera-complete/meta/main.yml
Base-roles
● linux-for-mariadb: Configure Linux for MariaDB
● chrony: NTP client because of cluster and monitoring
● mariadb-galera
● mariadb-permissions: Set permissions, not necessarily bound to
mariadb-galera
● mydumper: Backups, could run on a stand-alone server
● pmm-client: Monitoring
● cronjobs: It's convenient to have them in a separate role
Some highlights
From linux-for-mariadb
- name: Open some ports to the world
tags: [ linux-for-mariadb, iptables ]
iptables:
chain: "{{ item[1] }}"
protocol: "{{ item[0].protocol }}"
match: "{{ item[0].protocol }}"
destination_port: "{{ item[0].port }}"
jump: ACCEPT
with_nested:
- "{{ world_allowed_ports }}"
- "{{ chains }}"
From linux-for-mariadb
defaults/main.yml:
world_allowed_ports:
- { port: '3306', protocol: 'tcp' } # MariaDB native protocol
- { port: '4567', protocol: 'tcp' } # Galera replication
- { port: '4567', protocol: 'udp' } # Galera replication
- { port: '4444', protocol: 'tcp' } # Galera SST
- { port: '4568', protocol: 'tcp' } # Galera IST
kernel_parameters:
- { key: 'vm.swappiness', value: '0' }
mariadb-galera: validate variables
main.yml:
- name: Include validate.yml
tags: [ mariadb-galera, mariadb-galera-validate ]
include: validate.yml
validate.yml:
- name: Validate cluster IPs
assert:
that: cluster_hosts|length > 0
fail_msg: cluster_hosts must contain at least 1 element
success_msg: "cluster_hosts size: {{ cluster_hosts|length }}"
mariadb-galera: delete datadir
- name: Include clean.yml
tags: [ mariadb-galera, mariadb-galera-clean ]
include: clean.yml
when: db_init is defined and db_init == '1'
Nodes info
cluster_name: mysql_prod_1
cluster_hosts:
- { "node_name": "mariadb-main-1-1", " public_ip": "...", "private_ip":
"..." }
- { "node_name": "mariadb-main-1-2", " public_ip": "...", "private_ip":
"..." }
- { "node_name": "mariadb-main-1-3", " public_ip": "...", "private_ip":
"..." }
private_ips:
- ...
- ...
- ...
mariadb-galera: bootstrap cluster
- name: Copy wsrep.cnf to the first node
tags: [ mariadb-galera ]
template:
src="./templates/wsrep/default.cnf.j2"
dest=/etc/mysql/include/wsrep.cnf
when:
- inventory_hostname == cluster_hosts[0].node_name
- cluster_hosts|length > 1
● The file we're copying only contains wsrep_cluster_address= local node
● Yes, we could use --wsrep-new-cluster but I expect this method to work with:
○ any old MariaDB version
○ any MariaDB/MySQL variant that includes Galera
mariadb-permissions
● Permissions are defined in files:
○ roles/mariadb-permissions/groups/<group_name>.sql.j2
○ roles/mariadb-permissions/hosts/<host_name>.sql.j2
● Groups are logical groups of permissions
● We prefer to directly write SQL statements for this
cronjobs
● The cronjobs role:
○ Creates jobs declared in cronjob_set
○ Uploads scripts used in cronjobs
○ Creates any needed directory
● All cronjobs in a central place, because you need to coordinate them
● All cronjobs call scripts
○ Eg: db-dump.sh and db-dump-restore.sh
○ Because even when you need to perform these operations manually, you still want to automate
them as much as possible
Thanks for attending!
github.com/Vettabase/ansible-mariadb-cluster-example

Automate MariaDB Galera clusters deployments with Ansible

  • 1.
    Automate MariaDB Galera clusters deploymentswith Ansible How To and Best Practices Federico Razzoli
  • 2.
    $ whoami Hi, I’mFederico Razzoli from Vettabase Ltd Database consultant, open source supporter, long time MariaDB and MySQL user. ● vettabase.com ● Federico-Razzoli.com
  • 3.
    MariaDB KB Vettabase isa MariaDB Foundation technology partner that contributes contents to the MariaDB KnowledgeBase: Automated MariaDB Deployment and Administration https://mariadb.com/kb/en/automated-mariadb-deployment-and-administration/
  • 4.
    Examples Examples from thistalk are from: github.com/Vettabase/ansible-mariadb-cluster-example ● It is a working example ● We install everything you need in a real-life server ● It is based on Vettabase recommendations / my opinions ● In this talk we'll only have the time to explain some general ideas and some highlights
  • 5.
  • 6.
    General structure ● Wehave two inventories: ○ production ○ staging
  • 7.
    Inventories look likethis: [pmm] pmm-1 ansible_host=pmm-host [mariadb_1] mariadb-main-1-1 ansible_host=100.200.111.1 mariadb-main-1-2 ansible_host=100.200.111.2 mariadb-main-1-3 ansible_host=100.200.111.3 [mariadb_1:vars] pmm_server_host=pmm_host pmm_server_port=80
  • 8.
    Play (db.yml) --- - hosts:pmm roles: - pmm-server - hosts: mariadb_1 roles: - role: mariadb-galera-complete
  • 9.
  • 10.
    The metarole ● mariadb-galera-completeis a metarole that "includes": ○ linux-for-mariadb ○ chrony ○ mariadb-galera ○ mariadb-permissions ○ mydumper ○ pmm-client ○ cronjobs ● It actually depends on them, see roles/mariadb-galera-complete/meta/main.yml
  • 11.
    Base-roles ● linux-for-mariadb: ConfigureLinux for MariaDB ● chrony: NTP client because of cluster and monitoring ● mariadb-galera ● mariadb-permissions: Set permissions, not necessarily bound to mariadb-galera ● mydumper: Backups, could run on a stand-alone server ● pmm-client: Monitoring ● cronjobs: It's convenient to have them in a separate role
  • 12.
  • 13.
    From linux-for-mariadb - name:Open some ports to the world tags: [ linux-for-mariadb, iptables ] iptables: chain: "{{ item[1] }}" protocol: "{{ item[0].protocol }}" match: "{{ item[0].protocol }}" destination_port: "{{ item[0].port }}" jump: ACCEPT with_nested: - "{{ world_allowed_ports }}" - "{{ chains }}"
  • 14.
    From linux-for-mariadb defaults/main.yml: world_allowed_ports: - {port: '3306', protocol: 'tcp' } # MariaDB native protocol - { port: '4567', protocol: 'tcp' } # Galera replication - { port: '4567', protocol: 'udp' } # Galera replication - { port: '4444', protocol: 'tcp' } # Galera SST - { port: '4568', protocol: 'tcp' } # Galera IST kernel_parameters: - { key: 'vm.swappiness', value: '0' }
  • 15.
    mariadb-galera: validate variables main.yml: -name: Include validate.yml tags: [ mariadb-galera, mariadb-galera-validate ] include: validate.yml validate.yml: - name: Validate cluster IPs assert: that: cluster_hosts|length > 0 fail_msg: cluster_hosts must contain at least 1 element success_msg: "cluster_hosts size: {{ cluster_hosts|length }}"
  • 16.
    mariadb-galera: delete datadir -name: Include clean.yml tags: [ mariadb-galera, mariadb-galera-clean ] include: clean.yml when: db_init is defined and db_init == '1'
  • 17.
    Nodes info cluster_name: mysql_prod_1 cluster_hosts: -{ "node_name": "mariadb-main-1-1", " public_ip": "...", "private_ip": "..." } - { "node_name": "mariadb-main-1-2", " public_ip": "...", "private_ip": "..." } - { "node_name": "mariadb-main-1-3", " public_ip": "...", "private_ip": "..." } private_ips: - ... - ... - ...
  • 18.
    mariadb-galera: bootstrap cluster -name: Copy wsrep.cnf to the first node tags: [ mariadb-galera ] template: src="./templates/wsrep/default.cnf.j2" dest=/etc/mysql/include/wsrep.cnf when: - inventory_hostname == cluster_hosts[0].node_name - cluster_hosts|length > 1 ● The file we're copying only contains wsrep_cluster_address= local node ● Yes, we could use --wsrep-new-cluster but I expect this method to work with: ○ any old MariaDB version ○ any MariaDB/MySQL variant that includes Galera
  • 19.
    mariadb-permissions ● Permissions aredefined in files: ○ roles/mariadb-permissions/groups/<group_name>.sql.j2 ○ roles/mariadb-permissions/hosts/<host_name>.sql.j2 ● Groups are logical groups of permissions ● We prefer to directly write SQL statements for this
  • 20.
    cronjobs ● The cronjobsrole: ○ Creates jobs declared in cronjob_set ○ Uploads scripts used in cronjobs ○ Creates any needed directory ● All cronjobs in a central place, because you need to coordinate them ● All cronjobs call scripts ○ Eg: db-dump.sh and db-dump-restore.sh ○ Because even when you need to perform these operations manually, you still want to automate them as much as possible
  • 21.