Docker에 Pulsar 클러스터 배포하기
Docker에 Pulsar 클러스터 배포하기
Docker 명령으로 Pulsar 클러스터를 띄우려면 메타데이터 저장소, bookie, broker를 각각 컨테이너로 만들고 같은 네트워크에 연결해야 해요. 이 글에서는 Oxia를 메타데이터 저장소로 사용해 단일 클러스터를 Docker로 배포하는 전체 과정과, 컨테이너에서 설정을 적용하는 방법까지 정리해 드릴게요.
출처: 문서
본문
Docker 명령을 사용해 Docker에 Pulsar 클러스터를 배포하려면 다음 단계를 완료해야 해요.
1단계: Pulsar 이미지 가져오기
Docker에서 Pulsar를 실행하려면 Pulsar 각 구성 요소(메타데이터 저장소, bookie, broker)에 대해 컨테이너를 만들어야 해요. 이 튜토리얼은 새 클러스터에 권장되는 옵션인 Oxia를 메타데이터 저장소로 사용하는데, Oxia는 자체 이미지에서 실행돼요. bookie와 broker는 Pulsar 이미지에서 실행돼요. Oxia standalone은 단일 default 네임스페이스를 제공하며, Pulsar와 BookKeeper가 여기서 모두 사용해요. 프로덕션 클러스터는 별도의 Oxia 네임스페이스를 사용해요 (메타데이터 저장소 구성 참조).
다음 명령으로 Docker Hub에서 Pulsar 이미지를 가져올 수 있어요. 일부 커넥터를 사용하지 않으려면 여기서 apachepulsar/pulsar:latest를 사용할 수 있어요.
docker pull apachepulsar/pulsar-all:latest
2단계: 네트워크 만들기
Docker에 Pulsar 클러스터를 배포하려면 네트워크를 만들고 Oxia, bookie, broker의 컨테이너를 이 네트워크에 연결해야 해요.
다음 명령으로 pulsar 네트워크를 만들어요:
docker network create pulsar
3단계: 컨테이너 생성 및 시작
Oxia 컨테이너 만들기
Oxia 컨테이너를 만들고 Oxia 메타데이터 저장소를 시작해요.
docker run -d -p 6648:6648 --net=pulsar \
-v $(pwd)/data/oxia:/data \
--name oxia --hostname oxia \
oxia/oxia:latest \
oxia standalone
클러스터 메타데이터 초기화
Oxia 컨테이너를 성공적으로 만든 후 다음 명령으로 클러스터 메타데이터를 초기화할 수 있어요.
docker run --net=pulsar \
--name initialize-pulsar-cluster-metadata \
apachepulsar/pulsar-all:latest bash -c "bin/pulsar initialize-cluster-metadata \
--cluster cluster-a \
--metadata-store oxia://oxia:6648/default \
--configuration-store oxia://oxia:6648/default \
--web-service-url http://broker:8080 \
--broker-service-url pulsar://broker:6650"
bookie 컨테이너 만들기
bookie 컨테이너를 만들고 bookie 서비스를 시작해요.
docker run -d -e clusterName=cluster-a --net=pulsar \
-e metadataServiceUri=metadata-store:oxia://oxia:6648/default \
-v $(pwd)/data/bookkeeper:/pulsar/data/bookkeeper \
--name bookie --hostname bookie \
apachepulsar/pulsar-all:latest \
bash -c "bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"
broker 컨테이너 만들기
broker 컨테이너를 만들고 broker 서비스를 시작해요.
docker run -d -p 6650:6650 -p 8080:8080 --net=pulsar \
-e metadataStoreUrl=oxia://oxia:6648/default \
-e clusterName=cluster-a \
--name broker --hostname broker \
apachepulsar/pulsar-all:latest \
bash -c "bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"
4단계: 구성 개요
Pulsar Docker 이미지는 다음 구성 범주를 지원해요:
- JVM 구성: Broker와 BookKeeper 프로세스의 JVM 메모리 할당과 가비지 컬렉션을 제어해요. Docker에서 JVM 파라미터는 PULSAR_MEM, BOOKIE_MEM 같은 환경 변수로 설정돼요.
- Broker 구성 (broker.conf): 메타데이터 저장소 연결, 클러스터 이름, 포트, 메시지 복제 설정을 포함한 Pulsar Broker의 핵심 런타임 파라미터예요.
- BookKeeper 구성 (bookkeeper.conf): 저널 및 ledger 디렉터리, 컴팩션, 디스크 사용량 임계값을 포함한 BookKeeper Bookie의 저장 엔진 파라미터예요.
- Log4j 구성 (log4j2.yaml): 로그 수준, 출력 형식, 파일 롤링 전략을 포함한 로깅 프레임워크 설정이에요.
- 동적 구성: 일부 Broker 구성 속성은 컨테이너를 재시작하지 않고 pulsar-admin CLI 도구나 Admin REST API로 런타임에 갱신할 수 있어요.
사용 가능한 모든 구성 속성의 전체 목록은 Pulsar 구성 참조를 보세요.
Docker 구성 동작 방식
Pulsar Docker 이미지에는 메인 프로세스가 시작되기 전에 실행되는 apply-config-from-env.py라는 Python 스크립트가 포함돼요. 이 스크립트는 모든 환경 변수를 읽어 구성 파일 속성에 직접 매핑해요:
- 환경 변수 이름이 컨테이너에 포함된 내장 구성 파일(예: broker.conf 또는 bookkeeper.conf)의 키와 일치하면, 스크립트가 그 키의 값을 갱신해요.
- PULSAR_PREFIX_ 접두사가 붙은 환경 변수도 지원돼요. 접두사가 제거되고 남은 이름이 구성 키로 사용돼요. 이는 구성 키가 기존 시스템 환경 변수와 충돌할 때 유용해요. 포함된 구성 파일에는 없지만 구성 요소가 지원하는 구성 키(예: Pulsar의 ServiceConfiguration에 있는 키)에는 PULSAR_PREFIX_ 사용이 필요해요.
예를 들어 -e managedLedgerDefaultEnsembleSize=2를 설정하면 대상 구성 파일의 managedLedgerDefaultEnsembleSize 속성이 갱신돼요.
구성 방법
방법 1: -e 환경 변수 사용
docker run 명령에서 구성 속성을 환경 변수로 직접 전달해요:
docker run -d \
-e metadataStoreUrl=oxia://oxia:6648/default \
-e clusterName=cluster-a \
-e managedLedgerDefaultEnsembleSize=2 \
-e managedLedgerDefaultWriteQuorum=2 \
-e managedLedgerDefaultAckQuorum=2 \
apachepulsar/pulsar-all:latest \
bash -c "bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"
방법 2: --env-file로 일괄 로드
많은 구성 속성이 있다면 환경 파일을 사용해 docker run 명령을 깔끔하게 유지해요:
docker run -d --env-file ./broker-config.env \
apachepulsar/pulsar-all:latest \
bash -c "bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"
예시 broker-config.env 파일:
metadataStoreUrl=oxia://oxia:6648/default
clusterName=cluster-a
managedLedgerDefaultEnsembleSize=2
managedLedgerDefaultWriteQuorum=2
managedLedgerDefaultAckQuorum=2
PULSAR_MEM=-Xms4g -Xmx4g -XX:MaxDirectMemorySize=8g
방법 3: Docker Volume으로 커스텀 구성 파일 마운트
호스트의 커스텀 구성 파일을 컨테이너에 마운트해서 환경 변수 메커니즘을 완전히 우회할 수 있어요:
docker run -d \
-e PULSAR_MEM="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=8g" \
-v $(pwd)/my-broker.conf:/pulsar/conf/broker.conf \
apachepulsar/pulsar-all:latest \
bin/pulsar broker
일반적인 구성 예시
아래는 BookKeeper와 Broker 컨테이너에 흔히 사용하는 구성 속성 예시예요. 3단계에 보이는 docker run 명령에 -e 플래그를 더 추가해 동작을 커스터마이즈할 수 있어요.
BookKeeper
docker run -d -e clusterName=cluster-a --net=pulsar \
-e metadataServiceUri=metadata-store:oxia://oxia:6648/default \
# Storage directories: journal for write-ahead logs, ledgers for actual message data
-e journalDirectory=/pulsar/data/bookkeeper/journal \
-e ledgerDirectories=/pulsar/data/bookkeeper/ledgers \
# Disk usage thresholds: bookie will reject writes when usage exceeds these limits
-e diskUsageThreshold=0.95 \
-e diskUsageWarnThreshold=0.90 \
-e diskUsageLwmThreshold=0.87 \
# GC and Compaction: reclaim disk space by removing unused ledger data
-e gcWaitTime=900000 \
-e minorCompactionThreshold=0.2 \
-e minorCompactionInterval=3600 \
-e majorCompactionThreshold=0.5 \
-e majorCompactionInterval=86400 \
# JVM memory
-e BOOKIE_MEM="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=4g" \
# Extra JVM options: appended to JVM flags in the startup script, can override default JVM parameters
-e BOOKIE_EXTRA_OPTS="-XX:+ExitOnOutOfMemoryError" \
# Volume mounts: if possible, use separate physical disks for journal and ledger to improve read/write performance
-v $(pwd)/data/bookkeeper/journal:/pulsar/data/bookkeeper/journal \
-v $(pwd)/data/bookkeeper/ledgers:/pulsar/data/bookkeeper/ledgers \
--name bookie --hostname bookie \
apachepulsar/pulsar-all:latest \
bash -c "bin/apply-config-from-env.py conf/bookkeeper.conf && exec bin/pulsar bookie"
Broker
docker run -d -p 6650:6650 -p 8080:8080 --net=pulsar \
-e metadataStoreUrl=oxia://oxia:6648/default \
-e clusterName=cluster-a \
# Ensemble settings: control how messages are replicated across bookies (must not exceed the number of deployed bookies)
-e managedLedgerDefaultEnsembleSize=2 \
-e managedLedgerDefaultWriteQuorum=2 \
-e managedLedgerDefaultAckQuorum=1 \
# Ports: binary protocol port and HTTP admin port
-e brokerServicePort=6650 \
-e webServicePort=8080 \
# JVM memory
-e PULSAR_MEM="-Xms4g -Xmx4g -XX:MaxDirectMemorySize=8g" \
# Extra JVM options: appended to JVM flags in the startup script, can override default JVM parameters
-e PULSAR_EXTRA_OPTS="-Dio.netty.allocator.maxOrder=13 -Dio.netty.allocator.numDirectArenas=8 -Dio.netty.allocator.maxCachedBufferCapacity=1048576" \
--name broker --hostname broker \
apachepulsar/pulsar-all:latest \
bash -c "bin/apply-config-from-env.py conf/broker.conf && exec bin/pulsar broker"
팁 튜닝 참고 자료로 Pulsar Helm Chart values.yaml의 기본 구성을 참조할 수도 있어요.
더 알아보기 (Learn more)
- 메타데이터 저장소 관리 — Oxia를 메타데이터 저장소로 설정하는 방법을 익혀요.
- 바메탈 배포 — 컨테이너 없이 클러스터를 직접 구성해 봐요.
- Kubernetes 배포 개요 — Helm Chart로 배포하는 방법도 알아봐요.