MaxScale with MariaDB Replication in Docker containers
Introduction
When you setup a Galera Cluster or a Master Slave replication you will end up with multiple database containers, but for the applications there is only one database and they must be able to connect and work, independently from the database architecture.
To solve this we need MaxScale which provides a single access point to the database and also come up with other benefits like Load Balancing and Failover.
Let’s setup MaxScale in a Docker container and test its Failover functionalities.
Prerequisites
We need a MariaDB Master Slave replication cluster working in Docker containers.
For this we are going to use our Google Cloud Platform installation for MariaDB replication in Docker containers, please refer to MariaDB Master Slave in Docker Cointainers.
MaxScale Container
Build an Image
We are going to create our MaxScale image by using Ubuntu image, updating the OS, download/install the MaxScale software, expose the listeners ports and start the service.
First create a Dockerfile
like this:
FROM ubuntu
RUN apt update &&\
apt upgrade -y &&\
apt install -y vim nano net-tools iputils-ping wget
RUN wget https://downloads.mariadb.com/MaxScale/2.4.9/ubuntu/dists/bionic/main/binary-amd64/maxscale-2.4.9-1.ubuntu.bionic.x86_64.deb && \
dpkg -i maxscale-2.4.9-1.ubuntu.bionic.x86_64.deb; exit 0
RUN apt --fix-broken install -y
EXPOSE 4006 4008
CMD service maxscale start & tail -F /var/log/maxscale/maxscale.log
Then build
our image on the directory we created the Dockerfile
:
pato@patocontainer ~/maxscale $ docker build --tag patomx/patomaxscale .
...
Successfully built 35d1db931d60
Successfully tagged patomx/patomaxscale:latest
pato@patocontainer ~/maxscale $ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
patomx/patomaxscale latest 35d1db931d60 2 minutes ago 351MB
patomx/patomariadb latest 143534ffe233 5 days ago 453MB
Create the Container
Create the container patomaxmsr using our previously created image patomx/patomaxscale
and attach it to our network:
pato@patocontainer ~ $ docker run -d --name patomaxmsr --network pato-net patomx/patomaxscale
9c7cf7ee2093f84d38a653637f3da41a332eac84964e50f1ec94c1616a0ba058
pato@patocontainer ~ $
MaxScale Configuration
Create a Database User for MaxScale
Connect to the Master database and create the MaxScale monitor user maxpato user with the following privileges:
MariaDB [mysql]> GRANT SELECT ON mysql.* TO 'maxpato'@'%' IDENTIFIED BY '********';
Query OK, 0 rows affected (0.002 sec)
MariaDB [mysql]> GRANT SUPER, REPLICATION CLIENT, REPLICATION SLAVE, RELOAD, PROCESS, SHOW DATABASES, EVENT ON *.* TO 'maxpato'@'%';
Query OK, 0 rows affected (0.003 sec)
MariaDB [mysql]> flush privileges ;
Query OK, 0 rows affected (0.001 sec)
Create a Master-Slave Configuration File
On the docker container create a new file with the following parameters:
pato@patocontainer ~/maxscale $ nano maxscale-masterslave.cnf
- Define the host and port of the servers in the replication
[Pato-Master]
type=server
address=patomariadb
port=3306
protocol=MariaDBBackend
[Pato-Slave]
type=server
address=patomariarp
port=3306
protocol=MariaDBBackend
- Define the MaxScale monitor, using module
mariadbmon
as this is a Master-Slave replication.
Set the user and password for the monitoring user.
Setup the parameters for automaticFailover
andRejoin
[Pato-Monitor]
type=monitor
module=mariadbmon
servers=Pato-Master,Pato-Slave
user=maxpato
password=xxxxxxxx
monitor_interval=2000
auto_failover=true
auto_rejoin=true
- Define the Service for read write split between
Master
andSlave
listening onport 4006
.
[RW-Service]
type=service
router=readwritesplit
servers=Pato-Master,Pato-Slave
user=maxpato
password=********
[RW-Listener]
type=listener
service=RW-Service
protocol=MariaDBClient
port=4006
- Define the Service for the Command Line Interface
maxadmin
andmaxctrl
listening inlocalhost
port 6603
[CLI]
type=service
router=cli
[CLI-Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603
Load New Configuration
Copy the previous created file into our MaxScale container configuration /etc/maxscale.cnf
and restart the container so it can load the new configuration.
pato@patocontainer ~/maxscale $ docker cp maxscale-masterslave.cnf patomaxmsr:/etc/maxscale.cnf
pato@patocontainer ~/maxscale $ docker restart patomaxmsr
patomaxmsr
pato@patocontainer ~/maxscale $
Validate MaxScale is Running
Connect to MaxScale container and validate it is monitoring the configured databases by issuing the command maxadmin list servers
:
pato@patocontainer ~/maxscale $ docker exec -it patomaxmsr bash
root@9c7cf7ee2093:/# maxadmin -pmariadb list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server | Address | Port | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
Pato-Master | patomariadb | 3306 | 0 | Master, Running
Pato-Slave | patomariarp | 3306 | 0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------
and validate services are running and listening:
root@9c7cf7ee2093:/# maxadmin -pmariadb list listeners
Listeners.
---------------------+---------------------+--------------------+-----------------+-------+--------
Name | Service Name | Protocol Module | Address | Port | State
---------------------+---------------------+--------------------+-----------------+-------+--------
RW-Listener | RW-Service | MariaDBClient | :: | 4006 | Running
CLI-Listener | CLI | maxscaled | 127.0.0.1 | 6603 | Running
---------------------+---------------------+--------------------+-----------------+-------+--------
Connect to Database using MaxScale
As we have now our MaxScale running we no longer need to connect directly to the Master container.
For remote connections we need to point our client or application to the MaxScale container in port 4006
and activities balanced between Master
and Slave
:
$ mysql -u remoto -p -h patomaxmsr -P 4006
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
MariaDB [(none)]>
Automatic Functionalities
In our MaxScale configuration file we setup the options auto_failover
and auto_rejoin
:
auto_failover=true
auto_rejoin=true
With this options MaxScale will help our MariaDB Cluster to automate failover and rejoin activities whenever one node fails. Let’s test those functionalities.
Failover
We are going to stop the Master database to test the automatic failover:
pato@patocontainer ~/maxscale $ docker stop patomariadb
Master goes down and former Slave is promoted to Master role automatically. Check this by issuing the command maxctrl list servers
:
pato@patocontainer ~/maxscale $ docker exec -it --user maxscale patomaxmsr bash
maxscale@9c7cf7ee2093:/$ maxctrl list servers
+----------------------------------------------------------------------------+
¦ Server ¦ Address ¦ Port ¦ Connections ¦ State ¦ GTID ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Master ¦ patomariadb ¦ 3306 ¦ 0 ¦ Down ¦ 0-1-40 ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Slave ¦ patomariarp ¦ 3306 ¦ 0 ¦ Master, Running ¦ 0-11-44 ¦
+-------------+-------------+------+-------------+-----------------+---------+
note that GTID
is moving on the running node as all updates are performed in the new Master.
Availability
As we connect to the database through the MaxScale server, even if the instance patomariadb Pato-master
went down, the users can still work as the connections will be redirected transparently to the instance patomariarp Pato-Slave
:
$ mysql -u remoto -p -h patomaxmsr -P 4006
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 5
MariaDB [(none)]> select @@hostname;
+--------------+
| @@hostname |
+--------------+
| 4287cdea4dab |
+--------------+
1 row in set (0.000 sec)
Rejoin
When the server patomariadb is recovered it will automatically rejoin our replication cluster but this time with the Slave role. Check this by issuing the command maxctrl list servers
:
pato@patocontainer ~/maxscale $ docker start patomariadb
patomariadb
pato@patocontainer ~/maxscale $ docker exec -it patomaxmsr maxctrl list servers
+----------------------------------------------------------------------------+
¦ Server ¦ Address ¦ Port ¦ Connections ¦ State ¦ GTID ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Master ¦ patomariadb ¦ 3306 ¦ 0 ¦ Slave, Running ¦ 0-11-46 ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Slave ¦ patomariarp ¦ 3306 ¦ 0 ¦ Master, Running ¦ 0-11-46 ¦
+-------------+-------------+------+-------------+-----------------+---------+
Also we can see the global transaction id GTID
is again the same in both instances so they are in sync after Rejoin
.
Switchover
If everything is OK with the former Master server, we may need to Switchover the Master-Slave roles to the original ones.
For this we have to issue manually the command mariadbmon switchover
:
pato@patocontainer ~/maxscale $ docker exec -it --user maxscale patomaxmsr bash
maxscale@9c7cf7ee2093:/$ maxctrl call command mariadbmon switchover Pato-Monitor Pato-Master Pato-Slave -t 600000
OK
maxscale@9c7cf7ee2093:/$ maxctrl list servers
+---------------------------------------------------------------------------+
¦ Server ¦ Address ¦ Port ¦ Connections ¦ State ¦ GTID ¦
+-------------+-------------+------+-------------+-----------------+--------¦
¦ Pato-Master ¦ patomariadb ¦ 3306 ¦ 0 ¦ Master, Running ¦ 0-1-48 ¦
+-------------+-------------+------+-------------+-----------------+--------¦
¦ Pato-Slave ¦ patomariarp ¦ 3306 ¦ 0 ¦ Slave, Running ¦ 0-1-48 ¦
+-------------+-------------+------+-------------+-----------------+--------+
After role Switchover we can see the GTID
has changed from 0-11-#
to 0-1-#
(as patomariadb serverid is 1 and patomariarp serverid is 11).
Conclusion
We successfully installed MaxScale in a Docker container and configure it to monitor and control our Master Slave MariaDB cluster.
By connecting to MariaDB through MaxScale we ensure Availability by automating Failover activities when some node in our cluster fails, and also it help us with Load Balancing when all nodes are available.