1

I can get my Apache Kafka producer to send messages when it is running inside a container. However, when my producer is running outside the container in the host machine it doesn't work. I suspect it is a Docker networking issue with my Docker compose file but I can't figure it out.

I tried the solutions posted online similar to my problem but they don't work for me. Help!

  1. Docker-compose file
version: '3'
services:
  zookeeper:
    image: 'bitnami/zookeeper:latest'
    ports:
      - '2181:2181'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
  kafka:
    image: 'bitnami/kafka:latest'
    ports:
      - '9092:9092'
    environment:_
      - KAFKA_BROKER_ID=1
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092
      - ALLOW_PLAINTEXT_LISTENER=yes

  1. Host producer

//import util.properties packages
import java.util.Properties;

//import simple producer packages
import org.apache.kafka.clients.producer.Producer;

//import KafkaProducer packages
import org.apache.kafka.clients.producer.KafkaProducer;

//import ProducerRecord packages
import org.apache.kafka.clients.producer.ProducerRecord;

//Create java class named “SimpleProducer”
public class SimpleProducer {

   public static void main(String[] args) throws Exception{

      // Check arguments length value
      if(args.length == 0){
         System.out.println("Enter topic name");
         return;
      }

      //Assign topicName to string variable
      String topicName = args[0].toString();

      // create instance for properties to access producer configs   
      Properties props = new Properties();

      //Assign localhost id
      props.put("bootstrap.servers", "localhost:9092");

      //Set acknowledgements for producer requests.      
      props.put("acks", "all");

      //If the request fails, the producer can automatically retry,
      props.put("retries", 0);

      //Specify buffer size in config
      props.put("batch.size", 16384);

      //Reduce the no of requests less than 0   
      props.put("linger.ms", 1);

      //The buffer.memory controls the total amount of memory available to the producer for buffering.   
      props.put("buffer.memory", 33554432);

      props.put("key.serializer", 
         "org.apache.kafka.common.serialization.StringSerializer");

      props.put("value.serializer", 
         "org.apache.kafka.common.serialization.StringSerializer");

      Producer<String, String> producer = new KafkaProducer
         <String, String>(props);

      for(int i = 0; i < 10; i++)
         producer.send(new ProducerRecord<String, String>(topicName, 
            Integer.toString(i), Integer.toString(i)));
               System.out.println("Message sent successfully");
               producer.close();
   }
}

The host producer should post messages to the Docker Apache kafka but it doesn't. It creates the topic but the messages are never received. What am I doing wrong? This is a bitnami image, not Confluent image.

code4u
  • 119
  • 1
  • 2
  • 10
  • 1
    Typo? `localcost:9092`? – OneCricketeer Jun 03 '19 at 00:33
  • Possible duplicate of [Connect to Kafka running in Docker from local machine](https://stackoverflow.com/questions/51630260/connect-to-kafka-running-in-docker-from-local-machine) – OneCricketeer Jun 03 '19 at 00:36
  • 1
    Based on @cricket_007 response, I added/changed the following lines in my Docker-compose file and it worked for my bitnami image of Docker Apache Kafka: - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT - KAFKA_LISTENERS=PLAINTEXT://:9092,PLAINTEXT_HOST://:29092 - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 – code4u Jun 03 '19 at 18:43

2 Answers2

3

From my previous answer here:

What I needed to do was to declare the LISTENERS as both binding to the docker host, and then advertise them differently - one to the docker network, one to the host.

services:
  zookeeper:
    image: confluentinc/cp-zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_SYNC_LIMIT: 2
  kafka:
    image: confluentinc/cp-kafka
    ports:
      - 9094:9094
    depends_on:
      - zookeeper
    environment:
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_LISTENERS: INTERNAL://kafka:9092,OUTSIDE://kafka:9094
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka:9092,OUTSIDE://localhost:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL

Now you have the Kafka available on your localhost at :9094 (as per the OUTSIDE listener and the ports entry in the docker-compose file), and inside the Docker network at :9092.

daniu
  • 14,137
  • 4
  • 32
  • 53
1

This solution is for the bitnami Docker image of Apache Kafka. Thanks to @cricket_007 and @daniu for the solution. I updated several lines in my Docker-compose file in the Kafka environment section.

Here's the complete, updated Docker-compose file:

version: '3'
services:
  zookeeper:
    image: 'bitnami/zookeeper:latest'
    ports:
      - '2181:2181'
    environment:
      - ALLOW_ANONYMOUS_LOGIN=yes
  kafka:
    image: 'bitnami/kafka:latest'
    ports:
      - '9092:9092'
      - '29092:29092'
    environment:
      - KAFKA_BROKER_ID=1
      - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
      - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT 
      - KAFKA_LISTENERS=PLAINTEXT://:9092,PLAINTEXT_HOST://:29092 
      - KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092
      - ALLOW_PLAINTEXT_LISTENER=yes

code4u
  • 119
  • 1
  • 2
  • 10
  • How is that different from mine? – daniu Jun 03 '19 at 20:54
  • @daniu The question specifically asked about bitnami containers – OneCricketeer Jun 08 '19 at 13:26
  • @cricket_007 Yeah, but that makes the only difference the docker image name. The problem was providing an outside port for the kafka container; that's done with the LISTENERs-setup, which is the same. – daniu Jun 08 '19 at 14:43