15

Also mein Ziel hier ist es, einen Cluster von mehreren Kafka-Brokern in einer verteilten Art und Weise einzurichten. Aber ich kann nicht den Weg sehen, die Makler auf einander aufmerksam zu machen.Kafka auf Kubernetes multi-node

Soweit ich verstehe, benötigt jeder Broker eine separate ID in ihrer Konfiguration, die ich nicht garantieren oder konfigurieren kann, wenn ich die Container von Kubernetes starten?

Sie müssen auch den gleichen beworbenen_Host haben?

Gibt es irgendwelche Parameter, die fehlen, die geändert werden müssen, damit die Knoten sich gegenseitig entdecken?

Wäre es möglich, eine solche Konfiguration am Ende der Dockerfile mit einem Skript durchzuführen? Und/oder ein freigegebenes Volume?

Ich versuche das gerade mit dem spotify/kafka-image, das eine vorkonfigurierte zookeeper + kafka Kombination hat, auf Vanille Kubernetes.

Antwort

10

Meine Lösung dafür war Verwenden Sie die IP als ID: Trimmen Sie die Punkte und Sie erhalten eine eindeutige ID, die auch außerhalb des Containers zu anderen Containern verfügbar ist.

mit einem Service Sie Zugriff auf die mehrere Container IPs (siehe meine Antwort hier auf, wie dies zu tun bekommen. what's the best way to let kubenetes pods communicate with each other?

so können Sie ihre IDs erhalten, wenn Sie IP-Adressen als eindeutige ID verwenden das einzige Problem ist, dass IDs nicht kontinuierlich ist oder bei 0 beginnen, aber zookeeper/kafka scheint nicht in dem Sinne

EDIT. 1:

die Follow-up betrifft die Konfiguration Zookeeper:

Jeder ZK-Knoten muss die anderen Knoten kennen. Der Kubernetes Discovery Service bekannt von Knoten, die innerhalb eines Service sind, so ist die Idee, einen Service mit den ZK Knoten zu starten.

Dieser Dienst muss gestartet werden, BEVOR der ReplicationController (RC) der Zookeeper-Pods erstellt wird.

Die Inbetriebnahme wird Skript des ZK Container dann müssen:

  • Warten auf den Discovery-Dienst des ZK-Service mit seinen Knoten zu füllen (das dauert ein paar Sekunden, denn jetzt ich nur hinzufügen ein Schlaf 10 am Anfang meines Startskriptes, aber zuverlässiger sollten Sie nach dem Service suchen, um mindestens 3 Knoten darin zu haben.)
  • nachschlagen die Behälter, die den Service im Entdeckungsservice bilden: wird getan, indem man abfragt die API. Die Umgebungsvariable KUBERNETES_SERVICE_HOST ist in jedem Container verfügbar. Der Endpunkt Service Beschreibung zu finden ist dann

URL="http(s)://$USERNAME:[email protected]${KUBERNETES_SERVICE_HOST/api/v1/namespaces/${NAMESPACE}/endpoints/${SERVICE_NAME}"

wo NAMESPACEdefault ist, wenn Sie es sich geändert, und SERVICE_NAME würde zookeeper sein, wenn Sie Ihren Dienst zookeeper benannt.

Dort erhalten Sie die Beschreibung der Container, die den Dienst bilden, mit ihrer IP in einem "IP" -Feld. Sie tun können:

curl -s $URL | grep '\"ip\"' | awk '{print $2}' | awk -F\" '{print $2}' 

die Liste der IP-Adressen im Service zu erhalten. Damit bevölkern die zoo.cfg auf dem Knoten die ID über

Sie die NUTZERNAME und PASSWORT Möglicherweise müssen definiert mit den Endpunkt auf Dienste wie Google Container Motor zu erreichen. Diese müssen in einem Geheimnis Volumen gesetzt werden (siehe doc hier: http://kubernetes.io/v1.0/docs/user-guide/secrets.html)

Sie würden auch verwenden curl -s --insecure auf Google Container-Engine benötigen, wenn Sie die Mühe durch Hinzufügen der CA cert auf Ihre Schoten

Fügen Sie das Volumen dem Container hinzu, und suchen Sie die Werte aus der Datei. (Im Gegensatz zu dem, was der Doc sagt, setzen Sie nicht die \ n am Ende des Benutzername oder Passwort, wenn Base64-Kodierung: es nur das Leben noch komplizierter machen, wenn diejenigen, Lesen)

EDIT 2:

Eine weitere Sache, die Sie auf den Kafka-Knoten tun müssen, ist, die IP- und Hostnamen zu holen und sie in die Datei/etc/hosts zu schreiben. Kafka scheint die Knoten von Host-Namen kennen zu müssen, und diese werden in Service-Knoten standardmäßig nicht gesetzt

EDIT 3:

Nach viel Versuch und Gedanken unter Verwendung von IP als ID nicht so groß sein kann : Es hängt davon ab, wie Sie den Speicher konfigurieren. für jede Art von verteilter Dienst wie zoekeeper, kafka, mongo, hdfs, möchten Sie vielleicht den leeren Speicher-Typ verwenden, so dass es nur auf diesem Knoten (Montage eines Remote-Speicher Art von besiegt den Zweck der Verteilung dieser Dienste!) emptyDir wird mit den Daten auf demselben Knoten verbunden, daher erscheint es logischer, die NODE-ID (Knoten-IP) als ID zu verwenden, da dann ein Pod, der auf demselben Knoten neu startet, über die Daten verfügt. Das verhindert eine mögliche Beschädigung der Daten (wenn ein neuer Knoten in dasselbe Verzeichnis schreibt, das nicht wirklich leer ist, wer weiß, was passieren kann) und auch bei Kafka, wenn die Broker-ID geändert wird, wird den Brokern eine broker.id zugewiesen , zoekeeper aktualisiert das Thema broker.id nicht und das Thema sieht so aus, als sei es verfügbar, ABER zeigt auf die falsche broker.id und es ist ein Durcheinander.

Bis jetzt muss ich noch herausfinden, wie man den Node IP bekommt, aber ich denke, es ist möglich, in der API nachzuschlagen, indem man die Namen der Service-Pods und dann den Knoten nachschlägt.

EDIT 4

den Knoten IP zu erhalten, können Sie den pod Hostnamen == Namen von der API-Endpunkte erhalten /api/v1/Namespaces/default/Endpunkte/ wie oben erläutert. dann können Sie den Knoten IP aus dem Podname mit /api/v1/Namespaces/default/Hülsen/

PS erhalten: dies durch das Beispiel in der Kubernetes Repo (Beispiel für rethinkdb hier inspiriert: https://github.com/kubernetes/kubernetes/tree/master/examples/rethinkdb

prominent in meinen Recherchen
+0

Gute Idee! Das scheint eine machbare Lösung zu sein! Ich habe es geschafft, alle meine Broker-IDs jetzt über ein Startup-Skript zu geben: BROKER_ID = $ (ip addr | awk '/ inet/&& /eth0/{sub(/\/.*$/,"" ,$2); print $ 2} '| sed -r' s /\.// g ') und: sed -r -i "s/(makler.id) = (. *)/\ 1 = $ BROKER_ID/g" $ KAFKA_HOME/config/server.properties – NegatioN

+0

Ich habe ip = $ (hostname -i) Dann id = $ {ip //./} – MrE

+0

Kann ich auch fragen, wie Sie die Server zu /conf/zoo.cfg hinzufügen? Ein geteiltes Volume, das mit dem Kafka-Service von Kubernetes interagiert? – NegatioN

1

Ich habe diese mit Docker-compose (Der Unterschied für Kubernetes wäre, dass Sie die ID über Ihre service.yaml passieren würde und haben 2-Dienste):

kafka1: 
    build: kafka-0.8.1/ 
    ports: 
    - 9092 
    links: 
    - zookeeper 
    environment: 
    - ID=1 
kafka2: 
    build: kafka-0.8.1/ 
    ports: 
    - 9092 
    links: 
    - zookeeper 
    environment: 
    - ID=2 

Config:

broker.id=${ID} 
port=9092 
advertised.host.name=${HOST} 
advertised.port=9092 
num.network.threads=3 
num.io.threads=8 
socket.send.buffer.bytes=102400 
socket.receive.buffer.bytes=102400 
socket.request.max.bytes=104857600 
log.dirs=/kafka/kafka-logs-${ID} 
num.partitions=200 
num.recovery.threads.per.data.dir=1 
log.retention.hours=168 
log.segment.bytes=1073741824 
log.retention.check.interval.ms=300000 
log.cleaner.enable=false 
zookeeper.connect=${DOCKER_ZOOKEEPER_1_PORT_2181_TCP_ADDR}:${DOCKER_ZOOKEEPER_1_PORT_2181_TCP_PORT} 
zookeeper.connection.timeout.ms=6000 

sh:

#!/bin/bash 
echo "Running config" 
export HOST=`grep $HOSTNAME /etc/hosts | awk '{print $1}'` 
export ID=${ID:?} 
perl -p -i -e 's/\$\{([^}]+)\}/defined $ENV{$1} ? $ENV{$1} : $&/eg' </broker.template> $KAFKA_HOME/config/server.properties 
echo "Done" 
echo "starting kafka with:" 
echo "$KAFKA_HOME/config/server.properties" 
echo "" 
cat $KAFKA_HOME/config/server.properties 
$KAFKA_HOME/bin/kafka-server-start.sh $KAFKA_HOME/config/server.properties 
+0

Sind Sie sicher, dass es möglich ist, Umgebungsvariablen über einen Kubernetes-Service zu übergeben? Denn anders kann ich das als Lösung sehen. – NegatioN

+0

Es gibt einen Weg: https://github.com/kubernetes/kubernetes/issues/4710 – JuanIsFree

+0

Dies bezieht sich auf die Weitergabe von Umgebungsvariablen in Pods oder ReplicationControllern? Ich bin mir bewusst, dass dies möglich ist, aber bedeutet dies auch, dass es in einem Service durchgeführt werden kann? – NegatioN

2

Dies zeigt sich aber enthält ziemlich veraltete Informationen. um dies zu aktualisieren, mit einer moderneren Lösung, sollten Sie Verwenden Sie eine StatefulSet Bereitstellung, die erzeugt Pods, die einen Integer-Counter anstelle eines Hashs in ihrem Namen haben, z. kafka-controller-0.

Dies ist natürlich der Hostname, so von dort aus ist es eine einfache Angelegenheit ist ein festen, unveränderlichen Broker-ID zu extrahieren awk mit:

hostname | awk -F'-' '{print $3}' 

Die beliebtestenen Behälter für Kafka hat in diesen Tagen einen Broker-ID-Befehl .

Verwandte Themen