15

因此,我的目標是以分佈式方式建立幾個卡夫卡經紀人集羣。但我看不出讓經紀人意識到彼此的方式。Kubernetes多節點上的卡夫卡

據我瞭解,每個經紀人都需要在他們的配置中有一個單獨的ID,如果我從kubernetes啓動容器,我無法保證或配置它。

他們還需要有相同的advertised_host?

是否有任何我缺少的參數需要更改,以便節點互相發現?

是否可以通過腳本在Dockerfile的末尾執行這樣的配置?和/或共享音量?

我目前正在嘗試使用spotify/kafka-image,在香草Kubernetes上有一個預配置的zookeeper + kafka組合。

回答

10

我對此的解決方案一直以使用IP作爲ID:修剪點並且您將獲得一個唯一的ID,該ID也可在容器外部提供給其他容器。

與服務,你可以訪問到多個容器的IPS(見我的答案在這裏如何做到這一點: what's the best way to let kubenetes pods communicate with each other?

所以你可以,如果你使用的IP作爲唯一的ID獲得它們的ID太 唯一的問題是,ID是不連續的或從0開始,但動物園管理員/卡夫卡似乎並不介意做

編輯1:

的跟進關注配置動物園管理員:

每個ZK節點需要知道其他節點。 Kubernetes發現服務知道在服務內的節點,所以想法是啓動帶有ZK節點的服務

此服務需要在創建Zookeeper pod的ReplicationController(RC)之前啓動。

的ZK容器的啓動腳本然後將需要:

  • 等待發現服務,其節點(即需要幾秒鐘,現在我只需添加填充ZK服務在我的啓動腳本的開頭睡眠10,但更可靠,你應該尋找服務,至少有3個節點在它)
  • 查找中發現服務形成服務容器: 這是通過查詢完成API。 KUBERNETES_SERVICE_HOST環境變量在每個容器中都可用。 找到服務描述端點然後

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

其中NAMESPACEdefault,除非你改變它,SERVICE_NAME將飼養員,如果你命名你的服務飼養員。

有你形成服務容器的描述,他們在「IP」字段中的IP。 你可以這樣做:

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

得到的服務IP地址的列表。 就這樣,填充使用上述

定義的ID的節點上的zoo.cfg您可能需要USERNAMEPASSWORD對像谷歌容器引擎服務到達終點。這些都需要放在一個祕密卷(請參閱文檔在這裏:http://kubernetes.io/v1.0/docs/user-guide/secrets.html

您還需要使用curl -s --insecure在谷歌集裝箱引擎,除非你通過添加CA證書到你的豆莢的麻煩

基本上將卷添加到容器,並從文件中查找值。 (相反的是對醫生說,不要把\ n的用戶名或密碼的末尾時base64編碼:它只是讓你的生活更加複雜,讀那些時)

編輯2:

您需要在Kafka節點上執行的另一件事是獲取IP和主機名,並將它們放在/ etc/hosts文件中。 卡夫卡似乎需要知道主機名的節點,這些不是默認的服務節點中設置

編輯3:

後使用IP作爲一個ID多次試驗和思想可能沒那麼大:這取決於你如何配置存儲。 對於任何一種像動物園管理員分佈式服務的,卡夫卡,蒙戈,HDFS,你可能想使用emptyDir類型的存儲,所以它只是在該節點上(安裝遠程存儲樣的失敗分發這些服務的宗旨!) emptyDir將用相同的節點上的數據relaod,因此它似乎更多的邏輯以使用節點ID(節點IP)作爲ID,因爲那時,在同一節點上重新啓動吊艙將具有該數據。 這樣可以避免潛在的數據損壞(如果新節點開始在實際上不是空的相同目錄中寫入,誰知道會發生什麼)以及Kafka,如果代理ID發生更改,則分配給broker.id的主題,zookeeper不會更新主題broker.id並且該主題看起來像可用但是指向錯誤的broker.id並且它是一團糟。

到目前爲止,我還沒有找到如何獲得節點IP,但我認爲可以通過查找服務pod名稱以及它們所在的節點來查找API。

EDIT 4

爲了得到節點的IP,就可以得到主機莢==從端點API /API/V1 /命名空間/默認/端點/ 如上所述名。 那麼你可以從莢名稱的節點IP與 /API/V1 /命名空間/默認/莢/

PS:這是由在Kubernetes回購(這裏的例子爲rethinkdb例子啓發:https://github.com/kubernetes/kubernetes/tree/master/examples/rethinkdb

+0

好主意!這似乎是一個可行的解決方案!我現在通過一個啓動腳本來設置所有代理ID:BROKER_ID = $(ip addr | awk'/ inet/&& /eth0/{sub(/\/.*$/,"",$2);打印$ 2}'| sed -r's /\.// g')和:sed -r -i「s /(broker.id)=(。*)/ \ 1 = $ BROKER_ID/g」$ KAFKA_HOME/config/server.properties – NegatioN

+0

我用ip = $(hostname -i)然後id = $ {ip //./} – MrE

+0

我還可以問你如何將服務器添加到/conf/zoo.cfg?與Kubernetes的Kafka服務交互的共享卷? – NegatioN

1

我這樣做是使用泊塢窗 - 撰寫(用於Kubernetes所不同的是,你會通過你的service.yaml通過ID和有2個服務):

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 

配置:

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

您確定可以通過kubernetes服務傳遞環境變量嗎?因爲除此之外,我可以將其視爲解決方案。 – NegatioN

+0

有一種方法: https://github.com/kubernetes/kubernetes/issues/4710 – JuanIsFree

+0

這是關於在Pods或ReplicationControllers中傳遞環境變量的?我知道這是可能的,但這是否也意味着它可以在服務中完成? – NegatioN

2

這突出地顯示在我的搜索,但包含了相當過時的信息。要以更加現代化的解決方案更新了,你應該使用一個StatefulSet部署,其中將生成具有整數計數器而不是哈希名稱的莢,例如。卡夫卡控制器-0。

這是當然的主機名,所以從那裏它是一個簡單的事情用awk提取固定的,不變的經紀人ID:

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

最流行的容器可用於卡夫卡這些天一直經紀人ID命令。