Docker 설치

Docker 설치

Docker 컨테이너로 Pinot 클러스터를 실행하는 방법이에요. 로컬 평가와 CI 환경에 잘 맞고, docker-compose나 개별 docker run 명령으로 빠르게 구성 요소를 띄울 수 있어요.

출처: Docker

본문

이 페이지를 마치면 알게 되는 것 (Outcome)

Docker를 사용해 멀티 컴포넌트 Pinot 클러스터를 시작할 수 있어요. 로컬 평가와 CI 환경에 적합해요.

사전 요구 사항 (Prerequisites)

  • Docker 설치 및 실행 중
  • 권장 Docker 리소스 설정:
    • CPU: 8개
    • 메모리: 16 GB
    • Swap: 4 GB
    • 디스크 이미지 크기: 60 GB

단계 (Steps)

1. 이미지 버전 설정

export PINOT_VERSION=1.5.1
export PINOT_IMAGE=apachepinot/pinot:${PINOT_VERSION}
export ZK_IMAGE=zookeeper:3.9.5
export KAFKA_IMAGE=apache/kafka:4.0.0

현재 안정 릴리스 버전은 버전 레퍼런스 페이지에서 확인할 수 있어요.

2. Pinot 이미지 내려받기

docker pull apachepinot/pinot:${PINOT_VERSION}

사용 가능한 모든 태그는 Docker Hub에서 볼 수 있어요.

3. 클러스터 시작

Docker Compose (권장)

docker-compose.yml이라는 파일을 다음 내용으로 만드세요:

version: '3.7'

