DevOps

Configuring and Setting Up a Zookeeper Ensemble with Ansible – Part 4

In this guide, we’ll walk through the steps to configure and set up a Zookeeper ensemble using Ansible. We will cover how to partition, format, and mount disks, update configurations, install Zookeeper, and set up logging.

Zookeeper Configuration (zoo.cfg)

The Zookeeper configuration file zoo.cfg defines various parameters for Zookeeper. Below is an example configuration:

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial synchronization phase can take
initLimit=10
# The number of ticks that can pass between sending a request and getting an acknowledgement
syncLimit=5
# The directory where the snapshot is stored
dataDir=/tmp/data1/zookeeper
# The port at which the clients will connect
clientPort=2181
# The maximum number of client connections
maxClientCnxns=1000

server.1=192.168.33.20:2888:3888
server.2=192.168.33.30:2888:3888
server.3=192.168.33.40:2888:3888

Explanation:

  • tickTime: Basic time unit in milliseconds.
  • initLimit: Time Zookeeper allows followers to connect and sync with the leader.
  • syncLimit: Time to allow followers to sync with the leader.
  • dataDir: Directory where Zookeeper stores snapshots.
  • clientPort: Port for client connections.
  • maxClientCnxns: Maximum number of client connections.
  • server.X: List of Zookeeper ensemble servers.

Creating Necessary Directories

Create the directory for Zookeeper data storage.

mkdir -p /tmp/data1/zookeeper

Create the directory for Zookeeper logs.

mkdir -p /var/log/zookeeper

Logging Configuration (log4j.properties)

The log4j.properties file configures logging for Zookeeper. Below is an example configuration:

# Define some default values that can be overridden by system properties
zookeeper.root.logger=INFO, CONSOLE
zookeeper.console.threshold=INFO
zookeeper.log.dir=/var/log/zookeeper
zookeeper.log.file=zookeeper.log
zookeeper.log.threshold=DEBUG
zookeeper.tracelog.dir=.
zookeeper.tracelog.file=zookeeper_trace.log

# ZooKeeper Logging Configuration
log4j.rootLogger=${zookeeper.root.logger}

# Log INFO level and above messages to the console
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=${zookeeper.console.threshold}
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n

# Log DEBUG level and above messages to a rolling log file
log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
log4j.appender.ROLLINGFILE.Threshold=${zookeeper.log.threshold}
log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/${zookeeper.log.file}
log4j.appender.ROLLINGFILE.MaxFileSize=10MB
# Uncomment the next line to limit the number of backup files
# log4j.appender.ROLLINGFILE.MaxBackupIndex=10
log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L] - %m%n

# Log TRACE level messages to a trace file
log4j.appender.TRACEFILE=org.apache.log4j.FileAppender
log4j.appender.TRACEFILE.Threshold=TRACE
log4j.appender.TRACEFILE.File=${zookeeper.tracelog.dir}/${zookeeper.tracelog.file}
log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} [myid:%X{myid}] - %-5p [%t:%C{1}@%L][%x] - %m%n

Ansible Playbook for Zookeeper Setup

The Ansible playbook below sets up a Zookeeper ensemble by adding users, downloading Zookeeper, configuring it, and creating necessary directories.

- hosts: ensemble
  vars:
    ZOOKEEPER_VERSION: 3.4.12
  tags: ['ensemble', 'install', 'zoo_upgrade']
  tasks:
    - name: Add user zookeeper
      user:
        name: zookeeper

    - name: Download and Unarchive Zookeeper
      unarchive:
        src: http://www-us.apache.org/dist/zookeeper/zookeeper-3.4.12.tar.gz
        dest: /opt
        remote_src: yes
        owner: zookeeper
        group: zookeeper
        mode: 0755

    - name: Create softlink for Zookeeper base dir
      file:
        src: /opt/zookeeper-3.4.12
        path: /opt/zookeeper
        state: link
        owner: zookeeper
        group: zookeeper

    - name: Copy zoo.cfg and log4j.properties
      synchronize:
        src: "{{ base_dir }}/files/opt/zookeeper/conf"
        dest: /opt/zookeeper

    - name: Create data and log directories
      file:
        path: "{{ item }}"
        state: directory
        owner: zookeeper
        group: zookeeper
        mode: 0755
      loop:
        - /data1/zookeeper
        - /var/log/zookeeper

Running the Playbook

Run the playbook with the following command:

ansible-playbook kafka.yml -i hosts --extra-vars "base_dir=/" --tags ensemble --become

Setting up Zookeeper Service Script

Create a script to manage the Zookeeper service.

mkdir -p scripts
touch scripts/zookeeper-service.sh

Content of zookeeper-service.sh:

export ZOO_LOG_DIR=/var/log/zookeeper
/opt/zookeeper/bin/zkServer.sh $1

Adding myid Files

Each Zookeeper server needs a unique myid file. Run the following commands on each server:

ssh vagrant@192.168.33.20 "sudo -u zookeeper sh -c 'echo 1 > /tmp/data1/zookeeper/myid'"
ssh vagrant@192.168.33.30 "sudo -u zookeeper sh -c 'echo 2 > /tmp/data1/zookeeper/myid'"
ssh vagrant@192.168.33.40 "sudo -u zookeeper sh -c 'echo 3 > /tmp/data1/zookeeper/myid'"

Ali Imran
Over the past 20+ years, I have been working as a software engineer, architect, and programmer, creating, designing, and programming various applications. My main focus has always been to achieve business goals and transform business ideas into digital reality. I have successfully solved numerous business problems and increased productivity for small businesses as well as enterprise corporations through the solutions that I created. My strong technical background and ability to work effectively in team environments make me a valuable asset to any organization.
https://ITsAli.com

Leave a Reply