Конфигурация кластера Kafka KRaft в Docker

Вопрос или проблема

Я хочу создать кластер Kafka в режиме KRaft с двумя контроллерами и двумя брокерами. Я написал конфигурацию:

services:

  kafka-controller-1:
    image: 'bitnami/kafka:latest'
    environment:
      - KAFKA_CFG_NODE_ID=0
      - KAFKA_KRAFT_CLUSTER_ID='4ea7fcb4a2fb4dc8a402d4103ee414eb'
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-controller-1:9092,1@kafka-controller-2:9092
      - KAFKA_CFG_PROCESS_ROLES=controller

      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_LISTENERS=CONTROLLER://kafka-controller-1:9092
      - KAFKA_CFG_ADVERTISED_LISTENERS=CONTROLLER://kafka-controller-1:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT

  kafka-controller-2:
    image: 'bitnami/kafka:latest'
    environment:
      - KAFKA_CFG_NODE_ID=1
      - KAFKA_KRAFT_CLUSTER_ID='4ea7fcb4a2fb4dc8a402d4103ee414eb'
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-controller-1:9092,1@kafka-controller-2:9092
      - KAFKA_CFG_PROCESS_ROLES=controller

      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_LISTENERS=CONTROLLER://kafka-controller-2:9092
      - KAFKA_CFG_ADVERTISED_LISTENERS=CONTROLLER://kafka-controller-2:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT

  kafka-broker-1:
    image: 'bitnami/kafka:latest'
    environment:
      - KAFKA_CFG_NODE_ID=2
      - KAFKA_KRAFT_CLUSTER_ID='4ea7fcb4a2fb4dc8a402d4103ee414eb'
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-controller-1:9092,1@kafka-controller-2:9092
      - KAFKA_CFG_PROCESS_ROLES=broker

      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_LISTENERS=PLAINTEXT://kafka-broker-1:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT

  kafka-broker-2:
    image: 'bitnami/kafka:latest'
    environment:
      - KAFKA_CFG_NODE_ID=3
      - KAFKA_KRAFT_CLUSTER_ID='4ea7fcb4a2fb4dc8a402d4103ee414eb'
      - KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=0@kafka-controller-1:9092,1@kafka-controller-2:9092
      - KAFKA_CFG_PROCESS_ROLES=broker

      - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
      - KAFKA_CFG_LISTENERS=PLAINTEXT://kafka-broker-2:9092
      - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT

  kafka-ui:
    container_name: kafka-ui
    image: 'provectuslabs/kafka-ui:latest'
    environment:
      - KAFKA_CLUSTERS_0_NAME=test-local
      - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka-broker-1:9092
    depends_on:
      - kafka-controller-1
      - kafka-controller-2
      - kafka-broker-1
      - kafka-broker-2
    ports:
  - '1354:8080'

Это работает, UI показывает мне два брокера, и один из них является контроллером. (Я не могу опубликовать изображение, нужно 10 репутации)

Мои вопросы:

  1. Почему я вижу только два брокера и ни одного из моих контроллеров?
  2. Почему один из брокеров является контроллером, если я настроил другие два контроллера?

Дополнительно:

  1. - KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER настроен для брокеров, потому что без этого я получаю ошибку:

    Exception in thread “main” java.lang.IllegalArgumentException: requirement failed: controller.listener.names must contain at least one value when running KRaft with just the broker role

  2. Если я подключу интерфейс к контроллеру - KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka-controller-1:9092, UI не может запросить METADATA:

    2025-02-08 00:18:21 2025-02-07 21:18:21,979 INFO [kafka-admin-client-thread | kafka-ui-admin-1738963090-1] o.a.k.c.a.i.AdminMetadataManager: [AdminClient clientId=kafka-ui-admin-1738963090-1] Metadata update failed
    2025-02-08 00:18:21 org.apache.kafka.common.errors.UnsupportedVersionException: The broker does not support METADATA

Ответ или решение

Создание Kafka кластера в KRaft режиме с использованием Docker – задача, требующая тщательной настройки конфигураций для корректной работы всех компонентов. Рассмотрим подробно ваш случай для разъяснения ключевых моментов.

Теория

Apache Kafka в KRaft режиме (KRaft – это Kafka Raft metadata management mode) замещает необходимость использовать отдельный ZooKeeper для управления метаданными. В данном режиме контроллеры и брокеры работают в едином кластере, где контроллеры управляют метаданными, использованием Raft протокола для достижения консенсуса.

При настройке кластера в KRaft режиме важно правильно разграничить роли контроллеров и брокеров. Все узлы (или ноды) в кластере должны быть правильно сконфигурированы с учетом их специфических ролей для обеспечения стабильной и надежной работы.

Пример

В вашем примере конфигурации Kafka кластера через Docker Compose представлено четыре основных сервиса: два контроллера (kafka-controller-1 и kafka-controller-2) и два брокера (kafka-broker-1 и kafka-broker-2). Дополнительно вы включаете сервис для отображения пользовательского интерфейса – kafka-ui. Рассмотрим основные части вашей конфигурации более детально:

  1. Узлы контроллеров:

    • Каждый контроллер настраивается с уникальным идентификатором узла через переменную KAFKA_CFG_NODE_ID.
    • Кластерное решение поддерживается за счёт KAFKA_KRAFT_CLUSTER_ID – уникального идентификатора кластера.
    • Параметр KAFKA_CFG_CONTROLLER_QUORUM_VOTERS указывает на других участников кворума (контроллеров), обеспечивая консенсус.
  2. Узлы брокеров:

    • Брокеры также получают уникальные KAFKA_CFG_NODE_ID.
    • Они связываются с контроллерами через такие параметры, как KAFKA_CFG_CONTROLLER_LISTENER_NAMES, чтобы избегать ошибок, связанных с необходимостью конфигурации.
  3. Общий момент:

    • Все узлы разделают KAFKA_KRAFT_CLUSTER_ID, так как это один кластер.
    • Для сетевых соединений используется PLAINTEXT в параметре KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP, что может быть приемлемо для локальных или тестовых окружений, хотя для продакшн следует использовать TLS.

Применение

Причины проблем, которые вы наблюдаете, связаны с определенными нюансами конфигурации и пониманием, как компоненты взаимодействуют:

  1. Почему видны только брокеры:
    Пользовательский интерфейс Kafka, который вы используете, возможно, заточен под работу с брокерами и не отображает контроллеры, так как метаданные о контроллерах могут не приниматься брокерским API, к которому элемент управления подключается.

  2. Брокер выступает в роли контроллера:
    Вероятно, это связано с тем, что в KRaft режиме каждый узел, выполняющий роль контроллера, также может администрировать некоторые брокерские операции для поддержки отказоустойчивости и избыточности. Однако это не значит, что брокер «становится» контроллером в функциональном смысле.

  3. Ошибка при подключении UI к контроллеру:
    Контроллеры не обслуживают запросы клиента, такие как METADATA, поскольку напрямую работают только с внутренними данными кластера. Для получения метаданных и других данных о кластерной конфигурации инструменту UI необходимо подключиться к брокерам.

Ваш случай подчеркивает важность понимания роли каждого компонента в KRaft режиме и корректного отображения структурных особенностей конфигураций в связке Docker, что может предотвратить подобные нестыковки в дальнейшем.

Оцените материал
Добавить комментарий

Капча загружается...