카프카 KRaft 모드 통합 클러스터 구성하기
카프카의 예정된 릴리즈 정보에 4.0 버전부터는 ZK 모드가 제거되고 KRaft 모드만 지원 예정입니다.
KRaft 모드도 ZK모드와 같이 실제 서비스 운영 시에는 컨트롤러와 브로커가 각각 분리되어있는 별도 구성 Cluster를 권장합니다.
여기에서는 규모가 비교적 작은 로컬 등의 개발 환경에서 카프카를 쉽게 사용하기 위해 KRaft 모드로 Docker Compose 구성을 했습니다.
docker는 Docker Desktop 4.31.0 버전을 설치한 환경에서 진행했습니다.
따라 하실 분들은 미리 Docker Desktop을 설치 및 실행해주셔야 합니다.
KRaft 모드 관련 자세한 정보는 아래 링크를 참고바랍니다.
- https://devocean.sk.com/blog/techBoardDetail.do?ID=165711
- https://devocean.sk.com/blog/techBoardDetail.do?ID=165737
docker compose 구성 정보
- 카프카 이미지:
bitnami kafka 3.7.0 - 클러스터 구성: Controller-Broker 역할을 하는 카프카 3대로 구성
- 카프카 브로커 모니터링:
kafka-ui v0.7.2
docker-compose.yml 파일 정보
name: kafak-kraft-cluster
networks:
infra:
driver: bridge
services:
kafka-1:
hostname: kafka1
image: 'bitnami/kafka:3.7.0'
ports:
- '10001:9094'
restart: unless-stopped
environment:
# KRaft settings
- KAFKA_CFG_NODE_ID=1
- KAFKA_KRAFT_CLUSTER_ID=kafkakraftclusters
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
- KAFKA_CFG_PROCESS_ROLES=controller,broker
# Listeners
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_LISTENERS=CLIENT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka1:9092,EXTERNAL://127.0.0.1:10001
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
# Clustering
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
networks:
- infra
volumes:
- "kafka1:/bitnami/kafka"
kafka-2:
hostname: kafka2
image: 'bitnami/kafka:3.7.0'
ports:
- '10002:9094'
restart: unless-stopped
environment:
# KRaft settings
- KAFKA_CFG_NODE_ID=2
- KAFKA_KRAFT_CLUSTER_ID=kafkakraftclusters
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
- KAFKA_CFG_PROCESS_ROLES=controller,broker
# Listeners
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_LISTENERS=CLIENT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka2:9092,EXTERNAL://127.0.0.1:10002
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
# Clustering
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
networks:
- infra
volumes:
- "kafka2:/bitnami/kafka"
kafka-3:
hostname: kafka3
image: 'bitnami/kafka:3.7.0'
ports:
- '10003:9094'
restart: unless-stopped
environment:
# KRaft settings
- KAFKA_CFG_NODE_ID=3
- KAFKA_KRAFT_CLUSTER_ID=kafkakraftclusters
- KAFKA_CFG_CONTROLLER_QUORUM_VOTERS=1@kafka1:9093,2@kafka2:9093,3@kafka3:9093
- KAFKA_CFG_PROCESS_ROLES=controller,broker
# Listeners
- ALLOW_PLAINTEXT_LISTENER=yes
- KAFKA_CFG_LISTENERS=CLIENT://:9092,CONTROLLER://:9093,EXTERNAL://:9094
- KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka3:9092,EXTERNAL://127.0.0.1:10003
- KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT
- KAFKA_CFG_CONTROLLER_LISTENER_NAMES=CONTROLLER
- KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT
- KAFKA_CFG_AUTO_CREATE_TOPICS_ENABLE=true
# Clustering
- KAFKA_CFG_OFFSETS_TOPIC_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=3
- KAFKA_CFG_TRANSACTION_STATE_LOG_MIN_ISR=2
networks:
- infra
volumes:
- "kafka3:/bitnami/kafka"
kafka-ui:
hostname: kafka-ui
image: provectuslabs/kafka-ui:v0.7.2
restart: unless-stopped
ports:
- '8888:8080'
depends_on:
- kafka-1
- kafka-2
- kafka-3
environment:
- KAFKA_CLUSTERS_0_NAME=local
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka1:9092,kafka2:9092,kafka3:9092
- DYNAMIC_CONFIG_ENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_TOPICAUDITENABLED=true
- KAFKA_CLUSTERS_0_AUDIT_CONSOLEAUDITENABLED=true
networks:
- infra
volumes:
kafka1:
driver: local
kafka2:
driver: local
kafka3:
driver: local
설정 관련 정보
bitnami의 kafka에서는 KAFKA_CFG_ 접두사로 Apache Kafka의 대부분의 환경 변수를 키에 직접 매핑됩니다.
예:
- Apache Kafka: KAFKA_ADVERTISED_LISTENERS
- Bitnami Kafka : KAFKA_CFG_ADVERTISED_LISTENERS
좀 더 자세한 bitnami kafka에 대한 설정 정보는 아래 링크를 참고 바랍니다.
Docker Compose 이미지 실행
1.docker compose 파일이 있는 디렉터리로 이동
2.콘솔창에서 아래의 명령어로 Docker Compose 실행
docker-compose -f docker-compose.yml up -d
// 아래와 같이 실행 가능
docker-compose up -d
// 명령어 실행 시
[+] Running 5/5
✔ Network kafak-kraft-cluster_infra Created 0.0s
✔ Container kafak-kraft-cluster-kafka-3-1 Started 0.4s
✔ Container kafak-kraft-cluster-kafka-1-1 Started 0.4s
✔ Container kafak-kraft-cluster-kafka-2-1 Started 0.4s
✔ Container kafak-kraft-cluster-kafka-ui-1 Started 0.4s
3.kafka ui로 브로커 상태 확인
- kafka ui(
http://localhost:8888/)로 이동

4.quorum 정보 확인
- 직접 카프카 컨테이너에 붙어서 확인
- 3대의 카프카 모두 연결되어 있기에 어떤 카프카에 붙어도 같은 결과 확인 가능
// 아래 명령어 실행
kafka-metadata-quorum.sh --bootstrap-server kafka-1:9092 describe --status
// quorum 정보
ClusterId: kafkakraftclusters
LeaderId: 2
LeaderEpoch: 2
HighWatermark: 4099
MaxFollowerLag: 0
MaxFollowerLagTimeMs: 143
CurrentVoters: [1,2,3]
CurrentObservers: []
참고
- https://devocean.sk.com/blog/techBoardDetail.do?ID=165711
- https://devocean.sk.com/blog/techBoardDetail.do?ID=165737
- https://github.com/ArminShoeibi/KafkaDockerCompose/blob/main/docker-compose-cluster.yml
- https://github.com/bitnami/containers/tree/main/bitnami/kafka
- https://cwiki.apache.org/confluence/display/KAFKA/KIP-833%3A+Mark+KRaft+as+Production+Ready
- https://github.com/confluentinc/kafka-images/blob/master/examples/confluent-server-kraft/docker-compose.yml