services:
  pinot-zookeeper:
    image: ${ZK_IMAGE:-zookeeper:3.9.5}
    container_name: "pinot-zookeeper"
    restart: unless-stopped
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000
    networks:
      - pinot-demo
    healthcheck:
      test: ["CMD", "zkServer.sh", "status"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 10s

  pinot-controller:
    image: ${PINOT_IMAGE:-apachepinot/pinot:1.5.1}
    command: "StartController -zkAddress pinot-zookeeper:2181"
    container_name: "pinot-controller"
    restart: unless-stopped
    ports:
      - "9000:9000"
    environment:
      JAVA_OPTS: "-Dplugins.dir=/opt/pinot/plugins -Xms1G -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-controller.log"
    depends_on:
      pinot-zookeeper:
        condition: service_healthy
    networks:
      - pinot-demo
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:9000/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 10s

  pinot-broker:
    image: ${PINOT_IMAGE:-apachepinot/pinot:1.5.1}
    command: "StartBroker -zkAddress pinot-zookeeper:2181"
    container_name: "pinot-broker"
    restart: unless-stopped
    ports:
      - "8099:8099"
    environment:
      JAVA_OPTS: "-Dplugins.dir=/opt/pinot/plugins -Xms4G -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-broker.log"
    depends_on:
      pinot-controller:
        condition: service_healthy
    networks:
      - pinot-demo
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8099/health || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 10s

  pinot-server:
    image: ${PINOT_IMAGE:-apachepinot/pinot:1.5.1}
    command: "StartServer -zkAddress pinot-zookeeper:2181"
    container_name: "pinot-server"
    restart: unless-stopped
    ports:
      - "8098:8098"
    environment:
      JAVA_OPTS: "-Dplugins.dir=/opt/pinot/plugins -Xms4G -Xmx16G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-server.log"
    depends_on:
      pinot-broker:
        condition: service_healthy
    networks:
      - pinot-demo
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:8097/health/readiness || exit 1"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 10s

  pinot-minion:
    image: ${PINOT_IMAGE:-apachepinot/pinot:1.5.1}
    command: "StartMinion -zkAddress pinot-zookeeper:2181"
    restart: unless-stopped
    container_name: "pinot-minion"
    ports:
      - "6000:6000"
    depends_on:
      - pinot-broker
    networks:
      - pinot-demo

  pinot-kafka:
    image: ${KAFKA_IMAGE:-apache/kafka:4.0.0}
    container_name: "kafka"
    restart: unless-stopped
    ports:
      - "9092:9092"
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:9093
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      CLUSTER_ID: MkU3OEVBNTcwNTJENDM2Qk
    networks:
      - pinot-demo
    healthcheck:
      test: ["CMD-SHELL", "/opt/kafka/bin/kafka-broker-api-versions.sh --bootstrap-server kafka:9092"]
      interval: 30s
      timeout: 10s
      retries: 5
      start_period: 10s
    deploy:
      replicas: ${KAFKA_REPLICAS:-0}

networks:
  pinot-demo:
    name: pinot-demo
    driver: bridge

클러스터를 시작합니다:

docker compose --project-name pinot-demo up

실시간 스트리밍용으로 Kafka도 시작하려면:

export KAFKA_REPLICAS=1
docker compose --project-name pinot-demo up

개별 docker run 명령

네트워크 생성:

docker network create -d bridge pinot-demo

ZooKeeper 시작:

docker run \
    --network=pinot-demo \
    --name pinot-zookeeper \
    --restart always \
    -p 2181:2181 \
    -d ${ZK_IMAGE}

Pinot Controller 시작:

docker run --rm -ti \
    --network=pinot-demo \
    --name pinot-controller \
    -p 9000:9000 \
    -e JAVA_OPTS="-Dplugins.dir=/opt/pinot/plugins -Xms1G -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-controller.log" \
    -d ${PINOT_IMAGE} StartController \
    -zkAddress pinot-zookeeper:2181

Pinot Broker 시작:

docker run --rm -ti \
    --network=pinot-demo \
    --name pinot-broker \
    -p 8099:8099 \
    -e JAVA_OPTS="-Dplugins.dir=/opt/pinot/plugins -Xms4G -Xmx4G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-broker.log" \
    -d ${PINOT_IMAGE} StartBroker \
    -zkAddress pinot-zookeeper:2181

Pinot Server 시작:

docker run --rm -ti \
    --network=pinot-demo \
    --name pinot-server \
    -p 8098:8098 \
    -e JAVA_OPTS="-Dplugins.dir=/opt/pinot/plugins -Xms4G -Xmx16G -XX:+UseG1GC -XX:MaxGCPauseMillis=200 -Xloggc:gc-pinot-server.log" \
    -d ${PINOT_IMAGE} StartServer \
    -zkAddress pinot-zookeeper:2181

Pinot Minion 시작 (선택):

docker run --rm -ti \
    --network=pinot-demo \
    --name pinot-minion \
    -p 6000:6000 \
    -d ${PINOT_IMAGE} StartMinion \
    -zkAddress pinot-zookeeper:2181

Kafka 시작 (선택):

Kafka 4.0은 KRaft 모드로 실행되며 ZooKeeper가 필요 없어요:

docker run --rm -ti \
    --network pinot-demo --name=kafka \
    -e KAFKA_NODE_ID=1 \
    -e KAFKA_PROCESS_ROLES=broker,controller \
    -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:9093 \
    -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://kafka:9092 \
    -e KAFKA_CONTROLLER_LISTENER_NAMES=CONTROLLER \
    -e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT \
    -e KAFKA_CONTROLLER_QUORUM_VOTERS=1@kafka:9093 \
    -e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \
    -e CLUSTER_ID=MkU3OEVBNTcwNTJENDM2Qk \
    -p 9092:9092 \
    -d ${KAFKA_IMAGE}

확인 (Verify)

모든 컨테이너가 실행 중인지 확인합니다:

docker container ls -a

ZooKeeper, Controller, Broker, Server, Minion 컨테이너가 모두 정상(healthy) 상태인 것을 볼 수 있을 거예요. http://localhost:9000에서 Pinot Query Console을 열어 클러스터가 준비됐는지 확인해 보세요.

Docker 이미지 버전 (Docker image versions)

Pinot Docker 이미지는 이제 JDK 25 런타임을 대상으로 해요. latest 태그는 25-ms-openjdk 런타임을 승격하며, latest-25 및 버전이 붙은 -25 태그는 명시적 고정을 위해 계속 사용할 수 있어요.

Pinot는 더 이상 *-21-* 서비스 이미지 태그를 게시하지 않아요. apachepinot/pinot:latest-21-amazoncorretto, apachepinot/pinot:latest-21-ms-openjdk 또는 유사한 버전의 *-21-* 태그에 고정되어 있다면 업그레이드 전에 *-25-* 태그로 이동하세요.

다음 단계 (Next step)

클러스터가 실행 중이에요. 데이터를 로드하려면 첫 테이블과 스키마로 계속 진행하세요.

더 알아보기 (Learn more)