Siddharth Satish
Siddharth Satish

Reputation: 73

Apache Kafka cluster not connecting to Zookeeper on Docker

I am creating a 3 node Zookeeper and 3 node Kafka cluster on Docker. I need to link the Kafka cluster to the Zookeeper cluster.

Below is docker-compose.yml code -

version: '2'
services:
  zookeeper-1:
    image: zookeeper:latest
    environment:
      ZOOKEEPER_SERVER_ID: 1
      ZOOKEEPER_CLIENT_PORT: 22181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 5
      ZOOKEEPER_SYNC_LIMIT: 2
      ZOOKEEPER_SERVERS: localhost:22888:23888;localhost:32888:33888;localhost:42888:43888

  zookeeper-2:
    image: zookeeper:latest
    environment:
      ZOOKEEPER_SERVER_ID: 2
      ZOOKEEPER_CLIENT_PORT: 32181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 5
      ZOOKEEPER_SYNC_LIMIT: 2
      ZOOKEEPER_SERVERS: localhost:22888:23888;localhost:32888:33888;localhost:42888:43888  

  zookeeper-3:
    image: zookeeper:latest
    environment:
      ZOOKEEPER_SERVER_ID: 3
      ZOOKEEPER_CLIENT_PORT: 42181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_INIT_LIMIT: 5
      ZOOKEEPER_SYNC_LIMIT: 2
      ZOOKEEPER_SERVERS: localhost:22888:23888;localhost:32888:33888;localhost:42888:43888    

  kafka1:
    image: abc/kafka:latest
    hostname: kafka1
    network_mode: host
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: localhost:22181,localhost:32181,localhost:42181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:19092
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3

  kafka2:
    image: abc/kafka:latest
    hostname: kafka2
    network_mode: host
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: localhost:22181,localhost:32181,localhost:42181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:29092
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3

  kafka3:
    image: abc/kafka:latest
    hostname: kafka3
    network_mode: host
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: localhost:22181,localhost:32181,localhost:42181
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:39092
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3

When i run the docker-compose up command, the 3 node zookeeper cluster gets created successfully. But the Kafka cluster doesn't get created. It only displays the following error on command line -

kafka_kafka2_1 exited with code 0
kafka_kafka1_1 exited with code 0
kafka_kafka3_1 exited with code 0

I have also added the Dockerfile for creating the image, below -

FROM centos:7
MAINTAINER [email protected]

ENV KAFKA_BIN=http://www-eu.apache.org/dist/kafka/0.11.0.2/kafka_2.11-0.11.0.2.tgz

RUN yum install -y wget java-1.8.0-openjdk \
    && cd /tmp && wget -q $KAFKA_BIN \
    && export K_TAR=/tmp/$(ls kafka* | head -1) \
    && mkdir -p /opt/apache/kafka/ && tar -zxf $K_TAR -C /opt/apache/kafka/ \
    && cd /opt/apache/kafka && ln -s $(ls) current \
    && rm -rf $K_TAR

ENV KAFKA_HOME /opt/apache/kafka/current
ENV PATH $PATH:$KAFKA_HOME/bin

ADD resources /home/kafka

RUN groupadd -r kafka \
    && useradd -r -g kafka kafka \
    && mkdir -p /home/kafka \
    && chown -R kafka:kafka /home/kafka \
    && chmod -R +x /home/kafka/scripts \
    && mkdir -p /var/log/kafka \
    && chown -R kafka:kafka /var/log/kafka \
    && mkdir -p /etc/kafka \
    && chown -R kafka:kafka /etc/kafka

USER kafka

There is no error message of any sort. Can someone please help me debug this issue as to why the kafka cluster is not starting. I am unable to debug this, especially because it only exits with code 0 and provides no error message.

Upvotes: 3

Views: 8346

Answers (3)

smbanaei
smbanaei

Reputation: 1177

you need to set the proper hostname in /etc/hosts to ba able to connect the kafka containers outside the docker :

 cat /etc/hosts
# This file was automatically generated by WSL. To stop automatic generation of this file, add the following entry to /etc/wsl.conf:
# [network]
# generateHosts = false
127.0.0.1       localhost
127.0.0.1       kafka1
127.0.0.1       kafka2
127.0.0.1       kafka3

Here is My Working Config :

