Подтвердить что ты не робот

Кафка в Докере не работает

Я пытаюсь использовать wurstmeister\kafka-docker изображение с docker-compose, но у меня возникают реальные проблемы с подключением всего.

Все сообщения или вопросы, которые я проверяю, похоже, не имеют никаких проблем, но я откровенно проиграл. (И в SO есть как минимум два вопроса, которые пытаются решить проблему)

Я считаю, что проблема в том, что я плохо разбираюсь в сети docker. Итак, проблема:

Я могу потреблять и производить из одного контейнера kafka, но когда я пытаюсь создать другой контейнер (или использовать свой ноутбук с клиентом python), у меня появилось несколько ошибок, связанных с параметром advertised.host.name (в изображении это параметр KAFKA_ADVERTISED_HOST_NAME)

Я уже пытаюсь установить эту переменную множеством способов, но это просто не работает.

Итак, я ищу автоответчик (например, как автоматически установить эти параметры и что это значит), как установить docker-compose.yml

Это мое:

zookeeper:
  image: wurstmeister/zookeeper
  ports:
    - "2181:2181"

kafka:
  image: wurstmeister/kafka
 # hostname: kafka
  ports:
    - "9092"
  links:
    - zookeeper:zk
  environment:
    KAFKA_ADVERTISED_HOST_NAME: "kafka"
    KAFKA_ADVERTISED_PORT: "9092"
    KAFKA_ZOOKEEPER_CONNECT: "zk:2181"

UPDATE

Следуя совету @dnephin, я изменил start-kafka.sh в следующих строках:

...
if [[ -z "$KAFKA_ADVERTISED_PORT" ]]; then
    export KAFKA_ADVERTISED_PORT=$(hostname -i)
fi
...

и удалите KAFKA_ADVERTISED_HOST_NAME: "kafka" из docker-compose.yml

Я начал контейнеры каноническим способом:

docker-compose up -d

Оба контейнера запущены:

$ docker-compose ps
           Name                          Command               State                     Ports                    
-----------------------------------------------------------------------------------------------------------------
infraestructura_kafka_1       start-kafka.sh                   Up      0.0.0.0:32768->9092/tcp                    
infraestructura_zookeeper_1   /opt/zookeeper/bin/zkServe ...   Up      0.0.0.0:2181->2181/tcp, 2888/tcp, 3888/tcp 

Впоследствии я сделал:

docker-compose logs

И все работает плавно.

Для проверки IP-адресов:

$ KAFKA_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' infraestructura_kafka_1)                                                                                                            
$ echo $KAFKA_IP
172.17.0.4

and

$ ZK_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' infraestructura_zookeeper_1)                                                                                                           
$ echo $ZK_IP 
172.17.0.3

Затем я выполняю в двух разных консолях:

Производитель:

$ docker run --rm --interactive wurstmeister/kafka /opt/kafka_2.11-0.9.0.1/bin/kafka-console-producer.sh --topic grillo --broker-list 171.17.0.4:9092  

Потребитель:

$ docker run --rm --interactive  wurstmeister/kafka /opt/kafka_2.11-0.9.0.1/bin/kafka-console-consumer.sh --topic grillo --from-beginning --zookeeper 172.17.0.3:2181 

Почти сразу предупреждения начинают летать по всему экрану:

[2016-03-11 00:39:17,010] WARN Fetching topic metadata with correlation id 0 for topics [Set(grillo)] from broker [BrokerEndPoint(1001,ba53d4fd7595,9092)] failed (kafka.client.ClientUtils$)
java.nio.channels.ClosedChannelException
        at kafka.network.BlockingChannel.send(BlockingChannel.scala:110)
        at kafka.producer.SyncProducer.liftedTree1$1(SyncProducer.scala:75)
        at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:74)
        at kafka.producer.SyncProducer.send(SyncProducer.scala:119)
        at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:59)
        at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:94)
        at kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
        at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:63)
[2016-03-11 00:39:17,013] WARN [console-consumer-79688_9dd5f575d557-1457656747003-f1ed369d-leader-finder-thread], Failed to find leader for Set([grillo,0]) (kafka.consumer.ConsumerFetcherManager$LeaderFin
derThread)
kafka.common.KafkaException: fetching topic metadata for topics [Set(grillo)] from broker [ArrayBuffer(BrokerEndPoint(1001,ba53d4fd7595,9092))] failed
        at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:73)
        at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:94)
        at kafka.consumer.ConsumerFetcherManager$LeaderFinderThread.doWork(ConsumerFetcherManager.scala:66)
        at kafka.utils.ShutdownableThread.run(ShutdownableThread.scala:63)
