MQ

[kafkajs] docker를 이용한 kafka clustering 셋팅 방법

꼰딩 2023. 2. 26. 22:35

처음에는 local에서 kafka를 띄웠었습니다. (도움받은 블로그: https://yooloo.tistory.com/68)
나중에는 docker로 띄우더라도, 처음에는 local에서 직접 노가다하며 띄워보고 싶었기 때문입니다.


그런데 clustering을 구성하려고 하니 설정파일을 일일이 변경을 해주거나, 명령어에 덧붙여야해서 결국 docker로 띄우기로 결정했습니다.


구글에 검색을 해서 다른 분들이 작성하신 글을 보고 따라하니, 첫 번째 난관에 부딪혔습니다.

kafka에 대한 docker image의 종류가 여러개였기 때문입니다.

1. confluentinc/cp-kafka, confluentinc/cp-zookeeper

2. wurstmeister/kafka, wurstmeister/zookeeper

3. Bitnami, etc.


제 목표는 두가지 였습니다.

1. zookeeper 3, kafka 3(broker 3, partition 3) 으로 clustering 구성

2. node.js 앱에서 kafkajs를 사용하여 kafka client 구성


single broker로 2번 조건을 충족시키는 docker-compose.yml은 다음 사이트에서 얻었습니다.

https://javascript.plainenglish.io/a-beginners-introduction-to-kafka-with-typescript-using-nestjs-7c92fe78f638


1번 조건을 충족시키는 docker-compose.ymld은 박핑구님의 블로그에서 얻었습니다.

https://pinggoopark.tistory.com/299

https://pinggoopark.tistory.com/469


single broker docker-compose.yml에 박핑구님의 299번 docker-compose.yml 옵션을 추가했더니 kafka가 제대로 돌아가지 않았습니다.


한참을 시도해보다가 박핑구님의 299번 yml 파일은 wurstmeister 이미지였기때문에 설정 옵션이 달라 안되는 것으로 결론 지었습니다. (469번 글도 외부 접속 ip를 지정하지 않아 node.js 앱에서 연결이 불가합니다.)


kafka를 개발한 confluent의 공식 이미지인 confluentinc/cp-kafka를 사용하기로 결정했습니다.


여러 옵션을 하나씩 추가해가면서 되는 옵션을 확인하고, https://devocean.sk.com/blog/techBoardDetail.do?ID=164016 이런 블로그에서 각 옵션 별 설명도 확인했습니다.


다음은 1,2번 조건을 모두 충족하는 docker-compose.yml 입니다.

version: '2.1'

services:
  zookeeper-1:
    hostname: zookeeper-1
    container_name: zookeeper-1
    image: zookeeper:latest
    restart: always
    ports:
      - 2181:2181
    environment:
      ZOO_MY_ID: 1
      ZOO_SERVERS: server.1=zookeeper-1:2888:3888;2181 server.2=zookeeper-2:2888:3888;2181 server.3=zookeeper-3:2888:3888;2181
    volumes:
      - type: bind
        source: ./data/zk-cluster/zookeeper-1/data
        target: /data
        read_only: false

  zookeeper-2:
    hostname: zookeeper-2
    container_name: zookeeper-2
    image: zookeeper:latest
    restart: always
    ports:
      - 2182:2181
    environment:
      ZOO_MY_ID: 2
      ZOO_SERVERS: server.1=zookeeper-1:2888:3888;2181 server.2=zookeeper-2:2888:3888;2181 server.3=zookeeper-3:2888:3888;2181
    volumes:
      - type: bind
        source: ./data/zk-cluster/zookeeper-2/data
        target: /data
        read_only: false

  zookeeper-3:
    hostname: zookeeper-3
    container_name: zookeeper-3
    image: zookeeper:latest
    restart: always
    ports:
      - 2183:2181
    environment:
      ZOO_MY_ID: 3
      ZOO_SERVERS: server.1=zookeeper-1:2888:3888;2181 server.2=zookeeper-2:2888:3888;2181 server.3=zookeeper-3:2888:3888;2181
    volumes:
      - type: bind
        source: ./data/zk-cluster/zookeeper-3/data
        target: /data
        read_only: false

  zookeeper-navigator:
    hostname: zookeeper-navigator
    container_name: zookeeper-navigator
    image: elkozmon/zoonavigator:latest
    restart: always
    ports:
      - 9000:9000
    environment:
      HTTP_PORT: 9000
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3

  kafka-1:
    image: confluentinc/cp-kafka:latest
    hostname: kafka-1
    container_name: kafka-1
    ports:
      - 29092:29092
    environment:
      KAFKA_BROKER_ID: 1
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-1:9092, PLAINTEXT_HOST://localhost:29092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      # KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
      KAFKA_ZOOKEEPER_CONNECT: zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181
      BOOTSTRAP_SERVERS: kafka-1:9092,kafka-2:9093,kafka-3:9094
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3
    restart: always

  kafka-2:
    image: confluentinc/cp-kafka:latest
    hostname: kafka-2
    container_name: kafka-2
    ports:
      - 29093:29093
    environment:
      KAFKA_BROKER_ID: 2
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-2:9093, PLAINTEXT_HOST://localhost:29093
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      # KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9093
      KAFKA_ZOOKEEPER_CONNECT: zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181
      BOOTSTRAP_SERVERS: kafka-1:9092,kafka-2:9093,kafka-3:9094
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3
    restart: always

  kafka-3:
    image: confluentinc/cp-kafka:latest
    hostname: kafka-3
    container_name: kafka-3
    ports:
      - 29094:29094
    environment:
      KAFKA_BROKER_ID: 3
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka-3:9094, PLAINTEXT_HOST://localhost:29094
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 3
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      # KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9094
      KAFKA_ZOOKEEPER_CONNECT: zookeeper-1:2181,zookeeper-2:2181,zookeeper-3:2181
      BOOTSTRAP_SERVERS: kafka-1:9092,kafka-2:9093,kafka-3:9094
    depends_on:
      - zookeeper-1
      - zookeeper-2
      - zookeeper-3
    restart: always
  kafka_ui:
    image: provectuslabs/kafka-ui:latest
    restart: always
    depends_on:
      - kafka-1
    ports:
      - 8080:8080
    environment:
      KAFKA_CLUSTERS_0_ZOOKEEPER: zookeeper-1:2181,zookeeper-2:2182,zookeeper-3:2183
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka-1:9092,kafka-2:9093,kafka-3:9094

여기서 KAFKA_ADVERTISED_LISTENERS 부분에 있는 PLAINTEXT_HOST 와
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP이 있어야 외부 앱에서 접근이 가능합니다.


PLAINTEXT://이름:포트 이것은 카프카 내에서 통신하기 위해 필요한 주소이고, PLAINTEXT_HOST는 외부에서 통신하기 위한 주소라고 이해했습니다.


kafka_ui도 연결을 했는데, 처음에는 CMAK을 사용하려고 했으나 https://devocean.sk.com/blog/techBoardDetail.do?ID=163980 이 글을 보고 결정했습니다.



kafka_ui



띄운 kafka docker container 에서 config 파일들을 보려면 /etc/kafka 디렉토리를 확인하면 됩니다.


다만 vim이 설치되어 있지 않은데, sudo 명령어가 안멱허서 설치하려면 root 권한으로 접속해야 합니다.
이 부분은 검색을 해봤고, https://stackoverflow.com/questions/28721699/root-password-inside-a-docker-container 이 사이트에서 답을 찾았습니다.


애초에 컨테이너 bash에 접속할 때 docker exec -u 0 -it containerName bash로 접속하면 root 권한으로 접속됩니다.
그러면 vim같은것들을 설치할 수 있습니다.


전 블로그에서 작성했던 글: https://velog.io/@chss3339/kafka-docker-설정

'MQ' 카테고리의 다른 글

[kafkajs] consumer  (0) 2023.03.01
[kafkajs] producer 설정  (0) 2023.02.27
[kafkajs] kafka에 대한 간단한 소개  (0) 2023.02.26
kafka 글을 작성하기 전에  (0) 2023.02.26