【问题标题】:Expose individual Kafka brokers on Kubernetes through an ELB on AWS通过 AWS 上的 ELB 在 Kubernetes 上公开单个 Kafka 代理
【发布时间】:2018-07-10 01:18:23
【问题描述】:

我在 AWS 上运行 KOPS Kubernetes 集群,试图让 kubernetes-kafka 示例与弹性负载均衡器一起工作。这是两个经纪人的外部服务部分:

kind: Service
apiVersion: v1
metadata:
  name: outside-0
  namespace: kafka
spec:
  selector:
    app: kafka
    kafka-broker-id: "0"
  ports:
  - protocol: TCP
    targetPort: 9094
    port: 32400
    nodePort: 32400
  type: NodePort
---
kind: Service
apiVersion: v1
metadata:
  name: outside-1
  namespace: kafka
spec:
  selector:
    app: kafka
    kafka-broker-id: "1"
  ports:
  - protocol: TCP
    targetPort: 9094
    port: 32401
    nodePort: 32401
  type: NodePort

这是我尝试通过 ELB 公开这些代理(实际 FQDN 替换为 my.copmany.com)。

apiVersion: v1
kind: Service
metadata:
  name: kafka-0
  annotations:
    dns.alpha.kubernetes.io/external: kafka-0.kafka.my.company.com
spec:
  type: LoadBalancer
  ports:
  - port: 32400
    name: outside
    targetPort: 32400
  selector:
    app: outside-0
---
apiVersion: v1
kind: Service
metadata:
  name: kafka-1
  annotations:
    dns.alpha.kubernetes.io/external: kafka-1.kafka.my.company.com
spec:
  type: LoadBalancer
  ports:
  - port: 32401
    name: outside
    targetPort: 32401
  selector:
    app: outside-1

查看 AWS ELB 控制台显示 3 个实例中有 0 个可用于每个 Kafka ELB 代理,并使用 Kafka 命令行客户端超时生成到 kafka-1.kafka.my.company.com:9094outside-0 NodePort 服务如何通过kafka-0 LoadBalancer 服务暴露?还是有其他方法可以考虑?

【问题讨论】:

  • @DmitryMinkovsky - 谢谢你的链接,两个最重要的答案都有一些很好的元素,第一个通过ec2-host:port 公开它,第二个使用elb:port。我的挑战是每个卡夫卡经纪人都需要拥有自己的“永久”网址,例如subdomain-on-company-domain:port,例如kafka-1.kafka.my.company.com:9094.
  • 是的,我自己从来没有完全弄清楚。幸运的是,在我的情况下,我最终意识到我可以从内部发送数据,而不是向外部开放 Kafka。如果你明白这一点,请发布答案。
  • ELB DNS 对服务来说是永久的。如果您重新部署甚至删除部署,它不会改变。如果您删除该服务,它将被释放。如果您拥有自己的 DNS,例如 my.kafka.com,则可以将其别名为 ELB DNS

标签: amazon-web-services apache-kafka kubernetes amazon-elb


【解决方案1】:

Kakfa 非常注重需要直接访问作为主题领导者的服务器的客户端。为此,我做了以下工作:

1) 设置 configmap 以根据 pod 的序号值动态覆盖adverted.listeners 的值

POD_ID=${HOSTNAME##*-}

kafka-server-start.sh server.properties \
      --override advertised.listeners=INSIDE://`hostname -f`:9092,OUTSIDE://kafka-${POD_ID}.kafka.my.company.com:9094 \
      --override broker.id=${POD_ID} \
      --override listeners=INSIDE://:9092,OUTSIDE://:9094

2) 为每个 Kafka pod 创建一个 LoadBalancer 服务。更改选择器以匹配您的 kafka-pod-id。

    apiVersion: v1
    kind: Service
    metadata:
      name: kafka-0
      annotations:
        dns.alpha.kubernetes.io/external: kafka-0.kafka.my.company.com
    spec:
      externalTrafficPolicy: Local
      type: LoadBalancer
      ports:
      - port: 9094
        name: outside
        targetPort: 9094
      selector:
        app: kafka
        kafka-pod-id: "0"