Caused by: java.nio.channels.ClosedChannelException
        at kafka.network.BlockingChannel.send(BlockingChannel.scala:110)
        at kafka.producer.SyncProducer.liftedTree1$1(SyncProducer.scala:75)
        at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:74)
        at kafka.producer.SyncProducer.send(SyncProducer.scala:119)
        at kafka.client.ClientUtils$.fetchTopicMetadata(ClientUtils.scala:59)
        ... 3 more

и т.д.

В консоли продюсера я написал несколько предложений:

$ docker run --rm --interactive klustera/kafka /opt/kafka_2.11-0.9.0.1/bin/kafka-console-producer.sh --topic grillo --broker-list 171.17.0.4:9092                                                           
Hola
¿Cómo estáń?
¿Todo bien?

И через несколько мгновений я получил ответ:

[2016-03-11 00:39:28,955] ERROR Error when sending message to topic grillo with key: null, value: 4 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-03-11 00:40:28,956] ERROR Error when sending message to topic grillo with key: null, value: 16 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)
[2016-03-11 00:41:28,956] ERROR Error when sending message to topic grillo with key: null, value: 12 bytes with error: Failed to update metadata after 60000 ms. (org.apache.kafka.clients.producer.internals.ErrorLoggingCallback)

И в docker-compose logs

...
zookeeper_1 | 2016-03-11 00:39:07,072 [myid:] - INFO  [ProcessThread(sid:0 cport:2181)::[email protected]] - Got user-level KeeperException when processing sessionid:0x153631368b1000b type:create c
xid:0x2 zxid:0x47 txntype:-1 reqpath:n/a Error Path:/consumers Error:KeeperErrorCode = NodeExists for /consumers
zookeeper_1 | 2016-03-11 00:39:07,243 [myid:] - INFO  [ProcessThread(sid:0 cport:2181)::[email protected]] - Got user-level KeeperException when processing sessionid:0x153631368b1000b type:create c
xid:0x19 zxid:0x4b txntype:-1 reqpath:n/a Error Path:/consumers/console-consumer-79688/owners/grillo Error:KeeperErrorCode = NoNode for /consumers/console-consumer-79688/owners/grillo
zookeeper_1 | 2016-03-11 00:39:07,247 [myid:] - INFO  [ProcessThread(sid:0 cport:2181)::[email protected]] - Got user-level KeeperException when processing sessionid:0x153631368b1000b type:create $xid:0x1a zxid:0x4c txntype:-1 reqpath:n/a Error Path:/consumers/console-consumer-79688/owners Error:KeeperErrorCode = NoNode for /consumers/console-consumer-79688/owners
...

ОБНОВЛЕНИЕ 2

Я заработал, по крайней мере, в docker-machine:

Сначала я определил переменную с именем docker-machine:

DOCKER_VM=kafka_test

Затем я изменяю docker-compose.yml следующим образом:

KAFKA_ADVERTISED_HOST_NAME: "${DOCKER_MACHINE_IP}"

Наконец, в среде docker-machine я выполняю:

DOCKER_MACHINE_IP=$(docker-machine ip $DOCKER_VM) docker-compose up -d

Но в ноутбуке (я имею в виду, что без использования виртуальной машины это не работает)

4b9b3361

Ответ 1

Мое решение этой проблемы несколько отличается. Я настраиваю Kafka для рекламы на хосте kafka и, поскольку он отображается на главной машине в localhost:9092, я добавляю запись в /etc/hosts для kafka для разрешения на localhost. При этом Kafka может быть доступен из обоих контейнеров Docker и из локального хоста.

docker-compose.yml:

  my-web-service:
    build: ./my-web-service
    ports:
     - "8000:8000"
    links:
     - kafka
  kafka:
    image: "wurstmeister/kafka:0.10.2.0"
    ports:
     - "9092:9092"
    hostname: kafka
    links: 
     - zookeeper
    environment:
     - KAFKA_ADVERTISED_HOST_NAME=kafka
     - KAFKA_ZOOKEEPER_CONNECT=zookeeper:2181
     - KAFKA_ADVERTISED_PORT=9092
  zookeeper:
    image: wurstmeister/zookeeper
    ports:
      - "2181:2181"

