实现Kafka外部访问的操作实例

781 阅读5分钟

在这篇文章中,我们将介绍如何使用SupertubesKafka运营商配置你的Kafka集群,使其能够被运行在Kubernetes集群之外的外部客户端应用程序访问。

有两种方法可以让你从外部发布你的Kafka集群。

LoadBalancer 方法是一种非常方便的发布Kafka集群的方法,因为它允许你放弃设置负载平衡器、配置公共IP、配置路由规则等,因为这些都是为你服务的。另外,这种方法还有一个好处,就是减少了你的攻击面,因为你不需要让Kubernetes集群的节点从外部直接到达,因为进入的外部流量是通过负载平衡器路由到Kubernetes集群的节点。

image.png

NodePort 方法通过Kubernetes集群的节点的外部公共IP为外部客户提供对Kafka的访问。这种访问方法在以下情况下是很适合的。

  • 托管环境中使用的Kubernetes发行版不支持负载平衡器
  • 负载平衡器和Ingress控制器引入的额外跳数因业务需求而无法接受
  • Kubernetes集群所在的环境被锁定,因此Kubernetes节点无法通过其公共IP从外部到达。

image.png

外部监听器 🔗︎

你可以通过在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网状结构内运行。

这些入口控制器的其他配置,如复制的数量、资源要求和资源限制,可以分别通过envoyConfigistioIngressConfig字段进行配置。

通过静态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

如果hostnameOverridenodePortExternalIP两个字段都被设置。

  • 经纪人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访问方法中,必须为外部监听器指定hostnameOverridenodePortExternalIP,或者两者都要。在未来的版本中,如果没有设置这些,在advertized.listeners broker配置中,将使用broker pod被安排的节点IP。