Kafka su Kubernetes multi-nodo

Quindi il mio objective è quello di creare un gruppo di diversi mediatori di kafka in modo distribuito. Ma non riesco a vedere il modo di rendere i mediatori consapevoli.

Per quanto mi riguarda, each broker ha bisogno di un ID separato nella configuration, che non posso garantire o configurare se lancio i contenitori da kubernetes?

Hanno anche bisogno di avere lo stesso advertised_host?

Ci sono parametri che mi manca che dovrebbero essere cambiati per i nodes per scoprire l'altro?

Sarebbe conveniente fare una tale configuration alla fine del Dockerfile con uno script? E / o un volume condiviso?

Attualmente sto cercando di farlo con la spotify / kafka-image che ha una combinazione preconfigurata di zookeeper + kafka, su vanilla Kubernetes.

La mia soluzione per questo è stata quella di utilizzare l'IP come ID : tagliare i punti e get un ID univoco che è disponibile anche al di fuori del contenitore in altri contenitori.

Con un servizio è ansible accedere ai IP multipli dei container (vedere la mia risposta qui su come farlo: qual è il modo migliore per lasciare i kubenetes pods comunicare tra loro?

in modo da poter get i loro ID anche se utilizzi IP come ID univoco. L'unico problema è che gli ID non sono continui o iniziano a 0, ma lo zookeeper / kafka non sembra mente.

EDIT 1:

Il follow up riguarda la configuration di Zookeeper:

Ogni nodo ZK deve conoscere gli altri nodes. Il servizio di scoperta Kubernetes noto di nodes che si trovano all'interno di un servizio, quindi l'idea è di avviare un servizio con i nodes ZK.

Questo servizio deve essere avviato prima di creare il ReplicationController (RC) dei baccelli Zookeeper.

Lo script di avvio del contenitore ZK dovrà quindi:

  • attendere che il servizio di scoperta popolga il servizio ZK con i suoi nodes (che richiedono alcuni secondi, per ora aggiungo solo un sonno 10 all'inizio del mio script di avvio, ma più affidabile dovresti cercare che il servizio abbia alless 3 nodes dentro.)
  • cercare i contenitori che creano il servizio nel servizio di ricerca: questo viene fatto interrogando l'API. la variabile di ambiente KUBERNETES_SERVICE_HOST è disponibile in each contenitore. È quindi l'endpoint per trovare la descrizione del servizio

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

where NAMESPACE è default less che non l'hai modificato e SERVICE_NAME sarebbe zookeeper se hai chiamato il tuo zookeeper del servizio.

si ottiene la descrizione dei contenitori che formano il Servizio, con il loro ip in un field "ip". Tu puoi fare:

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

per get l'elenco di IP nel Servizio. Con questo, popolare lo zoo.cfg sul nodo utilizzando l'ID definito in precedenza

Potrebbe essere necessario che USERNAME e PASSWORD raggiungano l'endpoint su servizi come il motore di container google. Questi devono essere messi in un volume segreto (vedi doc qui: http://kubernetes.io/v1.0/docs/user-guide/secrets.html )

Dovresti anche usare curl -s --insecure sul motore di Google Container a less che non si superi il problema di aggiungere il certificato CA ai tuoi baccelli

Fondamentalmente aggiungere il volume al contenitore e cercare i valori dal file. (contrariamente a quanto dice il doc, NON metti il ​​\ n alla fine del nome utente o della password quando codifica base64: basta rendere la tua vita più complicata quando si legge)

EDIT 2:

Un'altra cosa che dovrai fare sui nodes Kafka è get l'IP e i nomi di host e inserirli nel file / etc / hosts. Kafka sembra avere bisogno di conoscere i nodes da parte dei nomi host e questi non sono impostati per i nodes di servizio per impostazione predefinita

EDIT 3:

Dopo molti tentativi e pensieri che utilizzano IP come ID potrebbero non essere così grandi: dipende da come configurare l'archiviazione. per qualsiasi tipo di servizio distribuito come zookeeper, kafka, mongo, hdfs, si potrebbe desiderare di utilizzare il tipo di archiviazione emptyDir, quindi è proprio su quel nodo (assembly di un tipo di sconfitta remoto allo scopo di distribuire questi servizi!) emptyDir relaod con i dati sullo stesso nodo, quindi sembra più logico utilizzare l'ID NODE (nodo IP) come ID, perché quindi un pod che riavvia sullo stesso nodo avrà i dati. Questo evita la potenziale danneggiamento dei dati (se un nuovo nodo inizia a scrivere nello stesso dir che non è effettivamente vuoto, chissà cosa può succedere) e anche con Kafka, gli argomenti assegnati a un broker.id, se l'id del broker cambia, zookeeper non aggiorna l'argomento del broker.id e l'argomento sembra che sia disponibile MA punti sul broker.id sbagliato ed è un casino.

Finora non ho ancora trovato come get il IP del nodo, ma penso che sia ansible cercare nell'API guardando i nomi dei nodes di servizio e poi il nodo in cui vengono distribuiti.

EDIT 4

Per get il nodo IP, è ansible get il nome pod hostname == da endpoint API / api / v1 / namespaces / default / endpoints / come sopra illustrato. allora è ansible get il nodo IP dal nome del pod con / api / v1 / namespaces / default / pods /

PS: questo è ispirato dall'esempio del repo Kubernetes (esempio per rethinkdb qui: https://github.com/kubernetes/kubernetes/tree/master/examples/rethinkdb

Guarda https://github.com/CloudTrackInc/kubernetes-kafka Permette di avviare Kafka in kubernetes e supportrla in scala e estendere automaticamente.

Ho fatto questo con il compositore docker (la differenza per Kubernetes sarebbe che passeresti l'ID attraverso il tuo service.yaml e avrai 2 servizi):

 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.networkingntion.hours=168 log.segment.bytes=1073741824 log.networkingntion.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