Обновлен файл hosts:

more /etc/hosts
127.0.0.1       localhost kafka

Ответ 2

Для разработки приложения на локальном хосте есть решение в документации: "HOSTNAME_COMMAND"

kafka:
  image: wurstmeister/kafka
  ports:
    - 9092:9092
environment:
  KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
  HOSTNAME_COMMAND: "route -n | awk '/UG[ \t]/{print $$2}'"

Надеюсь, это поможет другим...

Ответ 3

здесь улучшенная версия ответа @radek1st.

links - это старый способ докера, networks - текущий метод.

В любом случае, внесение каких-либо системных изменений нехорошо и никогда не нужно. это также отчасти побеждает цель использования Docker.

version: '2.1'

networks:
  sb:
    driver: bridge

services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    container_name: zookeeper
    hostname: zookeeper
    networks:
     - sb
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka:
    image: confluentinc/cp-kafka:latest
    container_name: kafka
    hostname: ${KAFKA_HOSTNAME:-kafka}
    depends_on:
      - zookeeper
    networks:
     - sb
    ports:
      - "9092:9092"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
      KAFKA_ADVERTISED_HOST_NAME: ${KAFKA_HOSTNAME:-kafka}
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://${KAFKA_HOSTNAME:-kafka}:9092
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

Затем я использую следующий скрипт bash для начала. Это позволяет мне переопределить имя хоста Kafka для локальной разработки. ./startup.sh localhost

#!/bin/bash
echo KAFKA_HOSTNAME=${1:-kafka} > .env
docker-compose up -d

Читать дальше -

Ответ 4

Я полагаю, что значение, которое вы используете для KAFKA_ADVERTISED_HOST_NAME, изменится в зависимости от того, как контейнер может быть достигнут.

Если вы пытаетесь подключиться из другого контейнера, использование kafka должно быть правильным (если вы используете это имя как псевдоним ссылки).

Если вы пытаетесь подключиться к хосту, это имя не будет работать. Вам нужно будет использовать IP-адрес контейнера, который можно использовать с помощью docker inspect. Однако IP-адрес контейнера изменится, поэтому было бы лучше установить это изнутри контейнера, используя $(hostname -i), чтобы извлечь его.

Ответ 5

Просто попробуйте следующее и используйте обнаружение службы, например этот.

zookeeper:
  image: wurstmeister/zookeeper
  ports:
    - "2181:2181"
kafka:
  build: .
  ports:
    - "9092:9092"
  links:
    - zookeeper:zk
  environment:
    KAFKA_ADVERTISED_HOST_NAME: 192.168.59.103
    KAFKA_ADVERTISED_PORT: 9092
    KAFKA_CREATE_TOPICS: "test:1:1"
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock

Или вы используете этот:

zookeeper:
  image: wurstmeister/zookeeper
  ports: 
    - "2181"
kafka:
  build: .
  ports:
    - "9092"
  links: 
    - zookeeper:zk
  environment:
    KAFKA_ADVERTISED_HOST_NAME: 192.168.59.103
    DOCKER_HOST: 192.168.59.103:2375
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock

Ответ 6

Я решил эту проблему, используя приведенный ниже код:

zookeeper:
  image: wurstmeister/zookeeper
  ports:
    - "2181:2181"
kafka:
  image: wurstmeister/kafka
  ports:
    - "9092:9092"
  depends_on:
    - zookeeper
  environment:
    HOSTNAME_COMMAND: "ifconfig eth0 | grep 'inet addr' | awk '{ print $$2}' | awk -F: '{print $$2}''"
    KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock

Ответ 7

Лично у меня была проблема, потому что KAFKA_ADVERTISED_PORT: "9092" отсутствовал в среде Кафки.

 kafka:
    image : wurstmeister/kafka
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_HOST_NAME: 127.0.0.1
      KAFKA_ADVERTISED_PORT: "9092"
      KAFKA_CREATE_TOPICS: "test:1:1"
      KAFKA_ZOOKEEPER_CONNECT: zookeeper

Ответ 8

Я просто обновляю свой хост файл и добавляю:

127.0.0.1 localhost kafkaserver

Он отлично работает для меня. Я использовал тот же образ докера в Windows 10.