したがって、ここでの目的は、分散した方法で複数のカフカブローカーのクラスターをセットアップすることです。しかし、私はブローカーにお互いを意識させる方法を見ることができません。
私が理解している限り、すべてのブローカーはその構成に個別のIDを必要としますが、kubernetesからコンテナーを起動した場合、保証または構成できません。
また、同じadvertised_hostが必要ですか?
ノードがお互いを発見するために変更する必要がある欠落しているパラメーターはありますか?
Dockerfileの最後でスクリプトを使用してこのような構成を行うのは現実的でしょうか?および/または共有ボリューム?
私は現在、Vanilla Kubernetesで、事前に構成されたzookeeperとkafkaの組み合わせが含まれているspotify/kafka-imageを使用してこれを実行しようとしています。
これに対する私の解決策は、IPをIDとして使用することです:ドットをトリミングすると、コンテナの外部でも使用できる一意のIDが取得されます。他のコンテナ。
サービスを使用すると、複数のコンテナーのIPにアクセスできます(これを行う方法については、私の回答を参照してください: kubenetesポッドを相互に通信させる最良の方法は何ですか?
そのため、一意のIDとしてIPを使用する場合も、それらのIDを取得できます。唯一の問題は、IDが連続していないか、0から始まることですが、zookeeper/kafka気にしないようです。
編集1:
Zookeeperの構成に関するフォローアップ:
各ZKノードは他のノードを認識している必要があります。 Service内にあるノードのKubernetes検出サービスの既知なので、ServiceZKノード。
このサービスは、ZookeeperポッドのReplicationController(RC)を作成する前に開始する必要があります。
ZKコンテナの起動スクリプトは、次のようにする必要があります。
KUBERNETES_SERVICE_Host
_環境変数は、各コンテナーで使用できます。サービスの説明を見つけるためのエンドポイントはURL="http(s)://$USERNAME:$PASSWORD@${KUBERNETES_SERVICE_Host/api/v1/namespaces/${NAMESPACE}/endpoints/${SERVICE_NAME}"
ここで、NAMESPACE
は変更しない限りdefault
であり、サービスズーキーパーに名前を付けた場合、_SERVICE_NAME
_はズーキーパーになります。
そこでは、サービスを形成するコンテナの説明が得られ、その「ip」フィールドにそれらのIPが表示されます。できるよ:
_curl -s $URL | grep '\"ip\"' | awk '{print $2}' | awk -F\" '{print $2}'
_
サービス内のIPのリストを取得します。これで、上記で定義したIDを使用してノードにZoo.cfgを入力します
[〜#〜] username [〜#〜]と[〜#〜] password [〜#〜]googleコンテナーエンジンなどのサービスのエンドポイントに到達する。これらはSecretボリュームに配置する必要があります(ここのドキュメントを参照してください: http://kubernetes.io/v1.0/docs/ user-guide/secrets.html )
また、ポッドにCA証明書を追加する問題が発生しない限り、Google Container Engineで_curl -s --insecure
_を使用する必要があります。
基本的にボリュームをコンテナーに追加し、ファイルから値を検索します。 (ドキュメントに書かれていることとは逆に、base64エンコーディングの場合は、ユーザー名またはパスワードの最後に\ nを付けないでください。これらを読むと、生活が複雑になります)
編集2:
Kafkaノードで行う必要があるもう1つのことは、IPとホスト名を取得し、それらを/ etc/hostsファイルに配置することです。Kafkaのようですホスト名でノードを認識する必要があり、これらはデフォルトではサービスノード内に設定されていません
編集3:
IPをIDとして使用して多くの試行錯誤を繰り返した結果、それほど優れていない可能性があります。ストレージの構成方法によって異なります。 zookeeper、kafka、mongo、hdfsなどのあらゆる種類の分散サービスの場合、emptyDirタイプのストレージを使用することができます。そのため、そのノード上にのみ存在します(リモートストレージの種類をマウントすると、これらのサービスを配布する目的が無効になります!)emptyDir同じノード上のデータで再ロードするため、IDとしてNODE ID(ノードIP)を使用する方が論理的です。同じノードで再起動するポッドにデータがあるためです。これにより、データが破損する可能性を回避できます(新しいノードが実際には空ではない同じディレクトリに書き込みを開始した場合、何が起こり得るかを知っています)。また、ブローカーIDが変更された場合に、ブローカーIDがトピックに割り当てられているKafka zookeeperはトピックbroker.idを更新せず、トピックは使用可能であるように見えますが、間違ったbroker.idをポイントしており、混乱しています。
これまでのところ、ノードIPを取得する方法はまだわかりませんが、サービスポッド名と、それらがデプロイされているノードを検索することで、APIを検索することは可能だと思います。
EDIT 4
ノードIPを取得するには、前述のように、エンドポイントAPI/api/v1/namespaces/default/endpoints /からポッドホスト名==名前を取得できます。次に、/ api/v1/namespaces/default/pods /を使用してポッド名からノードIPを取得できます
PS:これは、Kubernetesリポジトリの例にヒントを得ています(rethinkdbの例: https://github.com/kubernetes/kubernetes/tree/master/examples/rethinkdb
これは私の検索で目立つように表示されますが、かなり古い情報が含まれています。これをより最新のソリューションで更新するには、 StatefulSet デプロイメントを使用する必要があります。これにより、名前にハッシュの代わりに整数カウンターを持つポッドが生成されます。 kafka-controller-0。
これはもちろんホスト名なので、そこからawkを使用して固定された不変のブローカーIDを抽出するのは簡単です。
hostname | awk -F'-' '{print $3}'
Kafka最近利用できる最も人気のあるコンテナには、ブローカーIDコマンドがあります。
https://github.com/CloudTrackInc/kubernetes-kafka を見てください。Kafka kubernetesで開始することができ、スケーリングと自動拡張をサポートしています。
私はdocker-composeを使用してこれを行いました(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