Kafka Cluster Testing Tool

Детерминированный smoke test готовности Kafka-кластера с практическим упором на Kerberos-защищённые окружения

Совместимость

Поддерживаемые версии Apache Kafka: 3.0.0–4.2.0

Что проверяет

Утилита проверяет сетевую доступность, клиентское подключение, создание временных топиков, надёжную запись данных, консистентность метаданных и best-effort чтение через consumer

Когда использовать

Подходит для первичной проверки кластера, валидации Kerberos и ACL, проверки после апгрейда Kafka, dual-mode сценариев и smoke test после миграций

Что выдаёт на выходе

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

Пакеты

kafka-cluster-testing-with-jdk11

Внутри этой сборки уже есть JDK 11. После распаковки достаточно заполнить конфигурацию и запустить скрипт

kafka-cluster-testing-without-jdk11

Эта сборка не содержит JDK. Перед запуском нужно либо экспортировать JAVA_HOME, либо указать реальный путь до Java в run.sh

shell
export JAVA_HOME=/path/to/JDK11
./run.sh

Пошаговая настройка

1. Распакуйте архив

Выберите пакет под своё окружение. Версия with-jdk11 готова к запуску сразу после заполнения конфига. Версия without-jdk11 требует установленный JDK 11

2. Откройте основной конфиг

Основной конфигурационный файл: conf/kafka-cluster-testing.toml

3. Заполните bootstrap servers

Минимально достаточно указать Kafka bootstrap servers. Для не-Kerberos smoke test этого уже достаточно

kafka-cluster-testing.toml
[kafka]
bootstrap_servers = "kafka01.example.com:9093,kafka02.example.com:9093,kafka03.example.com:9093"

4. Выберите режим аутентификации

Для обычного кластера используйте security_protocol = "PLAINTEXT" и auth.mode = "none". Для Kerberos-защищённого кластера используйте SASL_PLAINTEXT или SASL_SSL вместе с auth.mode = "auto" или kerberos

5. Не забудьте principal и keytab для Kerberos

Если тестируется Kerberos Kafka-кластер, нужно указать валидные krb5.conf, principal и keytab. На практике самые важные поля - bootstrap servers, principal и путь до keytab

kafka-cluster-testing.toml
[kafka]
bootstrap_servers = "kafka01.example.com:9093,kafka02.example.com:9093,kafka03.example.com:9093"
security_protocol = "SASL_PLAINTEXT"

[auth]
mode = "auto"

[auth.kerberos]
krb5_conf = "/etc/krb5.conf"
principal = "kafka/client01.example.com@EXAMPLE.COM"
keytab = "/etc/security/keytabs/kafka-client.keytab"
sasl_mechanism = "GSSAPI"
sasl_kerberos_service_name = "kafka"

6. Запустите утилиту

Без аргументов утилита использует conf/kafka-cluster-testing.toml. При необходимости можно передать явный путь к конфигу

shell
./run.sh
shell
./run.sh /path/to/kafka-cluster-testing.toml

Режимы конфигурации

Без Kerberos Используйте PLAINTEXT вместе с auth.mode = "none".
С Kerberos Используйте SASL_PLAINTEXT или SASL_SSL вместе с auth.mode = "auto" или kerberos.
Некорректная конфигурация security_protocol = "SASL_*" вместе с auth.mode = "none" недопустимы и приводят к ошибке конфигурации/безопасности.

Коды завершения и файлы

0 Кластер работоспособен.
2 Техническая ошибка.
3 Ошибка безопасности или конфигурации.
Выходные файлы out/run.log, out/report.txt и out/*.json.

Пример отчёта

На странице опубликован вариант с example-доменами вместо реальных хостов

report.txt
====================================================================
                 KAFKA CLUSTER TEST REPORT
====================================================================
RESULT:    OK
exitCode:  0
totalMs:   36449

Run:
  runId:      20260323-202126-kafka01-dev01.example.com
  startedAt:  2026-03-23T17:21:26.493501Z

Connection:
  protocol:   SASL_PLAINTEXT
  authMode:   auto
  bootstrap:
    - kafka01.example.com:9093
    - kafka02.example.com:9093
    - kafka03.example.com:9093

Test objects:
  consumerGroup:
    - kct.20260323-202126-kafka01-dev01.example.com
  topics:
    - kct.20260323-202126-kafka01-dev01.example.com.1
    - kct.20260323-202126-kafka01-dev01.example.com.2
    - kct.20260323-202126-kafka01-dev01.example.com.3

Steps:
  STATUS  STEP                 TOOK_MS  DETAILS
  ------  -------------------  -------  ----------------------------------------
  OK      AUTH_RESOLVE               0  mode=auto protocol=SASL_PLAINTEXT
                                        principal=kafka/client01.example.com@EXAMPLE.COM
                                        keytab=/etc/security/keytabs/kafka-client.keytab
  OK      CONNECT                  829  clusterId=INYl1VqlQx281uuTzdGDDw nodes=7
  OK      CREATE_TOPICS            902  created=[kct.20260323-202126-kafka01-dev01.example.com.1,
                                        kct.20260323-202126-kafka01-dev01.example.com.2,
                                        kct.20260323-202126-kafka01-dev01.example.com.3]
  OK      WAIT_TOPICS_READY         47  topicsReady=3
  OK      VALIDATE_TOPICS           11  partitions=1 replicationFactor=3
  OK      PRODUCE                 1763  topics=3 messagesPerTopic=5 total=15
  OK      WAIT_END_OFFSETS         160  endOffsetsReached>=5
  WARN    CONSUME_ASSIGN             0  assigned=[]
  SKIP    CONSUME                 5087  consumer_group_not_assigned_within_timeout: assigned=[] (non-fatal for
                                        cluster health)
  OK      GROUP_OFFSETS            220  reason=post_run mode=no_commits partitions=3;
                                        kct.20260323-202126-kafka01-dev01.example.com.1-0
                                        committed=-1 end=5 lag=-1;
                                        kct.20260323-202126-kafka01-dev01.example.com.2-0
                                        committed=-1 end=5 lag=-1;
                                        kct.20260323-202126-kafka01-dev01.example.com.3-0
                                        committed=-1 end=5 lag=-1 totalLag=0
  OK      CLEANUP_DELETE_TOPI      377  deleted=[kct.20260323-202126-kafka01-dev01.example.com.1,
                                        kct.20260323-202126-kafka01-dev01.example.com.2,
                                        kct.20260323-202126-kafka01-dev01.example.com.3]

====================================================================

Шаг CONSUME является best-effort. Если за отведённый timeout не получено назначение consumer group, шаг может быть помечен как SKIP, а общий smoke test при этом всё равно остаётся успешным