如何在Kubernetes中对外公开StatefulSet的无头服务 [英] How to expose a headless service for a StatefulSet externally in Kubernetes
问题描述
使用 kubernetes-kafka 作为minikube的起点.
Using kubernetes-kafka as a starting point with minikube.
这使用StatefulSet和无头服务进行服务在集群中发现.
This uses a StatefulSet and a headless service for service discovery within the cluster.
目标是在外部公开各个Kafka经纪人,这些经纪人内部地址为:
The goal is to expose the individual Kafka Brokers externally which are internally addressed as:
kafka-0.broker.kafka.svc.cluster.local:9092
kafka-1.broker.kafka.svc.cluster.local:9092
kafka-2.broker.kafka.svc.cluster.local:9092
约束是该外部服务能够专门针对经纪人.
The constraint is that this external service be able to address the brokers specifically.
解决此问题的正确方法(或一种可能的方法)是什么?是否可以根据kafka-x.broker.kafka.svc.cluster.local:9092
公开外部服务?
Whats the right (or one possible) way of going about this? Is it possible to expose a external service per kafka-x.broker.kafka.svc.cluster.local:9092
?
推荐答案
到目前为止,解决方案还不足以让我自己满意,所以我将发表自己的答案.我的目标:
Solutions so far weren't quite satisfying enough for myself, so I'm going to post an answer of my own. My goals:
- 仍应通过StatefulSet尽可能多地动态管理Pod.
- 在每个Pod(即Kafka Broker)中为生产者/消费者客户端创建外部服务,并避免负载平衡.
- 创建内部无头服务,以便每个Broker可以彼此通信.
从 Yolean/kubernetes-kafka 开始,唯一缺少的是在外部公开该服务,这样做有两个挑战.
Starting with Yolean/kubernetes-kafka, the only thing missing is exposing the service externally and two challenges in doing so.
- 为每个Broker容器生成唯一的标签,以便我们可以为每个Broker容器创建一个外部服务.
- 在配置Kafka告诉生产者/消费者通过外部服务进行通信的同时,告诉经纪人使用内部服务进行相互通信.
每个吊舱标签和外部服务:
要为每个吊舱生成标签,此问题确实很有帮助.以此为指导,我们将以下行添加到 10broker-config.yml init.sh
属性,其中:
To generate labels per pod, this issue was really helpful. Using it as a guide, we add the following line to the 10broker-config.yml init.sh
property with:
kubectl label pods ${HOSTNAME} kafka-set-component=${HOSTNAME}
我们保留了现有的无头服务,但是我们还使用标签为每个pod生成了一个外部服务(我将它们添加到
We keep the existing headless service, but we also generate an external Service per pod using the label (I added them to 20dns.yml):
apiVersion: v1
kind: Service
metadata:
name: broker-0
namespace: kafka
spec:
type: NodePort
ports:
- port: 9093
nodePort: 30093
selector:
kafka-set-component: kafka-0
使用内部/外部监听器配置Kafka
我发现此问题在试图了解如何配置Kafka方面非常有用
I found this issue incredibly useful in trying to understand how to configure Kafka.
这又需要更新 10broker-config.yml ,其中包含以下内容:
This again requires updating the init.sh
and server.properties
properties in 10broker-config.yml with the following:
在server.properties
中添加以下内容以更新安全协议(当前使用PLAINTEXT
):
Add the following to the server.properties
to update the security protocols (currently using PLAINTEXT
):
listener.security.protocol.map=INTERNAL_PLAINTEXT:PLAINTEXT,EXTERNAL_PLAINTEXT:PLAINTEXT
inter.broker.listener.name=INTERNAL_PLAINTEXT
动态确定init.sh
中每个Pod的外部IP和外部端口:
Dynamically determine the external IP and for external port for each Pod in the init.sh
:
EXTERNAL_LISTENER_IP=<your external addressable cluster ip>
EXTERNAL_LISTENER_PORT=$((30093 + ${HOSTNAME##*-}))
然后为EXTERNAL_LISTENER
和INTERNAL_LISTENER
(也在init.sh
属性中)配置listeners
和advertised.listeners
IP:
Then configure listeners
and advertised.listeners
IPs for EXTERNAL_LISTENER
and INTERNAL_LISTENER
(also in the init.sh
property):
sed -i "s/#listeners=PLAINTEXT:\/\/:9092/listeners=INTERNAL_PLAINTEXT:\/\/0.0.0.0:9092,EXTERNAL_PLAINTEXT:\/\/0.0.0.0:9093/" /etc/kafka/server.properties
sed -i "s/#advertised.listeners=PLAINTEXT:\/\/your.host.name:9092/advertised.listeners=INTERNAL_PLAINTEXT:\/\/$HOSTNAME.broker.kafka.svc.cluster.local:9092,EXTERNAL_PLAINTEXT:\/\/$EXTERNAL_LISTENER_IP:$EXTERNAL_LISTENER_PORT/" /etc/kafka/server.properties
很明显,这不是完整的生产解决方案(例如,解决外部暴露的经纪人的安全问题),并且我仍在加深对如何让内部生产者/消费者也与经纪人进行沟通的理解.
Obviously, this is not a full solution for production (for example addressing security for the externally exposed brokers) and I'm still refining my understanding of how to also let internal producer/consumers to also communicate with the brokers.
但是,到目前为止,这是我了解Kubernetes和Kafka的最佳方法.
However, so far this is the best approach for my understanding of Kubernetes and Kafka.
这篇关于如何在Kubernetes中对外公开StatefulSet的无头服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!