Содержание
- Зачем запускать Kafka в Docker?
- Требования и подготовка к установке Apache Kafka KRaft кластера в Docker
- Официальный образ apache/kafka
- Структура проекта для развертывания Apache Kafka Kraft в Docker
- docker-compose.yml для однонодового кластера
- Ключевые переменные окружения
- Volumes. Почему это важно
- Шаг 1. Запуск кластера
- Шаг 2. Проверка брокера
- Шаг 3. Отправка и чтение сообщений
- Подключение к брокеру с хоста
- Остановка и очистка
- Архитектура кластера Apache Kafka Kraft в Docker. Что происходит внутри?
- Сравнение. Ручная установка кластера Apache Kafka vs Kafka Docker
- Заключение
- Референсные ссылки
- Все уроки курса
Изучаем Apache Kafka с нуля. Урок 3. Kafka Docker KRaft. Однонодовый кластер
ПО: Apache Kafka 4.2.0 (образ apache/kafka:4.2.0)
Docker: Engine 28.1, Compose v2.35 \
Окружение: Ubuntu 22.04 LTS / macOS 14+
Уровень: начинающий
В прошлом уроке мы установили Apache Kafka 4.2.0 вручную прямо на хост. Получилось рабочее окружение, но у него есть один минус: оно живёт только на вашей машине и требует ручной настройки при каждом переезде. Kafka Docker решает эту проблему — однажды написанный docker-compose.yml запустит Kafka на любом хосте одной командой.
В этом уроке мы поднимем однонодовый Kafka-кластер в KRaft-режиме через Docker Compose. Разберём официальный образ apache/kafka, объясним ключевые переменные окружения и проверим работу брокера теми же командами, что использовали в уроке 2. В конце — отдельный cheatsheet с командами Docker для работы с Kafka.
Если хотите углубиться в администрирование кластеров — загляните на курс KAFKA. Администрирование кластера Kafka. Там разбирают продакшн-топологии, мониторинг и сетевую конфигурацию на живых примерах.
Зачем запускать Kafka в Docker?
Ручная установка из урока 2 отлично подходит для знакомства с внутренностями Kafka. Но в реальной разработке она неудобна по нескольким причинам.
- Изоляция. Docker-контейнер не засоряет хост-систему. Kafka со всеми данными живёт внутри контейнера и удаляется одной командой.
- Воспроизводимость. docker-compose.yml фиксирует версию образа, порты и конфигурацию. Любой разработчик в команде поднимет точно такое же окружение.
- Скорость. Команда docker compose up -d запускает брокер за 10-15 секунд — без ручного форматирования хранилища и настройки PATH.
- Параллельность. На одной машине можно держать несколько изолированных Kafka-кластеров с разными версиями.
Кроме того, Docker — стандарт де-факто для локального стека разработки. Если в вашем проекте уже есть PostgreSQL или Redis в Docker, добавить туда Kafka займёт несколько строк в существующем compose-файле.
Требования и подготовка к установке Apache Kafka KRaft кластера в Docker
Перед началом убедитесь, что Docker установлен и работает. Проверить просто.
docker --version docker compose version
Нужные версии — Docker Engine 20.10+ и Docker Compose v2.x (встроен в Docker Desktop). Если у вас старый docker-compose (v1, отдельная утилита) — рекомендую обновить до Compose v2, где команда пишется через пробел: docker compose вместо docker-compose.
Порты 9092 и 9093 должны быть свободны. Если в прошлом уроке Kafka ещё запущена — остановите её через kafka-server-stop.sh перед тем, как поднимать контейнер.
Официальный образ apache/kafka
Apache Software Foundation публикует официальные Docker-образы Kafka начиная с версии 3.7.0. Образ доступен на Docker Hub как apache/kafka. Для нашего курса используем тег 4.2.0.
Этот образ работает в KRaft-режиме по умолчанию — ZooKeeper внутри него нет. При старте контейнера скрипт-обёртка автоматически форматирует хранилище метаданных, если видит переменную CLUSTER_ID. Нам не нужно вручную вызывать kafka-storage.sh format, как в уроке 2.
Образ содержит полный дистрибутив Kafka 4.2.0 с папкой bin/ внутри. Все утилиты из уроков 5-33 доступны через docker exec — об этом подробнее в разделе проверки ниже.
Структура проекта для развертывания Apache Kafka Kraft в Docker
Создаём рабочую директорию для урока и один файл внутри неё.
mkdir kafka-lesson3 cd kafka-lesson3
Всё, что нам нужно — один файл docker-compose.yml. Никаких дополнительных конфигов, скриптов или Dockerfile. Образ apache/kafka принимает конфигурацию через переменные окружения.
docker-compose.yml для однонодового кластера
Вот полный файл для запуска одного брокера Kafka 4.2.0 в KRaft-режиме.
# apache/kafka:4.2.0, Docker Compose v2.35
services:
kafka:
image: apache/kafka:4.2.0
container_name: kafka-kraft-single
ports:
- "9092:9092"
environment:
KAFKA_NODE_ID: 1
KAFKA_PROCESS_ROLES: broker,controller
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka: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
CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
volumes:
- kafka-data:/var/lib/kafka/data
volumes:
kafka-data:
Разберём переменные окружения, которые отличаются от конфига из урока 2.
Ключевые переменные окружения
Каждая переменная в блоке environment соответствует параметру из server.properties, только с префиксом KAFKA_ и в верхнем регистре. Разберём те, что требуют пояснений.
- KAFKA_NODE_ID. Уникальный ID этого узла в кластере. Эквивалент node.id=1 из server.properties.
- KAFKA_PROCESS_ROLES. Роли этого процесса. Значение broker,controller означает комбинированный режим — тот самый, что мы настраивали вручную в уроке 2.
- KAFKA_LISTENERS. На каких адресах и портах слушать. Порт 9092 для клиентов, 9093 для контроллерного трафика внутри кластера.
- KAFKA_ADVERTISED_LISTENERS. Адрес, который брокер сообщает клиентам при подключении. Для локальной разработки — localhost:9092. При работе на удалённом сервере замените на реальный IP или hostname.
- KAFKA_CONTROLLER_QUORUM_VOTERS. Список узлов кворума. Формат: node_id@host:port. Здесь указан hostname kafka, а не localhost — это имя сервиса внутри Docker-сети, через которое контейнер обращается сам к себе по внутреннему трафику.
- CLUSTER_ID. Уникальный идентификатор кластера в формате base64 UUID. Образ использует его для автоматического форматирования хранилища при первом запуске. Значение можно сгенерировать через kafka-storage.sh random-uuid или взять любое корректное — для учебного стенда подходит то, что в примере.
- KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1. Для однонодового кластера replication factor системных топиков должен быть 1, иначе Kafka откажется стартовать. В продакшне с несколькими брокерами это значение ставят 3.
Значение KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0 отключает задержку перед первым ребалансом consumer group. В продакшне этот параметр дают время подключиться всем консьюмерам перед стартом. Для разработки задержка только мешает.
Volumes. Почему это важно
Строка kafka-data:/var/lib/kafka/data монтирует именованный Docker volume в директорию данных брокера. Без этого все данные топиков и метаданные хранятся внутри контейнера и исчезают при docker compose down.
С volume данные сохраняются на хосте между перезапусками. Docker управляет этим volume самостоятельно — смотреть, где он физически лежит, обычно не нужно, но можно через docker volume inspect kafka-lesson3_kafka-data.
Шаг 1. Запуск кластера
Находясь в директории kafka-lesson3, запускаем контейнер в фоновом режиме.
docker compose up -d
При первом запуске Docker скачает образ apache/kafka:4.2.0 — около 600 МБ. Последующие запуски моментальные, образ кешируется локально. Смотрим логи, чтобы убедиться в успешном старте.
docker compose logs -f kafka
Брокер готов к работе, когда в логах появится строка KafkaServer id=1] started. Обычно это занимает 10-15 секунд. После этого нажимайте Ctrl+C, чтобы выйти из слежения за логами — контейнер продолжит работу в фоне.
Шаг 2. Проверка брокера
Проверяем статус контейнера и подключаемся к брокеру изнутри.
docker compose ps
В колонке Status должно быть running. Теперь заходим в контейнер и используем стандартные утилиты Kafka для проверки.
# Создаём тестовый топик изнутри контейнера docker exec -it kafka-kraft-single kafka-topics.sh \ --bootstrap-server localhost:9092 \ --create \ --topic test-topic \ --partitions 1 \ --replication-factor 1 # Проверяем список топиков docker exec -it kafka-kraft-single kafka-topics.sh \ --bootstrap-server localhost:9092 \ --list
Команды выполняются так же, как и в уроке 2, только через docker exec. Это важный момент — все утилиты из папки bin/, которые мы разбираем в уроках 5-33, работают внутри контейнера точно так же, как на голом хосте. Разница только в том, как мы до них добираемся.
Шаг 3. Отправка и чтение сообщений
Запускаем продюсера и проверяем, что брокер принимает и отдаёт сообщения.
# Отправляем тестовое сообщение echo "hello from docker" | docker exec -i kafka-kraft-single kafka-console-producer.sh \ --bootstrap-server localhost:9092 \ --topic test-topic
# Читаем сообщение docker exec -it kafka-kraft-single kafka-console-consumer.sh \ --bootstrap-server localhost:9092 \ --topic test-topic \ --from-beginning \ --max-messages 1
Если в терминале появилась строка hello from docker — брокер работает корректно. Продюсер и консьюмер успешно взаимодействуют через топик.
Подключение к брокеру с хоста
Порт 9092 пробрасывается на хост-машину. Это значит, что к брокеру можно подключаться напрямую с хоста, если у вас установлены утилиты Kafka из урока 2.
# Команда выполняется НА ХОСТЕ, не внутри контейнера kafka-topics.sh \ --bootstrap-server localhost:9092 \ --list
С точки зрения клиента брокер в контейнере и брокер на голом хосте выглядят одинаково — один и тот же адрес localhost:9092. Это удобно при разработке приложений — меняете только способ развёртывания Kafka, код приложения не трогаете.
Остановка и очистка
Docker Compose даёт три уровня «остановки» в зависимости от того, что нужно сделать.
- Пауза без удаления данных. Команда docker compose stop останавливает контейнер, но сохраняет его состояние и данные в volume. Следующий docker compose start поднимет его снова с теми же данными.
- Удаление контейнера, сохранение данных. Команда docker compose down удаляет контейнер и сеть, но оставляет volume нетронутым. Данные топиков сохраняются.
- Полная очистка. Команда docker compose down -v удаляет всё вместе с volume. Брокер при следующем запуске стартует с чистого листа.
Для разработки обычно используют docker compose down при завершении работы и docker compose up -d при следующем сеансе. Данные при этом сохраняются между сессиями.
# Остановить без удаления данных docker compose down # Полная очистка со сбросом всех данных docker compose down -v
Архитектура кластера Apache Kafka Kraft в Docker. Что происходит внутри?
Диаграмма показывает, как связаны хост, Docker-сеть и процесс Kafka внутри контейнера.

