diff --git a/.travis.yml b/.travis.yml index ab6cfcac..3356d71b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -41,6 +41,10 @@ env: - playbook: first-ansible-playbook.yml distro: centos7 + # TODO: Not easy to test in CI at this time. + # - playbook: gluster.yml + # distro: ubuntu2004 + - playbook: https-self-signed.yml distro: ubuntu2004 diff --git a/README.md b/README.md index d32f7284..62db576e 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,7 @@ Here is an outline of all the examples contained in this repository, by chapter: - [`lamp-infrastructure`](lamp-infrastructure/): A multi-server LAMP-based web application infrastructure focused on high-availability and performance for a LAMP-stack app. - [`elk`](elk/): A two-server example of the Elasticsearch-Logstash-Kibana stack, which uses one server to store and visualize logs centrally, and another server to send logs via Filebeat. + - [`gluster`](gluster/): A two-server example of building a fast networked storage setup using Gluster. ### Chapter 10 diff --git a/gluster/README.md b/gluster/README.md new file mode 100644 index 00000000..4df3d428 --- /dev/null +++ b/gluster/README.md @@ -0,0 +1,35 @@ +# GlusterFS Distributed Filesystem Configuration + +This project creates a distributed filesystem on two servers using [GlusterFS](http://www.gluster.org/). + +## Building the VMs + + 1. Download and install [VirtualBox](https://www.virtualbox.org/wiki/Downloads). + 2. Download and install [Vagrant](http://www.vagrantup.com/downloads.html). + 3. [Mac/Linux only] Install [Ansible](http://docs.ansible.com/ansible/latest/intro_installation.html). + 4. Run `ansible-galaxy install -r requirements.yml` in this directory to get the required Ansible roles. + 5. Run `vagrant up` to build the VMs and configure the infrastructure. + +When Vagrant is finished provisioning the VMs with Ansible, run the following two commands to confirm that Gluster is operating nominally: + +``` +# Get status for the Gluster cluster. +$ ansible gluster -i inventory -a "gluster peer status" -b + +# Get volume info for the Gluster cluster. +ansible gluster -i inventory -a "gluster volume info" -b +``` + +You can also do the following to confirm that files are being replicated/distributed correctly: + + 1. Log into the first server: `vagrant ssh gluster1` + 2. Create a file in the mounted gluster volume: `sudo touch /mnt/gluster/test` + 3. Log out of the first server: `exit` + 4. Log into the second server: `vagrant ssh gluster2` + 5. List the contents of the gluster directory: `ls /mnt/gluster` + +You should see the `test` file you created in step 2; this means Gluster is working correctly! + +## About the Author + +This project was created by [Jeff Geerling](https://www.jeffgeerling.com/) as an example for [Ansible for DevOps](https://www.ansiblefordevops.com/). diff --git a/gluster/Vagrantfile b/gluster/Vagrantfile new file mode 100644 index 00000000..3fb778d2 --- /dev/null +++ b/gluster/Vagrantfile @@ -0,0 +1,38 @@ +# -*- mode: ruby -*- +# vi: set ft=ruby : + +Vagrant.configure("2") do |config| + # Base VM OS configuration. + config.vm.box = "geerlingguy/ubuntu2004" + config.vm.synced_folder '.', '/vagrant', disabled: true + config.ssh.insert_key = false + + config.vm.provider :virtualbox do |v| + v.memory = 512 + v.cpus = 1 + end + + # Define two VMs with static private IP addresses. + boxes = [ + { :name => "gluster1", :ip => "192.168.29.2" }, + { :name => "gluster2", :ip => "192.168.29.3" } + ] + + # Provision each of the VMs. + boxes.each do |opts| + config.vm.define opts[:name] do |config| + config.vm.hostname = opts[:name] + config.vm.network :private_network, ip: opts[:ip] + + # Provision both VMs using Ansible after the last VM is booted. + if opts[:name] == "gluster2" + config.vm.provision "ansible" do |ansible| + ansible.playbook = "playbooks/provision.yml" + ansible.inventory_path = "inventory" + ansible.limit = "all" + end + end + end + end + +end diff --git a/gluster/inventory b/gluster/inventory new file mode 100644 index 00000000..dae8cbde --- /dev/null +++ b/gluster/inventory @@ -0,0 +1,7 @@ +[gluster] +192.168.29.2 +192.168.29.3 + +[gluster:vars] +ansible_ssh_user=vagrant +ansible_ssh_private_key_file=~/.vagrant.d/insecure_private_key diff --git a/gluster/playbooks/provision.yml b/gluster/playbooks/provision.yml new file mode 100644 index 00000000..fa66fba4 --- /dev/null +++ b/gluster/playbooks/provision.yml @@ -0,0 +1,39 @@ +--- +- hosts: gluster + become: yes + + vars_files: + - vars.yml + + roles: + - geerlingguy.firewall + - geerlingguy.glusterfs + + tasks: + - name: Ensure Gluster brick and mount directories exist. + file: + path: "{{ item }}" + state: directory + mode: 0775 + with_items: + - "{{ gluster_brick_dir }}" + - "{{ gluster_mount_dir }}" + + - name: Configure Gluster volume. + gluster_volume: + state: present + name: "{{ gluster_brick_name }}" + brick: "{{ gluster_brick_dir }}" + replicas: 2 + cluster: "{{ groups.gluster | join(',') }}" + host: "{{ inventory_hostname }}" + force: yes + run_once: true + + - name: Ensure Gluster volume is mounted. + mount: + name: "{{ gluster_mount_dir }}" + src: "{{ inventory_hostname }}:/{{ gluster_brick_name }}" + fstype: glusterfs + opts: "defaults,_netdev" + state: mounted diff --git a/gluster/playbooks/vars.yml b/gluster/playbooks/vars.yml new file mode 100644 index 00000000..68a8d4b3 --- /dev/null +++ b/gluster/playbooks/vars.yml @@ -0,0 +1,25 @@ +--- +# Firewall configuration. +firewall_allowed_tcp_ports: + - 22 + # For Gluster. + - 111 + # Port-mapper for Gluster 3.4+. + # - 2049 + # Gluster Daemon. + - 24007 + # 24009+ for Gluster <= 3.3; 49152+ for Gluster 3.4+ (one port per server). + - 24009 + - 24010 + - 49152 + - 49153 + # Gluster inline NFS server. + - 38465 + - 38466 +firewall_allowed_udp_ports: + - 111 + +# Gluster configuration. +gluster_mount_dir: /mnt/gluster +gluster_brick_dir: /srv/gluster/brick +gluster_brick_name: gluster diff --git a/gluster/requirements.yml b/gluster/requirements.yml new file mode 100644 index 00000000..823c1830 --- /dev/null +++ b/gluster/requirements.yml @@ -0,0 +1,3 @@ +--- +- src: geerlingguy.firewall +- src: geerlingguy.glusterfs