2016-05-18 18 views
2

Ich habe Kafka innerhalb Docker Container ausgeführt. Ich beginne meine ContainerVeröffentlichen einer Nachricht an Kafka läuft im Docker

docker run --rm -p 2181:2181 -p 9092:9092 -p 8081:8081 --env 
ADVERTISED_HOST=\`docker-machine ip \\`docker-machine active\\`` --env 
ADVERTISED_PORT=9092 -v 
/Users/abhishek.srivastava/MyProjects/KafkaTest/target/scala-2.11:/app 
-it -- name kafka spotify/kafka bash 

ich ein einfaches Programm geschrieben haben, mit dem folgenden Befehl, die ich im Inneren des Behälters kopieren und ausführen und es funktioniert perfekt.

object KafkaProducerString { 

    def SendStringMessage(msg: String) : Unit = { 
    val inputRecord = new ProducerRecord[String, String]("test", null, msg) 
    val producer: KafkaProducer[String, String] = CreateProducerString 
    val rm = producer.send(inputRecord).get(10, SECONDS) 
    println(s"offset: ${rm.offset()} partition: ${rm.partition()} topic: ${rm.topic()}") 
    producer.close() 
    } 

    private def CreateProducerString: KafkaProducer[String, String] = { 
    val props = new Properties() 
    props.put("bootstrap.servers", "localhost:9092") 
    props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer") 
    props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer") 
    props.put("batch.size", "0") 
    props.put("client.id", "1") 
    val producer = new KafkaProducer[String, String](props) 
    producer 
    } 
} 

Aber wenn ich das gleiche Programm von außerhalb des Containers (von meinem Mac) ausführen. [I ersetzen die „localhost“ mit der Ausgabe von docker-machine ip]

Ich erhalte diesen Fehler

[error] (run-main-0) java.util.concurrent.TimeoutException: Timeout after waiting for 10000 ms. 
java.util.concurrent.TimeoutException: Timeout after waiting for 10000 ms. 
    at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.get(FutureRecordMetadata.java:50) 
    at org.apache.kafka.clients.producer.internals.FutureRecordMetadata.get(FutureRecordMetadata.java:25) 
    at com.abhi.KafkaProducerString$.SendStringMessage(KafkaProducerString.scala:23) 
    at com.abhi.KafkaMain$$anonfun$main$1.apply$mcVI$sp(KafkaMain.scala:19) 
    at scala.collection.immutable.Range.foreach$mVc$sp(Range.scala:160) 
    at com.abhi.KafkaMain$.main(KafkaMain.scala:17) 
    at com.abhi.KafkaMain.main(KafkaMain.scala) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 

Mein Verständnis war, dass für einen kafka Produzenten entfernt zu sein, um die einzigen Anschlüsse brauche ich sind 2181 zu öffnen (zookeeper) und 9092 (kafka) und du kannst sehen, dass ich diese geöffnet habe.

Aber immer noch das gleiche Programm, wenn außerhalb des Containers ausgeführt wird, aber funktioniert, wenn innerhalb des Containers (mit localhost).

bearbeitet :: Auf der Grundlage der Vorschläge unten, habe ich versucht, das folgende

docker run --rm -p 127.0.0.1:2181:2181 -p 127.0.0.1:9092:9092 -p 
127.0.0.1:8081:8081 --env ADVERTISED_HOST=`docker-machine ip \`docker-machine 
active\`` --env ADVERTISED_PORT=9092 -v 
/Users/abhishek.srivastava/MyProjects/KafkaTest/target/scala-2.11:/app -it -- 
name kafka kafka_9.0 bash 

und

docker run --rm -p 0.0.0.0:2181:2181 -p 0.0.0.0:9092:9092 -p 0.0.0.0:8081:8081 
--env ADVERTISED_HOST=`docker-machine ip \`docker-machine active\`` --env 
ADVERTISED_PORT=9092 -v 
/Users/abhishek.srivastava/MyProjects/KafkaTest/target/scala-2.11:/app -it -- 
name kafka kafka_9.0 bash 

Aber das hat das Problem nicht lösen. Ich bekomme genau das gleiche Problem

+0

Hallo, ich habe auch das gleiche Problem. Hast du es gelöst? – maverick

+0

Ich habe aufgegeben :) werde es irgendwann wieder versuchen wenn ich Zeit habe. Überprüfen Sie die folgende Lösung. lass es mich wissen, wenn es funktioniert :) –

+0

Ich benutze Wurstmeister Kafka Docker. Alles funktioniert innerhalb von docker, aber mein Code für Producer/Consumer, der sich auf dem Host-Rechner befindet, kann keine Verbindung zum Kafka-Broker herstellen. Ich bin bei der Fehlersuche, wenn etwas kommt, werde ich Sie wissen lassen – maverick

Antwort

0

Sie müssen Ihren Docker-Container an den lokalen Rechner binden. Dies kann durch Verwendung Docker Lauf erfolgen, wie:

docker run --rm -p 127.0.0.1:2181:2181 -p 127.0.0.1:9092:9092 -p 127.0.0.1:8081:8081 .... 

Alternativ Sie Docker Lauf mit bind IP verwenden können:

docker run --rm -p 0.0.0.0:2181:2181 -p 0.0.0.0:9092:9092 -p 0.0.0.0:8081:8081 ..... 

Wenn Sie Docker Container routbaren in Ihrem Netzwerk machen möchten, können Sie verwenden:

docker run --rm -p <private-IP>:2181:2181 -p <private-IP>:9092:9092 -p <private-IP>:8081:8081 .... 

Oder schließlich können Sie gehen, die nicht durch die Netzwerkschnittstelle containerising mit:

docker run --rm -p 2181:2181 -p 9092:9092 -p 8081:8081 --net host .... 
+0

Ich habe versucht, die ersten beiden und sie lösten mein Problem nicht –

+0

Haben Sie die betroffenen Ports in Ihrem Dockerfile ausgesetzt? – t6nand

+0

Hier ist die Docker-Datei https://github.com/spotify/docker-kafka/blob/master/kafka/Dockerfile –

0

Während ich selbst mit dem ähnlichen Problem konfrontiert bin, kann ich versuchen, dieses Verhalten zu erklären.

Der Kafka-Produzent sucht nach dem Titel der Partition von Zookeeper, bevor er den Datensatz im Topic veröffentlicht. Der Zookeeper wird den Host-Eintrag des Anbieters haben, wie er vom Kafka-Server markiert ist, der in einem Docker-Container ausgeführt wird.

Aufgrund dieser Tatsache wird die IP vom Server markiert wird die Docker interne IP anstelle des Host-IP sein. Was natürlich nicht von der Client-Maschine auflösbar ist und daher zeitlich begrenzt ist.

Eine wahrscheinliche Lösung sein könnte, ist advertised.host.name Satz an den Host-IP der Docker Maschine. Dies wird jedoch ein anderes Problem einführen (wie ich konfrontiert!)

Broker Metadaten vom Server holen startet jetzt ausfällt. Dies liegt daran, dass der Zookeeper-Eintrag nun die Host-IP besitzt, die nicht vom Containerinneren aus aufgelöst werden kann.Als Konsequenz würde jede Verbraucheranwendung nun Warnungen erhalten.

Dies ist eine Deadlock-Situation und die Lösung hängt hauptsächlich von der Host-Auflösungsstrategie verwendet. Ich würde gerne wissen, wie die Leute hier vorgehen würden.

Verwandte Themen