Triển khai nhanh kafka server bằng docker compose

Posted on: 2/21/2025 4:34:00 PM

Chào anh em!

Bài viết này mình hướng dẫn anh em chi tiết cách triển khai Apache Kafka sử dụng SASL/PLAIN Authentication để bảo mật kết nối giữa Kafka Brokerclient. Ở đây mình sẽ sử dụng Docker Compose để cài đặt Kafka và Zookeeper.

Yêu cầu ban đầu

  • Triển khai nhanh
  • Có thể kết nối từ bên ngoài
  • Hỗ trợ xác thực qua SASL/PLAIN Authentication (với username + password) 
  • Tự tạo topic nếu chưa có (cái này tùy mục đích của anh em nhé)
  • Mount các thư mục quan trọng ra ngoài để không mất dữ liệu & cũng dễ debug
  • Có UI quản lý

Cấu trúc thư mục

F:\Docker\kafka\
│── docker-compose.yml
│── kafka_server_jaas.conf
│── client.properties
│── .env
└── volumes\
    ├── kafka\
    └── zookeeper\

Tạo file docker-compose.yml

services:
  zookeeper:
    image: confluentinc/cp-zookeeper:7.9.0
    volumes: 
        - "F:/Docker/kafka/zookeeper_jaas.conf:/etc/kafka/zookeeper_jaas.conf"
        - "F:/Docker/kafka/volumes/zookeeper:/var/lib/zookeeper"
        - "F:/Docker/kafka/volumes/zookeeper/log:/var/lib/zookeeper/log"
    hostname: zookeeper
    container_name: zookeeper
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
      ZOOKEEPER_AUTH_PROVIDER_XDIGEST: "org.apache.zookeeper.server.auth.DigestAuthenticationProvider"
      ZOOKEEPER_REQUIRE_CLIENT_AUTH_SCHEME: "digest"
      ZOOKEEPER_DATA_DIR: /var/lib/zookeeper
      ZOOKEEPER_LOG_DIR: /var/lib/zookeeper/log      
    command:
      - sh
      - -c
      - "export KAFKA_OPTS='-Djava.security.auth.login.config=/etc/kafka/zookeeper_jaas.conf'; /etc/confluent/docker/run"
  kafka:
    image: confluentinc/cp-kafka:7.9.0
    hostname: kafka
    container_name: kafka
    depends_on:
      - zookeeper
    volumes: 
        - "F:/Docker/kafka/volumes/kafka:/var/lib/kafka/data"
        - "F:/Docker/kafka/kafka_server_jaas.conf:/etc/kafka/kafka_server_jaas.conf"
        - "F:/Docker/kafka/client.properties:/etc/kafka/client.properties"
    ports:
      - "9092:9092"
      - "9093:9093"
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ZOOKEEPER_CONNECT: 'zookeeper:2181'
      
      # Cấu hình xác thực với Zookeeper
      KAFKA_OPTS: "-Djava.security.auth.login.config=/etc/kafka/kafka_server_jaas.conf"
      #KAFKA_ZOOKEEPER_SET_ACL: "true"
      
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
      # Cấu hình SASL/SCRAM cho Kafka
      KAFKA_ADVERTISED_HOST_NAME: ${HOST_PUBLIC_IP}
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,SASL_PLAINTEXT:SASL_PLAINTEXT
      KAFKA_LISTENERS: PLAINTEXT://kafka:29092,SASL_PLAINTEXT://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,SASL_PLAINTEXT://${HOST_PUBLIC_IP}:9093
      KAFKA_SASL_ENABLED_MECHANISMS: PLAIN
      KAFKA_INTER_BROKER_LISTENER_NAME: SASL_PLAINTEXT
      KAFKA_SASL_MECHANISM_INTER_BROKER_PROTOCOL: PLAIN
      KAFKA_LISTENER_NAME_SASL_PLAINTEXT_SASL_ENABLED_MECHANISMS: PLAIN
      
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_LOG_RETENTION_HOURS: 168  # Giữ messages trong 7 ngày (mặc định là 168 giờ)
      KAFKA_LOG_RETENTION_BYTES: -1   # Không giới hạn dung lượng
  kafka-ui: #UI for managerment
    container_name: kafka-ui
    image: provectuslabs/kafka-ui:latest
    ports:
      - 8080:8080
    depends_on:
      - kafka
    environment:
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: ${HOST_PUBLIC_IP}:9093
      KAFKA_CLUSTERS_0_PROPERTIES_SECURITY_PROTOCOL: SASL_PLAINTEXT
      KAFKA_CLUSTERS_0_PROPERTIES_SASL_MECHANISM: PLAIN
      KAFKA_CLUSTERS_0_PROPERTIES_SASL_JAAS_CONFIG: 'org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="admin-secret";'
      DYNAMIC_CONFIG_ENABLED: true # not necessary for sasl auth, added for tests
  

Tạo file xác thực kafka_server_jaas.conf

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

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

Lưu ý:

  • user_admin="admin-secret" → Đây là tài khoản xác thực Kafka Broker.
  • username="admin" → Tài khoản client kết nối Kafka.
  • Chú ý dấu ; ở cuối.

Tạo file client.properties

security.protocol=SASL_PLAINTEXT
sasl.mechanism=PLAIN
sasl.jaas.config=org.apache.kafka.common.security.plain.PlainLoginModule required username="admin" password="admin-secret";

File này giúp client kết nối Kafka qua cổng 9093 có bảo mật, anh em bỏ qua cái này cũng không sao (mục đích để chạy mấy command test trong docker container sau khi tạo thôi)

1 số lệnh test:

#list topic
docker exec -it kafka kafka-topics --bootstrap-server localhost:9093 --list --command-config 
client.properties

#create topic
docker exec -it kafka kafka-topics --bootstrap-server localhost:9093 --create --topic test-topic --partitions 1 --replication-factor 1 --command-config client.properties

Tạo file .env để lưu các biến môi trường, cái này tùy anh em, ví dụ như sau:

HOST_PUBLIC_IP=123.456.789.xxx #public ip

Ngon lành rồi, giờ chạy thôi :D

docker compose up -d

Anh em có thể truy cập UI quản lý từ localhost:8080

Kafka UI

Lưu ý:

  • Thay admin-secret thành chuỗi bí mật khó khó tí anh em nhé :D