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.
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
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 # ...
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
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
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
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",
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.
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)
Ready to optimize your Oracle Database for the future?