Blog | Pythian

Building a MariaDB Galera Cluster with Docker

Written by Pythian Marketing | Aug 28, 2014 4:00:00 AM

There’s been a lot of talk about Docker for running processes in isolated userspace (or the cloud for that matter) lately. Virtualization is a great way to compartmentalize applications and processes; however, the overhead of virtualization isn’t always worth it—in fact, without directly attached storage, IO degradation can seriously impact performance.

The solution? Perhaps Docker… With its easy-to-use CLI as well as the lightweight implementation of cgroups and kernel namespaces.

Without further ado, I present a step-by-step guide on how to build a MariaDB 5.5 Galera Cluster on Ubuntu 14.04. The same guide can probably be applied for MariaDB versions 10+; however, I’ve stuck with 5.5 since the latest version of MariaDB Galera Cluster is still in beta.

1. Preparing the Host Environment

We start off by modifying the ufw firewall policy to accept forwarded packets and perform a service restart for good measure:

root@workstation:~# vi /etc/default/ufw # Set DEFAULT_FORWARD_POLICY="ACCEPT"  root@workstation:~# service ufw restart ufw stop/waiting ufw start/running 

Installing Requirements and Pulling Base Images

I’m assuming you already have Docker installed—this is available as a package within the Ubuntu repositories and also available in the Docker repositories. You’ll also need to have LXC installed (apt-get install lxc should suffice) in order to attach to the Linux Containers / Docker Images.

The next step is pulling the Docker / Ubuntu repository in order to customize an image for our purposes:

root@workstation:~# docker pull ubuntu # ... (Download layers) ... Pulling repository ubuntu c4ff7513909d: Pulling dependent layers  3db9c44f4520: Download complete  # ... cc58e55aa5a5: Download complete 

After the download is complete, we can check the Ubuntu images available for customization with the following command:

root@workstation:~# docker images  REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE  ubuntu              14.04.1             c4ff7513909d        12 days ago         225.4 MB  ubuntu              trusty              c4ff7513909d        12 days ago         225.4 MB  # ... 

2. Creating the MariaDB Galera Docker Image

Now that we’ve downloaded our images, let's create a custom Dockerfile for our customized MariaDB / Galera Docker image. I’ve added a brief description for each line of the file:

root@workstation:~# vi Dockerfile  # MariaDB Galera 5.5.39/Ubuntu 14.04 64bit  FROM ubuntu:14.04  MAINTAINER Pythian Nikolaos Vyzas <vyzas@pythian.com>   # add the universe repo  RUN echo "deb https://archive.ubuntu.com/ubuntu trusty main universe" > /etc/apt/sources.list   # update apt  RUN apt-get -q -y update   # install software-properties-common for key management  RUN apt-get -q -y install software-properties-common   # add the key for Mariadb Ubuntu repos  RUN apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xcbcb082a1bb943db   # add the MariaDB repository for 5.5  RUN add-apt-repository 'deb https://ftp.cc.uoc.gr/mirrors/mariadb/repo/5.5/ubuntu trusty main'   # update apt again  RUN apt-get -q -y update   # configure the default root password during installation  RUN echo mariadb-galera-server-5.5 mysql-server/root_password password root | debconf-set-selections  # confirm the password (as in the usual installation)  RUN echo mariadb-galera-server-5.5 mysql-server/root_password_again password root | debconf-set-selections   # install the necessary packages  RUN LC_ALL=en_US.utf8 DEBIAN_FRONTEND=noninteractive apt-get -o Dpkg::Options::='--force-confnew' -qqy install mariadb-galera-server galera mariadb-client  # upload the locally created my.cnf (obviously this can go into the default MariaDB path  ADD ./my.cnf /etc/mysql/my.cnf  # startup the service - this will fail since the nodes haven't been configured on first boot  RUN service mysql restart   # open the ports required to connect to MySQL and for Galera SST / IST operations  EXPOSE 3306 4444 4567 4568  

Configuring MariaDB and Galera

We'll also need our base configuration for MariaDB. I've included the base configuration variables for Galera—obviously there are more, however these are good enough for starting up the service:

root@workstation:~# vi my.cnf  [mysqld]  wsrep_provider=/usr/lib/galera/libgalera_smm.so  wsrep_cluster_address=gcomm://  wsrep_sst_method=rsync  wsrep_cluster_name=galera_cluster  binlog_format=ROW  default_storage_engine=InnoDB  innodb_autoinc_lock_mode=2  innodb_locks_unsafe_for_binlog=1 

3. Building and Deploying the Cluster Nodes

So far so good. We have Docker installed and our Dockerfile as well as our my.cnf file ready to go. Now it's time to build our Docker image, check that the image exists, and start up three separate Docker images for each of our Galera nodes:

root@workstation:~# docker build -t ubuntu_trusty/mariadb-galera . root@workstation:~# docker images |grep mariadb-galera  ubuntu_trusty/mariadb-galera   latest               afff3aaa9dfb        About a minute ago   412.5 MB  # Start the three nodes docker run --name mariadb1 -i -t -d ubuntu_trusty/mariadb-galera /bin/bash docker run --name mariadb2 -i -t -d ubuntu_trusty/mariadb-galera /bin/bash docker run --name mariadb3 -i -t -d ubuntu_trusty/mariadb-galera /bin/bash 

4. Networking and Node Discovery

We’ve started up our Docker images; now let's verify that they are in fact up and retrieve the process information we need to connect. We’ll need two pieces of information: the IP-Address and the Docker image name, which can be received using the combination of the docker ps and the docker inspect commands:

root@workstation:~# docker ps  CONTAINER ID        IMAGE                                   COMMAND             CREATED             STATUS              PORTS                                    NAMES  b51e74933ece        ubuntu_trusty/mariadb-galera:latest   /bin/bash           About an hour ago   Up About an hour    3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp   mariadb3  03109c7018c0        ubuntu_trusty/mariadb-galera:latest   /bin/bash           About an hour ago   Up About an hour    3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp   mariadb2  1db2a9a520f8        ubuntu_trusty/mariadb-galera:latest   /bin/bash           About an hour ago   Up About an hour    3306/tcp, 4444/tcp, 4567/tcp, 4568/tcp   mariadb1  root@workstation:~# docker ps |cut -d' ' -f1 |grep -v CONTAINER | xargs docker inspect |egrep '"ID"|IPAddress'  "ID": "b51e74933ece...",  "IPAddress": "172.17.0.3",  "ID": "03109c7018c0...",  "IPAddress": "172.17.0.4",  "ID": "1db2a9a520f8...",  "IPAddress": "172.17.0.2", 

5. Bootstrapping the Galera Cluster

Time to use lxc-attach to connect to our Docker images using the Docker image name, add the mounts to /etc/mtab to keep them MariaDB friendly, and customize the gcomm:// address as we would for a usual Galera configuration.

Note: The Docker image ID is generated when the instance fires up, so make sure to use your own instance ID in the following commands.

# Connecting to the first node to bootstrap root@workstation:~# lxc-attach --name b51e74933ece...  root@b51e74933ece:~# cat /proc/mounts > /etc/mtab  root@b51e74933ece:~# service mysql restart    # Update gcomm with the node IPs found earlier  root@b51e74933ece:~# vi /etc/mysql/my.cnf  wsrep_cluster_address=gcomm://172.17.0.2,172.17.0.3,172.17.0.4  root@b51e74933ece:~# exit 

Repeat the process for the remaining nodes (mariadb2 and mariadb3), ensuring the gcomm:// string is identical across all nodes to facilitate discovery.

6. Verifying Cluster Health

Once all services are started, we log into the MariaDB monitor to verify that the nodes have joined the cluster successfully:

root@workstation:~# lxc-attach --name 1db2a9a520f8...  root@1db2a9a520f8:~# service mysql start  root@1db2a9a520f8:~# mysql -uroot -proot  MariaDB [(none)]> show status like 'wsrep_cluster%';  +--------------------------+--------------------------------------+  | Variable_name            | Value                                |  +--------------------------+--------------------------------------+  | wsrep_cluster_conf_id    | 3                                    |  | wsrep_cluster_size       | 3                                    |  | wsrep_cluster_state_uuid | 42bc375b-2bc0-11e4-851c-1a7627c0624c |  | wsrep_cluster_status     | Primary                              |  +--------------------------+--------------------------------------+  4 rows in set (0.00 sec) 

Oracle Database Consulting Services

Ready to optimize your Oracle Database for the future?