version: '2'
services:
  zookeeper1:
    image: confluentinc/cp-zookeeper:$CP_VERSION
    container_name: zookeeper1
    hostname: zookeeper1
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_SERVER_ID: 1
      ZOOKEEPER_SERVERS: "zookeeper1:22888:23888;zookeeper2:22888:23888;zookeeper3:22888:23888"
    ports:
      - 2181:2181
    volumes: 
      - ./data/zoo-1/data:/var/lib/zookeeper/data
      - ./data/zoo-1/log:/var/lib/zookeeper/log

  zookeeper2:
    image: confluentinc/cp-zookeeper:$CP_VERSION
    container_name: zookeeper2
    hostname: zookeeper2
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_SERVER_ID: 2
      ZOOKEEPER_SERVERS: "zookeeper1:22888:23888;zookeeper2:22888:23888;zookeeper3:22888:23888"
    ports:
      - 2182:2181
    volumes: 
      - ./data/zoo-2/data:/var/lib/zookeeper/data
      - ./data/zoo-2/log:/var/lib/zookeeper/log

  zookeeper3:
    image: confluentinc/cp-zookeeper:$CP_VERSION
    container_name: zookeeper3
    hostname: zookeeper3
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_SERVER_ID: 3
      ZOOKEEPER_SERVERS: "zookeeper1:22888:23888;zookeeper2:22888:23888;zookeeper3:22888:23888"
    ports:
      - 2183:2181
    volumes: 
      - ./data/zoo-3/data:/var/lib/zookeeper/data
      - ./data/zoo-3/log:/var/lib/zookeeper/log

  kafka1:
    image: confluentinc/cp-kafka:$CP_VERSION
    container_name: kafka1
    hostname: kafka1
    depends_on:
      - zookeeper1
      - zookeeper2
      - zookeeper3
    ports:
      - 9091:9091
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper1:2181,zookeeper2:2181,zookeeper3:2181
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_LISTENERS: INTERNAL://:29092,OUTSIDE://:9091
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka1:29092,OUTSIDE://kafka1:9091
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_LOG_DIRS: /var/lib/kafka/logs


  kafka2:
    image: confluentinc/cp-kafka:$CP_VERSION
    container_name: kafka2
    hostname: kafka2
    depends_on:
      - zookeeper1
      - zookeeper2
      - zookeeper3
    ports:
      - 9092:9092
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ZOOKEEPER_CONNECT: zookeeper1:2181,zookeeper2:2181,zookeeper3:2181
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_LISTENERS: INTERNAL://:29092,OUTSIDE://:9092
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka2:29092,OUTSIDE://kafka2:9092
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_LOG_DIRS: /var/lib/kafka/logs

  kafka3:
    image: confluentinc/cp-kafka:$CP_VERSION
    container_name: kafka3
    hostname: kafka3
    depends_on:
      - zookeeper1
      - zookeeper2
      - zookeeper3
    ports:
      - 9093:9093
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ZOOKEEPER_CONNECT: zookeeper1:2181,zookeeper2:2181,zookeeper3:2181
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_LISTENERS: INTERNAL://:29092,OUTSIDE://:9093
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka3:29092,OUTSIDE://kafka3:9093
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_LOG_DIRS: /var/lib/kafka/logs

Upvotes: 0

Emil Koutanov
Emil Koutanov

Reputation: 580

localhost inside Docker refers to the container instance, not the host. This is a major source of confusion for Kafka installations. You need to configure Kafka's listeners to advertise a different host:port combination — one that is reachable from within the container.

An example of how this is done for multiple brokers is shown below. Credit: The example is taken from a repo accompanying Effective Kafka.


version: "3.2"
services:
  zookeeper:
    image: bitnami/zookeeper:3
    ports:
      - 2181:2181
    environment:
      ALLOW_ANONYMOUS_LOGIN: "yes"
  kafka-0:
    image: bitnami/kafka:2
    ports:
      - 9092:9092
    environment:
      KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
      ALLOW_PLAINTEXT_LISTENER: "yes"
      KAFKA_LISTENERS: >-
          INTERNAL://:29092,EXTERNAL://:9092
      KAFKA_ADVERTISED_LISTENERS: >-
          INTERNAL://kafka-0:29092,EXTERNAL://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: >-
          INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
    depends_on:
      - zookeeper
  kafka-1:
    image: bitnami/kafka:2
    ports:
      - 9093:9093
    environment:
      KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
      ALLOW_PLAINTEXT_LISTENER: "yes"
      KAFKA_LISTENERS: >-
          INTERNAL://:29092,EXTERNAL://:9093
      KAFKA_ADVERTISED_LISTENERS: >-
          INTERNAL://kafka-1:29092,EXTERNAL://localhost:9093
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: >-
          INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
    depends_on:
      - zookeeper
  kafka-2:
    image: bitnami/kafka:2
    ports:
      - 9094:9094
    environment:
      KAFKA_CFG_ZOOKEEPER_CONNECT: zookeeper:2181
      ALLOW_PLAINTEXT_LISTENER: "yes"
      KAFKA_LISTENERS: >-
          INTERNAL://:29092,EXTERNAL://:9094
      KAFKA_ADVERTISED_LISTENERS: >-
          INTERNAL://kafka-2:29092,EXTERNAL://localhost:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: >-
          INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: "INTERNAL"
    depends_on:
      - zookeeper
  kafdrop:
    image: obsidiandynamics/kafdrop:latest
    ports:
      - 9000:9000
    environment:
      KAFKA_BROKERCONNECT: >-
          kafka-0:29092,kafka-1:29092,kafka-2:29092
    depends_on:
      - kafka-0
      - kafka-1
      - kafka-2

Here, the application that connects to the brokers is Kafdrop, but you would replace it with your own image. Also, the example only uses one ZK node with 3 brokers for brevity; this should be a straightforward change.

Upvotes: 0

Hendrik M Halkow
Hendrik M Halkow

Reputation: 2302

First, you forgot to expose the zookeeper ports. Second, localhost means localhost – even for the docker containers. So your Kafka containers would try to connect to zookeeper within the same container, which does not work.

Have a look here how it is done correctly: https://github.com/confluentinc/cp-docker-images/blob/4.0.x/examples/cp-all-in-one/docker-compose.yml

If you don't like that approach, you can do it without exposing any port. For that, set the zookeeper client port in the zookeeper environment section of your compose file:

...
services:
  zookeeper:
    ...
    environment:
       ZOOKEEPER_CLIENT_PORT: 2181

Second, connect your kafka container to it:

...
kafka:
  ...
  environment:
    ZOOKEEPER_SERVERS: zookeeper:2181

With this approach, everything will happen inside the docker compose network.

Upvotes: 4

Related Questions