Nad*_*far 49 apache-kafka kubernetes
使用kubernetes-kafka作为minikube的起点.
这使用StatefulSet和无头服务在集群内进行服务发现.
目标是在外部公开个人Kafka经纪人,这些经纪人在内部被称为:
kafka-0.broker.kafka.svc.cluster.local:9092
kafka-1.broker.kafka.svc.cluster.local:9092
kafka-2.broker.kafka.svc.cluster.local:9092
Run Code Online (Sandbox Code Playgroud)
限制是该外部服务能够专门解决代理.
什么是正确的(或一种可能的)方式?是否可以公开外部服务kafka-x.broker.kafka.svc.cluster.local:9092
?
Jas*_*ncl 24
我们已经通过改变无头服务Type=NodePort
和设置来解决这个问题externalTrafficPolicy=Local
.这会绕过服务的内部负载平衡,并且只有当Kafka pod位于该节点上时,指向该节点端口上的特定节点的流量才会起作用.
apiVersion: v1
kind: Service
metadata:
name: broker
spec:
externalTrafficPolicy: Local
ports:
- nodePort: 30000
port: 30000
protocol: TCP
targetPort: 9092
selector:
app: broker
type: NodePort
Run Code Online (Sandbox Code Playgroud)
例如,我们有两个节点nodeA和nodeB,nodeB正在运行一个kafka pod.nodeA:30000将无法连接,但nodeB:30000将连接到nodeB上运行的kafka pod.
https://kubernetes.io/docs/tutorials/services/source-ip/#source-ip-for-services-with-typenodeport
请注意,这也可以在1.5和1.6中作为beta注释使用,更多内容可以在功能可用性中找到:https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#保存最客户端源IP
另请注意,虽然这会将kafka pod与特定的外部网络标识绑定,但并不能保证您的存储卷与该网络标识相关联.如果您在StatefulSet中使用VolumeClaimTemplates,那么您的卷将绑定到pod,而kafka期望该卷与网络标识绑定.
例如,如果kafka-0 pod重新启动并且kafka-0在nodeC而不是nodeA上出现,则kafka-0的pvc(如果使用VolumeClaimTemplates)具有针对nodeA的数据,并且在kafka-0上运行的代理开始拒绝请求思考它是nodeA而不是nodeC.
为了解决这个问题,我们期待Local Persistent Volumes,但是现在我们的kafka StatefulSet只有一个PVC,数据存储在$NODENAME
该PVC上,以便将卷数据绑定到特定节点.
https://github.com/kubernetes/features/issues/121 https://kubernetes.io/docs/concepts/storage/volumes/#local
Nad*_*far 20
到目前为止,解决方案对我自己来说还不够令人满意,所以我将发布一个自己的答案.我的目标:
从Yolean/kubernetes-kafka开始,唯一缺少的是外部公开服务以及这样做的两个挑战.
每个pod标签和外部服务:
要为每个pod生成标签,此问题非常有用.使用它作为指导,我们将以下行 添加到10broker-config.ymlinit.sh
属性中:
kubectl label pods ${HOSTNAME} kafka-set-component=${HOSTNAME}
Run Code Online (Sandbox Code Playgroud)
我们保留现有的无头服务,但我们还使用标签为每个pod生成一个外部服务(我将它们添加到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
Run Code Online (Sandbox Code Playgroud)
使用内部/外部侦听器配置Kafka
我发现这个问题非常有用,试图了解如何配置Kafka.
这又需要使用以下内容更新10broker-config.yml中的init.sh
和server.properties
属性:
将以下内容添加server.properties
到更新安全协议(当前使用PLAINTEXT
):
listener.security.protocol.map=INTERNAL_PLAINTEXT:PLAINTEXT,EXTERNAL_PLAINTEXT:PLAINTEXT
inter.broker.listener.name=INTERNAL_PLAINTEXT
Run Code Online (Sandbox Code Playgroud)
动态确定以下内容中每个Pod的外部IP和外部端口init.sh
:
EXTERNAL_LISTENER_IP=<your external addressable cluster ip>
EXTERNAL_LISTENER_PORT=$((30093 + ${HOSTNAME##*-}))
Run Code Online (Sandbox Code Playgroud)
然后配置listeners
和advertised.listeners
IP EXTERNAL_LISTENER
和INTERNAL_LISTENER
(也在init.sh
属性中):
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
Run Code Online (Sandbox Code Playgroud)
显然,这不是一个完整的生产解决方案(例如解决外部暴露经纪人的安全问题),我仍然在理解如何让内部生产者/消费者也与经纪人沟通.
然而,到目前为止,这是我理解Kubernetes和Kafka的最佳方法.
neo*_*yle 14
我想说我之前已经读过这个问题和答案3次,试图围绕无头服务是什么/它们的意义.(而且我从来没有完全理解无头服务,或者这个Q&A的内容.)
在第4次阅读(在进一步教育自己之后重新审视它)它终于点击了/我终于理解了.
因此,这个答案的目的是重申Nadir的问题/问题/答案,好像向小学生解释一样.因此,偶然发现这一点的其他人将会在第一次阅读时获得纳迪尔非常棒的解决方案的重要性.
有用的背景知识:
存在类型为:ExternalName的服务.
ExternalName服务只是指向DNS地址.
外部名称服务有2种口味:
有状态集有三个部分:
Kube-Proxy有三个重要的事项要记住:
关于无头服务有四个重要的事项需要记住:
现在我们更好地理解了这个问题,让我们回到一个问题:无头服务(指向有状态集的个体成员)如何在外部暴露?
解决方案第1部分:
群集中的任何pod都可以与statefulset的成员通信.
因为有状态生成无头服务,具有可预测的内部群集DNS地址,其形式为:
statefulsetname - #
.associatedheadlessservice.namespace.svc.cluster.local:port
kafka-0.broker.kafka.svc.cluster.local:9092
kafka -1.broker.kafka.svc.cluster.local:9092
kafka-2.broker.kafka.svc.cluster.local:9092
broker.kafka.svc.cluster.local:9092,也可以用来指代哪个一个可用.
解决方案第2部分:
您允许外部流量与有状态集的成员通信,方法是引入可接受外部流量的第二个服务,然后将流量从该服务重定向到只能接受互联网流量的无头服务.
对于有状态集中的每个窗格,将创建一个类型为ExternalName的服务,其中包含由Kube-Proxy管理的虚拟静态ClusterIP地址.这些ExternalName服务中的每一个都指向/重定向流量到解决方案1中标识的可预测的静态内部群集DNS地址,并且因为此ExternalName服务具有通过Kube-Proxy管理的虚拟静态ClusterIP,所以可以存在从NodePorts到其的映射.
归档时间: |
|
查看次数: |
15576 次 |
最近记录: |