Взаимодействие с контейнером докеров kafka извне хоста докеров

Я создал контейнер докеров kafka и оркестровал его с помощью docker-compose.

Позвонив docker ps, я получаю следующий ввод:

CONTAINER ID        IMAGE                          COMMAND                CREATED             STATUS              PORTS                                         NAMES
    5bde6f76246e        hieutrtr/docker-kafka:0.0.1    "/start.sh"            About an hour ago   Up About an hour    7203/tcp, 0.0.0.0:32884->9092/tcp             dockerkafka_kafka_3
    be354f1b8cc0        hieutrtr/docker-ubuntu:devel   "/usr/bin/supervisor   About an hour ago   Up About an hour    22/tcp                                        producer1
    50d3203af90e        hieutrtr/docker-kafka:0.0.1    "/start.sh"            About an hour ago   Up About an hour    7203/tcp, 0.0.0.0:32883->9092/tcp             dockerkafka_kafka_2
    61b285f39615        hieutrtr/docker-kafka:0.0.1    "/start.sh"            2 hours ago         Up 2 hours          7203/tcp, 0.0.0.0:32882->9092/tcp             dockerkafka_kafka_1
    20c9c5ccec05        jplock/zookeeper:3.4.6         "/opt/zookeeper/bin/   2 hours ago         Up 2 hours          2888/tcp, 3888/tcp, 0.0.0.0:32881->2181/tcp   dockerkafka_zookeeper_1

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

Например:

Я запускаю продюсер kafka на моем локальном хосте, и появляется следующая ошибка:

$ kafka_2.9.1-0.8.2.1: bin/kafka-console-producer.sh --topic test --broker-list $DOCKER_HOST:32884
[2015-08-31 06:55:15,450] WARN Property topic is not valid (kafka.utils.VerifiableProperties)
to
[2015-08-31 06:55:20,214] WARN Failed to send producer request with correlation id 2 to broker 1 with data for partitions [test,0] (kafka.producer.async.DefaultEventHandler)
java.nio.channels.ClosedChannelException
    at kafka.network.BlockingChannel.send(BlockingChannel.scala:100)
    at kafka.producer.SyncProducer.liftedTree1$1(SyncProducer.scala:73)
    at kafka.producer.SyncProducer.kafka$producer$SyncProducer$$doSend(SyncProducer.scala:72)
    at kafka.producer.SyncProducer$$anonfun$send$1$$anonfun$apply$mcV$sp$1.apply$mcV$sp(SyncProducer.scala:103)
    at kafka.producer.SyncProducer$$anonfun$send$1$$anonfun$apply$mcV$sp$1.apply(SyncProducer.scala:103)
    at kafka.producer.SyncProducer$$anonfun$send$1$$anonfun$apply$mcV$sp$1.apply(SyncProducer.scala:103)

Это мой пример докера kafka на github, который включает упомянутую проблему.

Итак, кто-нибудь испытывает те же проблемы и может мне чем-то помочь?

Дополнительная информация:

(Просто создайте вилку из ches / kafka и измените что-нибудь для docker-compose):


person Trung Hiếu Trần    schedule 31.08.2015    source источник


Ответы (5)


В свойствах сервера Kafka вам нужно установить advertised.host.name и advertised.port на ip / порт вашего запущенного контейнера, и тогда он должен работать.

person Lundahl    schedule 31.08.2015
comment
Думаю, проблема не в этом. Потому что я все еще создаю тему со своего локального хоста. Есть что-нибудь о java.rmi ....? - person Trung Hiếu Trần; 31.08.2015
comment
Это то, что помогло мне при очень похожих симптомах. Я мог создавать темы из localhost или других контейнеров, но не публиковать сообщения, пока не установил advertised.host.name - person Lundahl; 31.08.2015
comment
что мы должны указать как Advertised.host.name? Столкнувшись с той же проблемой - person Siddharth Gupta; 30.11.2016

Вот мои два цента, так как мне было трудно понять это.

Мой $ KAFKA_HOME / config / server.properties содержит следующее:

listener.security.protocol.map=INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT

advertised.listeners=INSIDE://${container_ip}:9092,OUTSIDE://${outside_host_ip}:29092

listeners=INSIDE://:9092,OUTSIDE://:29092

inter.broker.listener.name=INSIDE

Это создает два соединения, одно для использования внутри докера, а другое для использования снаружи. Для последнего вы должны выбрать новый порт, в моем случае 29092, убедитесь, что этот порт открыт и отображается докером.

Я еще не смог найти решение без $ {outside_host_ip} в среде, поэтому я предоставляю ip хост-машины как env var.

Контрольная работа:

  1. Войдите в контейнер Kafka и создайте тему: ./kafka-topics.sh -zookeeper zookeeper:2181 --create --topic dummytopic --partitions 1 --replication-factor 1
  2. Извне контейнера Kafka выполните: ./kafka-console-producer.sh --broker-list 0.0.0.0:29092 --topic dummytopic и введите сообщение

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

person João Matos    schedule 12.04.2019

Вам нужно указать имя хост-машины, на которой был развернут экземпляр докера. Также вам необходимо сопоставить порты с хост-машины докера (общедоступной) с экземпляром контейнера докера (частным).

person sivakadi    schedule 06.12.2016
comment
Также убедитесь, что вы не установили какие-либо связанные свойства в server.properties - person sivakadi; 07.12.2016
comment
Извините, нажмите "Enter" слишком рано. - person sivakadi; 07.12.2016
comment
Простите за мое первое использование. Значения, установленные в server.properties, имеют приоритет, и, по моему опыту, по умолчанию используется порт 9092. Я запускаю dev и qa docker Kafka в той же Kafka. Ничего не установил порт, но использовал открытые порты из контейнера докеров как 9092. Сопоставление этих портов с портом хоста public / docker на 9092 и 9192 для dev и qa соответственно. - person sivakadi; 07.12.2016

TL; DR Откройте порт 9092 на хосте и сопоставьте его с портом контейнера 9092 для доступа к брокерам kafka вне контейнера. Подробнее см. В документации по docker-compose.

Я думаю, проблема в том, что вы не открываете порт 9092 за пределами контейнера. Согласно вашему списку docker ps, ваш порт контейнера 9092 динамически сопоставляется с диапазоном портов хоста 32882-32884. Когда вы подключаетесь к брокеру, настроенному таким образом, вы получаете метаданные, которые содержат порт 9092 для рекламы. С помощью этих метаданных производитель пытается выполнить другие запросы через порт 9092 и терпит неудачу.

person Oleksandr Galperin    schedule 21.12.2017

Для справки, еще один способ заставить моего локального потребителя kafka общаться с удаленным брокером внутри контейнера Docker - добавить запись в мой / etc / hosts: docker-host-ip-address docker -kafka-container-hostname

В любом случае решение Lundahl сработало для меня и кажется более чистым. Еще лучше было бы установить Advertised.listeners = host-ip: port, поскольку Advertised.host.name и Advertised.port устарели.

person manucho    schedule 13.03.2018