Пример docker-compose для запуска Kafka

Обновлено и опубликовано Опубликовано:

Используемые термины: Kafka, Docker.

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

Пример команд будет приведет с использованием Linux.

Описание файла docker-compose

Создаем рабочий каталог и переходим в него:

mkdir /opt/kafka && cd /opt/kafka

Создаем файл docker-compose:

vi docker-compose.yml

services:

  kafka1:
    image: apache/kafka:${KAFKA_VER}
    container_name: kafka1
    hostname: kafka1
    restart: unless-stopped
    environment:
      TZ: ${TIMEZONE}
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: INTERNAL://0.0.0.0:9092,EXTERNAL://0.0.0.0:9094,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: INTERNAL://kafka1:9092,EXTERNAL://${KAFKA_HOSTNAME}:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INTERNAL:PLAINTEXT,EXTERNAL:PLAINTEXT,CONTROLLER:PLAINTEXT
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_INTER_BROKER_LISTENER_NAME: INTERNAL
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka1:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1
      KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1
      KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0
      KAFKA_NUM_PARTITIONS: 3
    volumes:
      - ./kafka/data:/var/lib/kafka/data
    ports:
      - 9092:9092
      - 9093:9093
      - 9094:9094
    healthcheck:
      test: ["CMD-SHELL", "nc -z 127.0.0.1 9092 || exit 2"]
      start_period: 10s
      interval: 30s
      timeout: 5s
      retries: 5

* подробнее рассмотрим системные переменные, которые определяют поведение работы кафки:

  1. Идентификация и роли
    • KAFKA_NODE_ID — Уникальный числовой идентификатор брокера в кластере.
    • KAFKA_PROCESS_ROLES — Совмещение ролей. Узел работает и как хранилище данных (broker), и как управляющий элемент (controller).
  2. Сетевые подключения (Слушатели)
    • KAFKA_LISTENERS — Интерфейсы и порты, которые слушает Kafka внутри контейнера или сервера. 0.0.0.0 означает прием подключений на всех сетевых интерфейсах.
    • KAFKA_ADVERTISED_LISTENERS — Адреса, которые Kafka передаёт клиентам. INTERNAL используется для клиентов внутри Docker-сети, EXTERNAL — для внешних подключений.
    • KAFKA_CONTROLLER_LISTENER_NAMES — Указывает, какой именно из настроенных слушателей используется для связи между контроллерами кластера.
    • KAFKA_INTER_BROKER_LISTENER_NAME — слушатель, который используется для внутренних запросов (между контейнерами docker).
    • KAFKA_LISTENER_SECURITY_PROTOCOL_MAP — Привязывает имена слушателей (INTERNALEXTERNALCONTROLLER) к протоколу безопасности (PLAINTEXT).
  3. Кворум и согласованность KRaft
    • KAFKA_CONTROLLER_QUORUM_VOTERS — Список всех голосующих узлов-контроллеров для выбора лидера. Формат: ID_узла@IP:порт. В данном случае узел голосует сам за себя на локальном интерфейсе.
  4. Репликация системных топиков
    • KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR — Фактор репликации для служебного топика __consumer_offsets, где хранятся позиции чтения клиентов. Значение 1 подходит только для разработки или одного узла.
    • KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR — Фактор репликации для топика состояния транзакций.
    • KAFKA_TRANSACTION_STATE_LOG_MIN_ISR — Минимальное количество синхронных реплик (ISR), необходимое для подтверждения транзакции. При значении 1 транзакции будут работать даже на одиночном брокере.
  5. Производительность и дефолты
    • KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS — Время ожидания (в миллисекундах) перед первой балансировкой группы потребителей. Значение 0 ускоряет старт и прогон тестов, так как группа собирается мгновенно.
    • KAFKA_NUM_PARTITIONS — Количество разделов (партиций) по умолчанию для любого нового топика, если оно не было указано явно при его создании.

Создадим конфигурационный файл: 

vi .env

TIMEZONE=Europe/Moscow

KAFKA_HOSTNAME=test.dmosk.ru

KAFKA_VER=4.3.1

* где:

  • TIMEZONE — временная зона, в которой работает сервер кафки.
  • KAFKA_HOSTNAME — имя сервера кафки. Должно разрешаться в DNS для возможности подключения к брокеру.
  • KAFKA_VER — версия кафки. Актуальный тег можно найти на Docker Hub.

Одноузловой кластер настроен. Для запуска выполняем команду:

docker-compose up -d

И проверяем статус:

docker-compose ps

Проверка тестовым сообщением