---     
apiVersion: v1
        kind: Service
        metadata:
          name: kafka-1
          annotations:
            dns.alpha.kubernetes.io/external: kafka-1.kafka.my.company.com
        spec:
          externalTrafficPolicy: Local
          type: LoadBalancer
          ports:
          - port: 9094
            name: outside
            targetPort: 9094
          selector:
            app: kafka
            kafka-pod-id: "1"

【讨论】:

    【解决方案2】:

    这些 Kubernetes 配置看起来正确。但是,如果 AWS 控制台显示“3 个实例中的 0 个可用”,这通常意味着您未通过 ELB 运行状况检查。如果没有可用于向其发送数据的健康后端实例,ELB 将丢弃任何流量,这将解释对 Kafka 的调用超时。

    节点端口服务的简单 ELB 运行状况检查只是 SSH 以查看实例本身是否处于活动状态,因为该实例上的 kube-proxy 实际上会将流量转发到正确的实例。如果您只在 ELB 上运行一个侦听器,那么您实际上可以在运行状况检查中检查该端口。 (我经常为每个 ELB 运行一组 nodeport 侦听器,而不是为每个 nodeport 服务运行一个以节省资金。)

    【讨论】:

      【解决方案3】:

      根据文档 (Kuebrnetes Service Types):

      LoadBalancer:使用云提供商的外部公开服务 负载均衡器。 NodePort 和 ClusterIP 服务,其外部 负载均衡器将路由,自动创建。

      您不应该为 NodePort 和 LoadBalancer 类型定义单独的服务,而只能指定 LoadBalancer 并指定 nodePort(请测试并尝试添加/删除一些选项,因为我没有可以测试的环境):

      apiVersion: v1
      kind: Service
      metadata:
        name: kafka-0
      spec:
        type: LoadBalancer
        ports:
        - port: 32400
          name: kafka
          nodePort: 32400
        selector:
          app: kafka
          kafka-broker-id: "0"
      ---
      apiVersion: v1
      kind: Service
      metadata:
        name: kafka-1
      spec:
        type: LoadBalancer
        ports:
        - port: 32401
          name: kafka
          nodePort: 32401
        selector:
          app: kafka
          kafka-broker-id: "1"
      
      • Kubernetes 集群应配置 AWS API 访问。 kubeletkube-apiserverkube-controller-manager/cloud-controller-manager 有云配置选项。

      【讨论】:

        【解决方案4】:

        目标端口设置不正确,必须使用容器端口,会自动分配一个NodePort。配置如下:

        apiVersion: v1
        kind: Service
        metadata:
          name: kafka-0
          annotations:
            dns.alpha.kubernetes.io/external: kafka-0.kafka.my.company.com
        spec:
          type: LoadBalancer
          ports:
          - port: 9094
            name: outside
            targetPort: 9094
          selector:
            app: outside-0
        ---
        apiVersion: v1
        kind: Service
        metadata:
          name: kafka-1
          annotations:
            dns.alpha.kubernetes.io/external: kafka-1.kafka.my.company.com
        spec:
          type: LoadBalancer
          ports:
          - port: 9094
            name: outside
            targetPort: 9094
          selector:
            app: outside-1
        

        外部端口可以是任何你想要的,例如你可以使用9094,与容器的端口相同,并且它可以是所有服务的相同端口,因为你使用不同的ELB。只要确保选择器设置正确,这应该可以正常工作。

        【讨论】:

          猜你喜欢
          • 2022-12-12
          • 2020-05-28
          • 2018-06-19
          • 2017-07-30
          • 2022-01-02
          • 2019-03-22
          • 2021-01-21
          • 2018-05-11
          • 2017-12-20
          相关资源
          最近更新 更多