Build distributed storage nodes with LXC containers and Gluster
It allows you to pool your data in various configurations similar to raid. You can have distributed volumes or replicated volumes for redundancy and fail over or stripe data across volumes to increase performance, making it a great fit for typical scale out scenarios.
Gluster is an excellent alternative to expensive proprietary storage systems. There are other approaches to distributed storage and high availability like DRBD and Ceph but Gluster is far easier to setup and use. Gluster doesn't need any specific setup, it sits above the file system layer and thus works on any file system (XFS recommended, we use btrfs) and installs like any other app.
In a typical app like WordPress for example apart from the db, data is stored in /wp-content/upload. You can use rsync to keep things in sync between 2 or more instances, but that's not a real time or scalable solution.
Combine Gluster with LXC and you have got yourself a fantastic set of capabilities for a highly scalable architecture. You can have data in Gluster storage bricks inside containers, these can be like your portable scalable instances, or store it outside containers in Gluster storage nodes with Gluster mounts or even LXC bind mounts. The possibilities are endless
For this guide we are going to focus on installing Gluster in containers and use it to replicate data across 2 containers.
Installing Gluster
You can download the latest Gluster packages as per your container OS. You need the Glusterfs-server and Gluster-fs client packages.
For this guide we are going to use Debian Wheezy 64 bit containers. So let's start by adding the Gluster Wheezy repo to the containers.
wget -O - http://download.gluster.org/pub/gluster/glusterfs/3.5/3.5.2/Debian/wheezy/pubkey.gpg | apt-key add -
echo deb http://download.gluster.org/pub/gluster/glusterfs/3.5/3.5.2/Debian/wheezy/apt wheezy main > /etc/apt/sources.list.d/gluster.list
apt-get update
Gluster depends on Fuse and since we are installing in containers we need to create the fuse device in our containers before installing. Make sure /dev/fuse is loaded in the host, and you are using default LXC OS templates for your containers.
In both containers
mknod /dev/fuse c 10 229
Once this is done install Gluster on both containers
apt-get install glusterfs-server glusterfs-client
If you are in Ubuntu and incase you get an apparmor error, disable apparmor in the container temporarily by using the LXC flag
lxc.aa_profile = off
Reboot the container with the profile off, create the device. Once this is successful you can stop the container, remove the line and reboot the container to proceed.
Configuring Gluster
We are using a single LXC host for this guide, in actual use Gluster will typically span multiple hosts. For production environments it's a good idea to configure your internal DNS server to resolve container names. If you use our advanced networking guide to connect containers across several hosts, the /etc/hosts file will suffice.
Let's connect the Gluster nodes. We are using only 2 nodes for this guide. You can initiate the peering from any node. Let's do it from Gluster 1.
gluster peer probe gluster2
You should get a successful peering confirmation
peer probe: success
To check peer status you can use the command
gluster peer status
This should give you a status message like below
Number of Peers: 1 Hostname: gluster2 Port: 24007 Uuid: 7fbha954-9d2a-8n7f-73ga-5ccj42f8932f State: Peer in Cluster (Connected)
Now that the nodes are peered let's add a Gluster replication volume (from Gluster 1 container node)
gluster volume create volume1 replica 2 transport tcp gluster1:/var/gluster-storage gluster2:/var/gluster-storage
Let's start the volume
gluster volume start volume1
You can query for volume info
gluster volume info
The Gluster client is used to mount volumes in nodes. Let's mount volume 1 in our Gluster 1 container node.
mount -t glusterfs gluster1:/volume1 /var/www/data
Do the same in Gluster 2
mount -t glusterfs gluster1:/volume1 /var/www/data
/var/www/data is the mount point for your replicated Gluster volume. This mount point can of course can be any location folder of your choice. Any data placed here will be replicated across the nodes.
Now that everything works the next step is to ensure these volumes are automatically mounted at boot. You could add a line to the containers fstab but with recent versions of Gluster I have found this often doesn't work.
An alternative is to use an init script. Here is a working init script from the fine folks at the infosec blog. You need to change the 'gluster1' in the script to match your chosen host names for the containers.
### BEGIN INIT INFO # Provides: mount-glusterfs # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO #! /bin/sh # /etc/init.d/mount-glusterfs # # Some things that run always at boot mount -t glusterfs gluster1:/volume1 /var/www/data # Uncomment this line if you need to start Apache after mount glusterFS volume # service apache2 start # Carry out specific functions when asked to by the system case "$1" in start) echo "Mounting glusterfs volumes " mount -t glusterfs gluster1:/volume1 /var/www/data ;; stop) echo "Unmount glusterfs volumes" umount /var/mount ;; *) echo "Usage: /etc/init.d/mount-glusterfs {start|stop}" exit 1 ;; esac exit 0
Gluster concepts
However since we love our readers we are going to give a high level conceptual overview and hope it is useful.
Gluster uses the concept of pools, nodes, volumes, bricks and mounts. Depending on your architecture you can bring these together in various ways to give you maximum resilience, performance, availability and flexibility.
A pool is a collection of nodes/peers that form the storage pool, these could be nodes dedicated to storage that are consumed by other nodes or directly the nodes delivering services.
A lot of the use cases we cover are in the cloud, Gluster like LXC does not need us to focus on underlying file systems or storage which is what makes them truly flexible. However you could for instance dedicate underlying hardware specifically to your Gluster pool and create volumes out of them which are consumed by your nodes.
A Gluster volume is created on your storage nodes. It could be a replicated or distributed volume depending on how its configured and it spans nodes. A volume is typically made up of individual bricks on the nodes. Volumes are what is finally consumed. Volumes are mounted in a chosen directory on node/nodes that consume Gluster storage services.
For the use case this guide covered, our storage nodes were our actual application service nodes, and had a single volume with 2 bricks in the 2 nodes (containers) configured for replication.