ZooKeeper cluster with Vagrant
Tags: clickhouse, zookeeper, vagrant
Published: 2021-01-25 15:08:05

If we want to set up a ZooKeeper cluster in our development environment one way to proceed is defining it in Vagrant.

Let's suppose we want to set up a cluster with 3 nodes (zk1, zk2, and zk3). The `Vagrantfile` will be:

```ruby
# -*- mode: ruby -*-
# vi: set ft=ruby :

# rubocop: disable Metrics/BlockLength
Vagrant.configure('2') do |config|
  config.vm.define 'zk1' do |zookeeper|
    zookeeper.vm.box = 'debian/stretch64'
    zookeeper.vm.network :private_network, ip: '192.168.33.211'
    zookeeper.vm.hostname = 'zk1'
    # Configure VM
    zookeeper.vm.provider 'virtualbox' do |vb|
      vb.memory = '256'
      vb.cpus = 2
    end
    # Install and start zookeeper
    zookeeper.vm.provision 'shell', inline: <<-SHELL
      apt update
      apt install -y default-jdk
      mkdir -p /var/lib/zookeeper
      chown vagrant:vagrant /var/lib/zookeeper
      wget http://apache.uvigo.es/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
      tar xvf apache-zookeeper-3.6.2-bin.tar.gz
      rm apache-zookeeper-3.6.2-bin.tar.gz
      mv apache-zookeeper-3.6.2-bin /opt/zookeeper-3.6.2
      chown -R vagrant:vagrant /opt/zookeeper-3.6.2
      echo -e 'tickTime=2000\ndataDir=/var/lib/zookeeper\nclientPort=2181\ninitLimit=5\nsyncLimit=2\nserver.1=192.168.33.211:2888:3888\nserver.2=192.168.33.212:2888:3888\nserver.3=192.168.33.213:2888:3888' > /opt/zookeeper-3.6.2/conf/zoo.cfg
      echo -e '1' > /var/lib/zookeeper/myid
    SHELL
  end

  config.vm.define 'zk2' do |zookeeper|
    zookeeper.vm.box = 'debian/stretch64'
    zookeeper.vm.network :private_network, ip: '192.168.33.212'
    zookeeper.vm.hostname = 'zk2'
    # Configure VM
    zookeeper.vm.provider 'virtualbox' do |vb|
      vb.memory = '256'
      vb.cpus = 2
    end
    # Install and start zookeeper
    zookeeper.vm.provision 'shell', inline: <<-SHELL
      apt update
      apt install -y default-jdk
      mkdir -p /var/lib/zookeeper
      chown vagrant:vagrant /var/lib/zookeeper
      wget http://apache.uvigo.es/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
      tar xvf apache-zookeeper-3.6.2-bin.tar.gz
      rm apache-zookeeper-3.6.2-bin.tar.gz
      mv apache-zookeeper-3.6.2-bin /opt/zookeeper-3.6.2
      chown -R vagrant:vagrant /opt/zookeeper-3.6.2
      echo -e 'tickTime=2000\ndataDir=/var/lib/zookeeper\nclientPort=2181\ninitLimit=5\nsyncLimit=2\nserver.1=192.168.33.211:2888:3888\nserver.2=192.168.33.212:2888:3888\nserver.3=192.168.33.213:2888:3888' > /opt/zookeeper-3.6.2/conf/zoo.cfg
      echo -e '2' > /var/lib/zookeeper/myid
    SHELL
  end

  config.vm.define 'zk3' do |zookeeper|
    zookeeper.vm.box = 'debian/stretch64'
    zookeeper.vm.network :private_network, ip: '192.168.33.213'
    zookeeper.vm.hostname = 'zk3'
    # Configure VM
    zookeeper.vm.provider 'virtualbox' do |vb|
      vb.memory = '256'
      vb.cpus = 2
    end
    # Install and start zookeeper
    zookeeper.vm.provision 'shell', inline: <<-SHELL
      apt update
      apt install -y default-jdk
      mkdir -p /var/lib/zookeeper
      chown vagrant:vagrant /var/lib/zookeeper
      wget http://apache.uvigo.es/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
      tar xvf apache-zookeeper-3.6.2-bin.tar.gz
      rm apache-zookeeper-3.6.2-bin.tar.gz
      mv apache-zookeeper-3.6.2-bin /opt/zookeeper-3.6.2
      chown -R vagrant:vagrant /opt/zookeeper-3.6.2
      echo -e 'tickTime=2000\ndataDir=/var/lib/zookeeper\nclientPort=2181\ninitLimit=5\nsyncLimit=2\nserver.1=192.168.33.211:2888:3888\nserver.2=192.168.33.212:2888:3888\nserver.3=192.168.33.213:2888:3888' > /opt/zookeeper-3.6.2/conf/zoo.cfg
      echo -e '3' > /var/lib/zookeeper/myid
    SHELL
  end
end
# rubocop: enable Metrics/BlockLength
```

This way we could start the 3 nodes of the cluster with:

```bash
vagrant up zk1
vagrant up zk2
vagrant up zk3
```

This `Vagrantfile` does not start the ZooKeeper nodes automatically so we will have to start them manually:

```bash
vagrant ssh zk1
cd /opt/zookeeper-3.6.2/bin
./zkServer.sh start
```

I'm sure this `Vagrantfile` can be improved removing the repeated parts and starting the servers automatically.