Создадим топик и отправим в него тестовое сообщение — так проверим, что кластер работает:

docker exec -it kafka1 /opt/kafka/bin/kafka-topics.sh --create --topic test --bootstrap-server localhost:9092

* где test — имя топика, localhost:9092 — адрес брокера внутри контейнера.

Запустим продюсер и отправим сообщение:

docker exec -it kafka1 /opt/kafka/bin/kafka-console-producer.sh --topic test --bootstrap-server localhost:9092

В открывшейся строке вводим текст сообщения и нажимаем Enter, затем закрываем консоль сочетанием Ctrl+C.

В отдельном окне терминала запустим консумер и прочитаем сообщение:

docker exec -it kafka1 /opt/kafka/bin/kafka-console-consumer.sh --topic test --bootstrap-server localhost:9092 --from-beginning

Мы должны увидеть отправленное ранее сообщение в выводе консоли.

Кластер принимает и отдает сообщения.

В примерах ниже используется адрес localhost:9092 — это внутренний listener INTERNAL. Если вы подключаетесь к Kafka извне (не из контейнера), используйте внешний адрес, указанный в KAFKA_HOSTNAME, и порт 9094 (EXTERNAL).

Выбор образа Kafka и версии

В примере мы используем образ apache/kafka. Но есть и другие варианты:

  • apache/kafka — официальный образ проекта. Поддерживает KRaft без ZooKeeper, переменные начинаются с KAFKA_.
  • confluentinc/cp-kafka — образ от Confluent. Тоже работает в режиме KRaft, но часть переменных называется иначе, а в старых версиях нужен отдельный контроллер.
  • bitnami/kafka — образ от Bitnami. Использует префикс KAFKA_CFG_ вместо KAFKA_, и добавляет свои готовые пресеты для одноузлового и многоузлового запуска.

* при смене образа сверяем набор переменных окружения с документацией — прямой перенос значений между образами не всегда работает.

Кафка в нашем примере работает без ZooKeeper — это режим KRaft. Роли broker и controller совмещены в одном узле через переменную KAFKA_PROCESS_ROLES. Кворум и выбор лидера контролирует сама Kafka через KAFKA_CONTROLLER_QUORUM_VOTERS. Раньше эту задачу решал отдельный компонент — ZooKeeper.

* в старых версиях Kafka (до перехода на KRaft) ZooKeeper еще требуется — уточняем версию образа перед настройкой.

Расширение до нескольких узлов

Пример с одним узлом подходит для разработки и тестов. Для продакшена обычно разворачивают три узла и больше. Каждому новому узлу задаем свой KAFKA_NODE_ID, и добавляем его в общий список KAFKA_CONTROLLER_QUORUM_VOTERS на всех узлах.

* при добавлении узлов также пересчитываем факторы репликации (KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR и подобные) — значение 1 подходит только для одного брокера.

Переход к кластеру из нескольких узлов делается по тому же принципу.

Решение проблем

Рассмотрим несколько часто встречаемых ошибок.

1. Ошибка подключения

Клиент подключается к брокеру и получает ошибку соединения.

Причина: часто из-за того, что KAFKA_ADVERTISED_LISTENERS указывает адрес, недоступный извне контейнера.

Решение: проверяем значение KAFKA_HOSTNAME в файле .env — оно должно быть адресом, по которому клиент реально достучится до брокера.

2. Кафка внутри контейнера на работает

Healthcheck контейнера показывает unhealthy, хотя в логах kafka1 нет ошибок.

Причина: иногда команда nc отсутствует внутри образа.

Решение: смотрим логи:

docker logs kafka1

... и при необходимости, меняем тест healthcheck на вызов kafka-broker-api-versions.sh.

# DevOps # Linux # Контейнеризация # Серверы
Дмитрий Моск — частный мастер
Был ли вам полезен этот скрипт?

Да            Нет

Дмитрий Моск
— IT-специалист.
Настройка серверов, услуги DevOps.

Заказать настройку контейнеризации

Нужна бесплатная консультация?

Скрипты

Пример файла docker-compose для развертывания брокера Kafka

Пример сценария docker-compose для запуска сервера Dependency-Track

Запуск SonarQube Server в контейнере с помощью docker-compose

Пример docker-compose файла для запуска сервера rustdesk в docker

Пример файла docker-compose для запуска Garage S3

Развертывание N8N в среде контейнеров с помощью docker-compose

Сценарий в docker-compose для запуска Rocket.Chat

Другие скрипты

Все статьи

Нужен скрипт? Опишите его назначение:





Реклама