在这篇文章中,我们将介绍如何使用Supertubes或Kafka运营商配置你的Kafka集群,使其能够被运行在Kubernetes集群之外的外部客户端应用程序访问。
有两种方法可以让你从外部发布你的Kafka集群。
LoadBalancer 方法是一种非常方便的发布Kafka集群的方法,因为它允许你放弃设置负载平衡器、配置公共IP、配置路由规则等,因为这些都是为你服务的。另外,这种方法还有一个好处,就是减少了你的攻击面,因为你不需要让Kubernetes集群的节点从外部直接到达,因为进入的外部流量是通过负载平衡器路由到Kubernetes集群的节点。
NodePort 方法通过Kubernetes集群的节点的外部公共IP为外部客户提供对Kafka的访问。这种访问方法在以下情况下是很适合的。
- 托管环境中使用的Kubernetes发行版不支持负载平衡器
- 负载平衡器和Ingress控制器引入的额外跳数因业务需求而无法接受
- Kubernetes集群所在的环境被锁定,因此Kubernetes节点无法通过其公共IP从外部到达。
外部监听器 🔗︎
你可以通过在KafkaCluster 自定义资源中声明一个或多个externalListeners将Kafka集群暴露在Kubernetes集群之外。
listenersConfig:
externalListeners:
- type: "plaintext"
name: "external1"
externalStartingPort: 19090
containerPort: 9094
- type: "plaintext"
name: "external2"
externalStartingPort: 19090
containerPort: 9095
以上,externalListeners创建了两个外部访问点,通过它们可以到达Kafka集群的经纪人。这些外部监听器在advertized.listeners Kafka经纪人配置中被注册为EXTERNAL1://...,EXTERNAL2://...
带有LoadBalancer访问方法的外部监听器 🔗︎
外部监听器的默认访问方法是LoadBalancer,因此,在下面的例子中。
accessMethod: LoadBalancer
可以从外部监听器的配置中省略。
listenersConfig:
externalListeners:
- type: "plaintext"
name: "external1"
externalStartingPort: 19090
containerPort: 9094
accessMethod: LoadBalancer
这将为外部监听器创建一个Load Balancer,external1 。集群中的每个代理将在Load Balancer上收到一个专用的端口号,其计算方法是代理端口号= externalStartingPort + broker id。这将在每个经纪商的配置中注册为advertized.listeners=EXTERNAL1://: 。
使用LoadBalancer访问方法的外部监听器也需要配置一个入口控制器,这可以通过KafkaCluster自定义资源的ingressController 字段进行配置。
spec:
ingressController: "envoy"
目前支持的入口控制器有。
- envoy - 使用Envoy Proxy作为入口控制器。
- istioingress - 使用Istio网关作为入口控制器。这是用Supertubes配置的Kafka集群的默认控制器,因为这些集群在Istio网状结构内运行。
这些入口控制器的其他配置,如复制的数量、资源要求和资源限制,可以分别通过envoyConfig和istioIngressConfig字段进行配置。
通过静态URL的外部访问 🔗︎
为了通过URL暴露Kafka集群,而不是通过负载均衡器的公共IP,在外部监听器的hostnameOverride 字段中指定URL,该URL可解析到负载均衡器的公共IP。
listenersConfig:
externalListeners:
- type: "plaintext"
name: "external1"
externalStartingPort: 19090
containerPort: 9094
accessMethod: LoadBalancer
hostnameOverride: kafka-1.dev.my.domain
这将导致经纪人访问地址被宣传为,advertized.listeners=EXTERNAL1://kafka-1.dev.my.domain: 。
使用NodePort访问方法的外部监听器 🔗︎
使用NodePort访问方法,外部监听器可以通过Kubernetes集群节点的外部IP或路由到集群的外部IP访问Kafka经纪人。
listenersConfig:
externalListeners:
- type: "plaintext"
name: "external1"
externalStartingPort: 32000
containerPort: 9094
accessMethod: NodePort
将为每个经纪人单独创建一个NodePort类型的服务。经纪人可以从Kubernetes集群外部到达: ,其中 ,计算为externalStartingPort + broker id。
externalStartingPort必须属于Kubernetes集群上分配给节点端口的范围,这个范围通过*-service-node-port-range*指定(见Kubernetes文档)。
通过动态URL的外部访问 🔗︎
为了使经纪人通过URL访问,在外部监听器的hostnameOverride 字段中指定一个后缀。
listenersConfig:
externalListeners:
- type: "plaintext"
name: "external1"
externalStartingPort: 32000
containerPort: 9094
accessMethod: NodePort
hostnameOverride: .dev.my.domain
hostnameOverride 在这里的行为与LoadBalancer的访问方法不同。在这种情况下,每个代理将被宣传为advertized.listeners=EXTERNAL1://-.: 。如果一个名为kafka的三经纪商Kafka集群在kafka命名空间中运行,那么经纪商的advertized.listeners ,将看起来像这样。
- broker 0:
- advertized.listeners=EXTERNAL1://kafka-0.external1.kafka.dev.my.domain:32000
- broker 1:
- advertized.listeners=EXTERNAL1://kafka-1.external1.kafka.dev.my.domain:32001
- broker 2:
- advertized.listeners=EXTERNAL1://kafka-2.external1.kafka.dev.my.domain:32002
NodePort external IP 🔗︎
Kafka代理可以通过外部IP进行访问,这些IP不是节点IP,但可以路由到Kubernetes集群。这些外部IP可以在KafkaCluster自定义资源中为每个经纪人设置,如下例所示。
brokers:
- id: 0
brokerConfig:
nodePortExternalIP:
external1: 13.53.214.23 # if "hostnameOverride" is not set for "external1" external listener, then broker is advertised on this IP
- id: 1
brokerConfig:
nodePortExternalIP:
external1: 13.48.71.170 # if "hostnameOverride" is not set for "external1" external listener, then broker is advertised on this IP
- id: 2
brokerConfig:
nodePortExternalIP:
external1: 13.49.70.146 # if "hostnameOverride" is not set for "external1" external listener, then broker is advertised on this IP
如果hostnameOverride字段没有设置,那么经纪人地址就会被Advertized,如下所示。
- broker 0:
- advertized.listeners=EXTERNAL1://13.53.214.23:9094
- broker 1:
- advertized.listeners=EXTERNAL1://13.48.71.170:9094
- 经纪人 2:
- advertized.listeners=EXTERNAL1://13.49.70.146:9094
如果hostnameOverride和nodePortExternalIP两个字段都被设置。
- 经纪人0。
- advertized.listeners=EXTERNAL1://kafka-0.external1.kafka.dev.my.domain:9094
- 经纪人 1:
- advertized.listeners=EXTERNAL1://kafka-1.external1.kafka.dev.my.domain:9094
- 经纪人 2:
- advertized.listeners=EXTERNAL1://kafka-2.external1.kafka.dev.my.domain:9094
注意,如果设置了nodePortExternalIP,那么来自外部监听器配置的containerPort将被用作经纪商端口,并且对每个经纪商都是一样的。
未来的NodePort增强功能 🔗︎
目前,在NodePort访问方法中,必须为外部监听器指定hostnameOverride或nodePortExternalIP,或者两者都要。在未来的版本中,如果没有设置这些,在advertized.listeners broker配置中,将使用broker pod被安排的节点IP。