Выставляйте отдельных брокеров Кафки на Kubernetes через ELB на AWS


Я запускаю кластер KOPS Kubernetes на AWS, пытаясь заставить 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 (фактическое полное доменное имя заменено на 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 показывает 0 из 3 экземпляров, доступных для каждого брокера Kafka ELB и производящих к kafka-1.kafka.my.company.com:9094 с помощью командной строки клиента Kafka тайм-аут. Как можно outside-0 сервис NodePort будет открыт через kafka-0 сервис LoadBalancer? Или есть другие подходы, которые следует рассмотреть?

4 4

4 ответа:

Kakfa очень строго относится к клиентам, нуждающимся в прямом доступе к серверу, который является лидером темы. Чтобы достичь этого, я сделал следующее:

1) настройте configmap для динамического переопределения значений для объявленных.слушатели, основанные на порядковом значении модуля

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.

    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"

В соответствии с документацией (типы услуг Kuebrnetes):

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 должен быть настроен доступ к API AWS. kubelet, kube-apiserver, kube-controller-manager/cloud-controller-manager есть параметры конфигурации облака.

Эти конфигурации Kubernetes выглядят правильно. Однако если консоль AWS говорит "0 из 3 доступных экземпляров", это обычно означает, что вы не выполнили проверку работоспособности ELB. ELB будет отбрасывать любой трафик, если нет работоспособного экземпляра бэкенда, доступного для отправки данных, что объяснило бы вызовы Кафке тайм-аута.

Простая проверка работоспособности ELB для служб nodeport - это просто SSH, чтобы увидеть, жив ли сам экземпляр, так как kube-proxy на этом экземпляре-это то, что происходит на самом деле чтобы перенаправить трафик в нужный экземпляр. Если вы используете только один прослушиватель на ELB, то вы можете проверить этот порт в своей проверке работоспособности. (Я часто запускаю кучу слушателей nodeport на ELB вместо одного на службу 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, такой же, как порт контейнера, и он может быть одним и тем же портом для всех служб, потому что вы используете разные ELBs. Просто убедитесь, что селекторы установлены правильно, и это должно работать нормально.