Клиент на хосте подключается к localhost:9092. Docker перенаправляет трафик в контейнер на тот же порт. Внутри один процесс Kafka выполняет роли брокера и контроллера одновременно — комбинированный KRaft-режим, как в уроке 2. Данные пишутся в volume, который живёт на хосте вне зависимости от жизненного цикла контейнера.
Сравнение. Ручная установка кластера Apache Kafka vs Kafka Docker
| Параметр | Ручная установка (урок 2) | Docker Compose (урок 3) |
|---|---|---|
| Время первого запуска | 10-15 мин | 2-3 мин (скачать образ + старт) |
| Время повторного запуска | ~30 сек | 10-15 сек |
| Изоляция от хост-системы | нет | полная |
| Форматирование хранилища | вручную (kafka-storage.sh) | автоматически по CLUSTER_ID |
| Настройка PATH | нужна | не нужна |
| Сохранность данных при перезапуске | да (в /tmp/kraft-combined-logs) | да (Docker volume) |
| Воспроизводимость на другой машине | низкая | высокая |
| Параллельные версии Kafka | неудобно | легко |
Для локальной разработки Docker-подход предпочтительнее почти всегда. Ручная установка полезна, когда нужно понять внутреннее устройство Kafka — именно поэтому мы начали с неё в уроке 2.
Заключение
Мы запустили однонодовый кластер Kafka в Docker и проверили, что брокер принимает подключения. Один узел — это удобно для разработки, но не даёт никакой отказоустойчивости.
В уроке 4 развернём кластер из трёх брокеров с помощью Docker Compose. Там увидим, как Kafka распределяет партиции между узлами и что происходит, когда один из брокеров падает.
Референсные ссылки
- Apache Kafka 4.2.0 — Docker (официальная документация)
- apache/kafka — Docker Hub, официальный образ
- Apache Kafka KRaft Mode — официальная документация
- Docker Compose — официальная документация, актуальная версия
