Spring Boot + Apache Kafka и SSL в Docker контейнере

Artiom Mozgovoy
4 min readJun 7, 2020

--

Фото от Esperanza Gates

Друзья, привет. В статье я расскажу как собрать решение для быстрого старта вашей разработки из standalone Java приложения, брокера и Zookeeper’а Kafka, поднятых в отдельных Docker контейнерах и настроенной plaintext авторизацией для доступа как с локальной машины, так и из внешнего контура.

👇 Готовый проект на github можно забрать в конце статьи 👇

Выбор docker образа Apache Kafka + Zookeeper

Для начала придется определиться с вендором образа Apache Kafka для нашего контейнера. Требования каждого конкретного проекта разнятся по необходимому уровню безопасности и надежности решения, в некоторых случаях конечно придется собирать свой собственный образ, но для большинства проектов будет разумным выбрать один из доступных на docker hub. На 2020й год есть три основных популярных вендора образов kafka+zookeper:

  • образы от confluent [ субъективно, большой плюс — поставляются разработчиками самой Apache Kafka и наиболее надежны в плане информационной безопасности ]
  • образы от bitnami [плюс, в сравнении с confluent, в том что образы нуждаются в минимальной конфигурации и “стартуют из коробки”]
  • образы от wurstmeister [в этом примере я буду использовать их, потому что у проекта наибольшее активное комьюнити на github и hub.docker, а так же отличная документация ]

Установка Docker-compose

Для запуска и конфигурирования образов используется docker-compose, который позволяет запускать мультиконтейнерные приложения. Без него не обойтись, потому что минимальная конфигурация kafka предусматривает связку из zookeeper и хотя бы одного брокера.

Сompose идет в комплекте с mac/windows — дистрибутивом Docker, так что установка необходимого окружения сводится к загрузке и установке дистрибутива с https://docs.docker.com/engine/install/.

А вот linux пользователям его необходимо устанавливать отдельно. За гайдом по установке docker + compose лучше всего обратиться к официальной документации https://docs.docker.com/compose/install/.

Пишем yaml файл для compose

Общая схема нашей конфигурации для всех клиентов и контейнеров будет следующей:

К одному координатору будет подключаться один брокер с открытыми портами 9093 — для localhost подключений и 9092 для подключений с других машин.

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

В итоге файл будет иметь следующий вид(адрес <your public IP here> нужно заменить на ваш публичный IP для возможности доступа из других сетей):

version: '2'
services:
zookeeper:
image: wurstmeister/zookeeper
expose:
- "2181"
kafka:
image: wurstmeister/kafka
ports:
- "9092:9092"
expose:
- "9093"
environment:
KAFKA_AUTO_CREATE_TOPICS_ENABLE: 'true'
KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://<your public IP here>:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:SASL_PLAINTEXT
KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"
KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: PLAIN
depends_on:
- zookeeper
volumes:
- ./:/etc/kafka

Авторизация клиентов

Для того что бы включить авторизацию необходимо передать kafka_server_jaas.conf файл в kafka. В папке с compose yaml файлом создадим kafka_server_jaas.conf и в нем добавим одного пользователя admin с паролем admin-secret:

KafkaServer {
org.apache.kafka.common.security.plain.PlainLoginModule required
username="admin"
password="admin-secret"
user_admin="admin-secret";
};
Client {};

Этот файл будет передаваться в образ с kafka брокером через:

  1. указание пути к файлу в непосредственно конфиге kafka
KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"

2. маппинг локальной директории с файлом в /etc/kafka директорию образа

volumes:
- ./:/etc/kafka

Запуск контейнеров

В итоге мы должны получить 2 файла, которые находятся в одной директории:

  • docker-compose.yml
  • kafka_server_jaas.conf

В этой директории нужно вызвать команду:

$ docker-compose up -d

флаг -d позволяет запуститься в Detached mode и закрыть консоль при необходимости без выключения образов.

Java клиент на Spring Boot

Напишем минималистичный клиент с возможностью публикации и чтения сообщений из kafka. Для этого создадим новый проект через Spring Initializr или любой другой привычный вам инструмент. Будет достаточно подключить одну зависимость:

spring-kafka

Настройку Spring Boot приложения я предпочитаю по возможности реализовывать через конфигурационные yaml файлы с минимальной конфигураций в Java коде. За счет встроенного структурирования в Yaml-формат, эти файлы гораздо удобнее для человеческого восприятия, чем .properties файлы и позволяют группировать настройки по модулям. Единственный недостаток .yml конфигурации в том, что она не поддерживается в тестах, но он легко обходится встроенными инструментами boot’.

Очень рекомендую попробовать посмотреть как изменится ваше восприятие старого .properties файла (особенно для больших проектов), если его переписать в yaml. Это можно сделать в пару кликов на https://www.toyaml.com/index.html.

В resources проекта создадим файл application.yml cо следующим содержанием:

Этот сетап работает для последовательной вычитки по одному сообщению (max-poll-records: 1) одним слушателем (concurrency: 1) и требует ручного подтверждения обработки сообщения в listener (ack-mode: manual_immediate).

Добавим классы producer и consumer

Слушатель получает сообщение и логирует все доступные сведения о нем в консоль.

Запустим добавление сообщений в очередь каждые 3 секунды

для включения шедулера надо повесить анотацию @EnableScheduling на наше spring приложение

Voilà! и приложение готово к запуску. Можно запускать dev вариант с локальным клиентом и локальной kafka, а так же к kafka можно получить доступ из других сетей если открыть 9092 порт и указать в application.yml адрес хоста.

Удачи в разработке! Код доступен в репозитории -https://github.com/layonez/kafka-example

--

--

Artiom Mozgovoy
Artiom Mozgovoy

Written by Artiom Mozgovoy

Currently making beautiful frontend for Westwing

Responses (1)