Programming/Kafka

[kafka] multi-node zookeeper & kafka docker-compose.yml file

bisi 2020. 5. 19. 12:31

주키퍼와 카프카를 도커에 구축하기 위해서는 

도커로 하나씩 실행하는 것보단 도커 컴포즈나 도커 스왐으로 실행하는 것을 추천한다. 

 

주키퍼, 카프카 모두 분산 처리 시스템이기 때문에 여러개의 어플리케이션을 한꺼번에 띄우고 관리하는 것은

도커 컴포즈가 편하기 때문이다. 

 

도커 컴포즈를 사용하다보면 도커 스왐이나 쿠버네티스가 더 편할것 같고, 옮길까 고민도 했지만

우선 도커 컴포즈 기준으로 분산 처리 시스템을 구축해본다.

 

Sample docker-compose.yml 

주키퍼 1개와 카프카 3개를 셋팅한 도커 컴포즈 파일은 아래와 같다. 

version: "3.8"
services:
  zoo1:
    image: zookeeper:3.4.9
    restart: always
    hostname: zoo1    
    networks:
      broker-bridge:
        ipv4_address: 172.18.0.11
    ports:
      - "2181:2181"
    environment:
        ZOO_MY_ID: 1
        ZOO_PORT: 2181
        ZOO_SERVERS: server.1=zoo1:2888:3888
    volumes:
      - /home/broker/zookeeper-kafka-data/zoo1/data:/data
      - /home/broker/zookeeper-kafka-data/zoo1/datalog:/datalog
  
  kafka1:
    image: confluentinc/cp-kafka:5.5.0
    hostname: kafka1
    restart: always
    networks:
      broker-bridge:
        ipv4_address: 172.18.0.21
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_LISTENERS: LISTENER_DOCKER_INTERNAL://kafka1:19092,LISTENER_DOCKER_EXTERNAL://${DOCKER_HOST_IP:-127.0.0.1}:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_DOCKER_INTERNAL:PLAINTEXT,LISTENER_DOCKER_EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_DOCKER_INTERNAL
      KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
      KAFKA_BROKER_ID: 1
      KAFKA_LOG4J_LOGGERS: "kafka.controller=INFO,kafka.producer.async.DefaultEventHandler=INFO,state.change.logger=INFO"
      # relication facotor      
      KAFKA_DEFAULT_REPLICATION_FACTOR : 2
      # partition
      KAFKA_NUM_PARTITIONS: 3
    volumes:
      - /home/broker/zookeeper-kafka-data/kafka1/data:/var/lib/kafka/data
      # you have to create server.properties file before starting docker compose.
      - /home/broker/conf/server1.properties:/etc/kafka/server.properties      
    depends_on:
      - zoo1

  kafka2:
    image: confluentinc/cp-kafka:5.5.0
    hostname: kafka2
    restart: always
    networks:
      broker-bridge:
        ipv4_address: 172.18.0.32
    ports:
      - "9093:9093"
    environment:
      KAFKA_ADVERTISED_LISTENERS: LISTENER_DOCKER_INTERNAL://kafka2:19093,LISTENER_DOCKER_EXTERNAL://${DOCKER_HOST_IP:-127.0.0.1}:9093
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_DOCKER_INTERNAL:PLAINTEXT,LISTENER_DOCKER_EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_DOCKER_INTERNAL
      KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
      KAFKA_BROKER_ID: 2
      KAFKA_LOG4J_LOGGERS: "kafka.controller=INFO,kafka.producer.async.DefaultEventHandler=INFO,state.change.logger=INFO"
      # relication facotor
      KAFKA_DEFAULT_REPLICATION_FACTOR : 2
      # partition
      KAFKA_NUM_PARTITIONS: 3
    volumes:
      - /home/broker/zookeeper-kafka-data/kafka2/data:/var/lib/kafka/data
      # you have to create server.properties file before starting docker compose.
      - /home/broker/conf/server2.properties:/etc/kafka/server.properties      
    depends_on:
      - zoo1

  kafka3:
    image: confluentinc/cp-kafka:5.5.0
    hostname: kafka3
    restart: always
    networks:
      broker-bridge:
        ipv4_address: 172.18.0.33
    ports:
      - "9094:9094"
    environment:
      KAFKA_ADVERTISED_LISTENERS: LISTENER_DOCKER_INTERNAL://kafka3:19094,LISTENER_DOCKER_EXTERNAL://${DOCKER_HOST_IP:-127.0.0.1}:9094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: LISTENER_DOCKER_INTERNAL:PLAINTEXT,LISTENER_DOCKER_EXTERNAL:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: LISTENER_DOCKER_INTERNAL
      KAFKA_ZOOKEEPER_CONNECT: "zoo1:2181"
      KAFKA_BROKER_ID: 3
      KAFKA_LOG4J_LOGGERS: "kafka.controller=INFO,kafka.producer.async.DefaultEventHandler=INFO,state.change.logger=INFO"
      # relication facotor
      KAFKA_DEFAULT_REPLICATION_FACTOR : 2
      # partition
      KAFKA_NUM_PARTITIONS: 3
    volumes:
      - /home/broker/zookeeper-kafka-data/kafka3/data:/var/lib/kafka/data
      # you have to create server.properties file before starting docker compose.
      - /home/broker/conf/server3.properties:/etc/kafka/server.properties      
    depends_on:
      - zoo1

