一尘不染

Kubernetes多节点上的Kafka

docker

因此,我的目标是以分布式方式建立一个由多个kafka经纪人组成的集群。但是我看不出让经纪人彼此了解的方法。

据我了解,每个代理在其配置中都需要一个单独的ID,如果我从Kubernetes启动容器,我不能保证或配置该ID吗?

他们还需要具有相同的advertised_host吗?

是否有我需要更改的参数才能使节点相互发现?

在Dockerfile的末尾使用脚本进行这样的配置是否可行?和/或共享卷?

我目前正在尝试在香草Kubernetes上使用具有预先配置的zookeeper + kafka组合的spotify / kafka-image进行此操作。


阅读 306

收藏
2020-06-17

共1个答案

一尘不染

我的解决方案是 使用IP作为ID :修剪点,您将获得一个唯一的ID,该ID在容器外部也可用于其他容器。

借助服务,您可以访问多个容器的IP(有关如何执行此操作的信息,请参见此处的答案:
让kubenetes容器彼此通信的最佳方法是什么?

因此,如果您使用IP作为唯一ID,也可以获取其ID。唯一的问题是ID并不是连续的,也不是从0开始的,但是zookeeper / kafka似乎并不介意。

编辑1:

后续操作涉及配置Zookeeper:

每个ZK节点都需要知道其他节点。是一个内节点的Kubernetes发现服务的已知, 服务 这样的想法是启动 服务 与ZK节点。

在创建Zookeeper容器的ReplicationController(RC)之前,需要启动此服务。

ZK容器的启动脚本将需要:

  • 等待发现服务用其节点填充ZK服务(这需要几秒钟,现在我仅在启动脚本的开头添加sleep 10,但更可靠的是,您应该寻找至少有3个节点的服务在里面。)
  • 在发现服务中查找构成服务的容器:这是通过查询API来完成的。的KUBERNETES_SERVICE_HOST环境变量是在每个容器中提供。然后找到服务描述的端点

URL="http(s)://$USERNAME:$PASSWORD@${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 才能到达诸如Google容器引擎之类的服务上的端点。这些文件需要放在一个 秘密
卷中(请参阅此处的文档:http :
//kubernetes.io/v1.0/docs/user-
guide/secrets.html

curl -s --insecure除非您遇到将CA证书添加到Pod的麻烦,否则还需要在Google Container Engine 上使用

基本上将卷添加到容器,然后从文件中查找值。(与文档所说的相反,在进行base64编码时,请勿将\ n放在用户名或密码的末尾:这只会使您的生活更加复杂)

编辑2:

您需要在Kafka节点上做的另一件事是获取IP和主机名,并将它们放在/ etc /
hosts文件中。Kafka似乎需要通过主机名知道节点,并且默认情况下未在服务节点内设置这些名称

编辑3:

经过大量的尝试和思考,使用IP作为ID可能并不那么好:这取决于您如何配置存储。对于任何种类的分布式服务(例如zookeeper,kafka,mongo,hdfs),您可能希望使用emptyDir类型的存储,因此它只是在该节点上(安装远程存储会破坏分发这些服务的目的!)emptyDir将在同一节点上重新使用数据,因此使用NODE
ID(节点IP)作为ID似乎更合乎逻辑,因为在同一节点上重新启动的Pod将具有数据。这样可以避免潜在的数据损坏(如果一个新节点开始在实际上不为空的同一目录中开始写入,谁知道会发生什么情况),还可以避免使用Kafka,为该主题分配一个broker.id,如果broker
id更改, zookeeper不会更新主题代理。

到目前为止,我还没有找到如何获取节点IP的方法,但是我认为可以通过查找服务容器名称然后部署它们的节点来查找API。

编辑4

要获取节点IP,您可以从端点API / api / v1 / namespaces / default / endpoints
/中获取pod主机名==名称,如上所述。那么您可以使用/ api / v1 / namespaces / default / pods
/从容器名称中获取节点IP

PS:这是受到Kubernetes回购中的示例的启发(此处为rethinkdb的示例:https//github.com/kubernetes/kubernetes/tree/master/examples/rethinkdb

2020-06-17