networks:
  broker-bridge:
    external:
      name: broker

 

주키퍼 3개와 카프카 3개를 셋팅한 도커 컴포즈 파일과 상세한 실행 방법 관련해서는 아래 github 페이지를 참고

https://github.com/logengineer/confluent-docker-compose

 

logengineer/confluent-docker-compose

zookeeper, kafka docker-compose yml. Contribute to logengineer/confluent-docker-compose development by creating an account on GitHub.

github.com

 

옵션 설명

image

  • 주키퍼 버전은 3.4.9로, 카프카 버전은 5.5.0(2020-05-18 기준 가장 최신) 사용한다.
  • 주키퍼의 최신 버전은 원인은 모르겠지만, 카프카(ver 5.5.0) 연동이 안된다.

 

restart: always 

  • 시스템 시작시 항상 해당 어플리케이션이 자동으로 실행된다.

 

port 

  • 도커에서 외부로 열어줄 포트를 설정한다. 
  • 자신의 포트를 열어주어야 주키퍼, 카프카가 서로 연동이 가능하다. 

 

volumes

  • 도커 내부에 저장하는 경로를 외부에 연동시킨다. 
  • server.properties 외부 연동
- /home/broker/conf/server1.properties:/etc/kafka/server.properties 

카프카의 server.properties 파일을 연동시켜서 관리하는 것도 시도 했지만, 파일 수정한 내용이 카프카가 실행할때 적용되지 않는 것 같아서 보류했다. 

 

 

 

enviroment

  • 주키퍼, 카프카 관련 옵션 셋팅으로 docker-compose.yml 파일에서 관리한다.
  • confluent 공식홈페이지의 도커 환경설정 내용을 참고하면 주키퍼와 카프카의 옵션은 prefix로 관리 가능하다.
    • 주키퍼는 'ZOOKEEPER_'를 입력하고 zookeeper.properties 항목의 옵션을 그대로 사용할 수 있다. 
    • 카프카는 'KAFKA_'를 입력하고 server.properties 항목의 옵션을 그대로 사용할 수 있다. 
    • 활용 예시로 카프카의 옵션에서 replication factor와 partition 옵션을 주기 위해 아래와 같이 설정하였다. 
# relication facotor 
KAFKA_DEFAULT_REPLICATION_FACTOR : 2 
# partition 
KAFKA_NUM_PARTITIONS: 3

 

network 

 

주의할 점

아파치 주키퍼 홈페이지에는 아래와 같이 하나의 물리 서버에 3개의 주키퍼를 띄우는 것을 추천하지 않는다.

Please be aware that setting up multiple servers on a single machine will not create any redundancy. If something were to happen which caused the machine to die, all of the zookeeper servers would be offline. Full redundancy requires that each server have its own machine. It must be a completely separate physical server. Multiple virtual machines on the same physical host are still vulnerable to the complete failure of that host.

redundancy를 보장하지 않고, 서버 하나가 죽으면 모든 주키퍼가 죽기 때문이다.

필자는 테스트 환경이기 때문에 싱글 서버에 멀티 노드로 구축했지만, 실제 운영해서는 이점을 꼭 고려해서 진행해야 한다. 

 

 

 

'Programming > Kafka' 카테고리의 다른 글

[kafka] Confluent Platform Versions  (0) 2020.05.20
[kafka] 보관 주기 설정  (0) 2020.05.15
[kafka][용어정리] ISR : In Sync Replica  (2) 2020.05.14