[Kafka] Kubernetes환경에서 Kafka 구성하기 (with Strimzi)

1. Kafka와 Strimzi에 대한 설명

Kafka란? Apache Kafka는 대용량 실시간 데이터를 처리하기 위한 분산 이벤트 스트리밍 플랫폼입니다. 주로 아래와 같은 역할을 수행합니다.

  • 메시지 큐(Message Queue): 생산자(Producer)가 보낸 메시지를 소비자(Consumer)가 받아서 처리할 수 있도록 저장하고 전달하는 역할을 합니다.
  • 분산 시스템: 여러 대의 서버(브로커)에 데이터를 분산 저장하여 확장성과 안정성을 확보합니다.
  • 고성능 및 확장성: 초당 수백만 건의 이벤트를 처리할 수 있으며, 필요에 따라 브로커 수를 늘려 성능을 확장할 수 있습니다.
  • 지속성: 디스크에 데이터를 저장하여 장애 발생 시에도 데이터 손실 없이 복구할 수 있습니다.

Strimzi란? Strimzi는 쿠버네티스(Kubernetes) 환경에서 Apache Kafka를 운영하기 위한 Operator 패턴을 구현한 도구입니다. 복잡한 Kafka 클러스터의 배포, 관리, 유지보수 작업을 자동화하고 간소화하는 역할을 합니다.

 

Strimzi Architecture (파란색으로 칠해진 Operator = Strimzi Operator)

출처: https://strimzi.io/docs/quickstart/0.15.0/

 

2. Strimzi로 Kafka를 구성하는 이유

Strimzi 사용 유무 비교

  Strimzi 미사용 (수동 관리) Strimzi 사용 (자동화 관리)
배포 쿠버네티스 Deployment, Service, StatefulSet 등을 직접 작성해야 합니다. Kafka CRD 파일 하나만 작성하면 Operator가 자동으로 배포합니다.
운영 브로커의 스케일링, 업그레이드, 장애 복구를 수동으로 관리해야 합니다. Operator가 스케일링, 업그레이드, 장애 복구를 자동으로 처리합니다.
토픽/유저 관리 Kafka 셸 스크립트나 외부 도구를 사용해 토픽, 사용자, ACL을 관리해야 합니다. KafkaTopic, KafkaUser CRD로 선언적으로 관리합니다.
운영 복잡성 쿠버네티스와 Kafka 양쪽 모두의 전문 지식이 필요하며, 많은 수작업이 발생합니다. 선언적 API를 통해 운영 복잡성을 크게 줄여줍니다.
자동화 수동 작업 위주 모든 라이프사이클을 자동화

 

Strimzi를 사용하는 이유는 결국 운영의 복잡성을 줄이고, 안정성과 효율성을 높여주기 위함입니다. 특히 컨테이너 환경에서 Kafka를 운영할 때 발생하는 수작업을 없애고, 개발자가 코드를 통해 인프라를 관리하는 GitOps와 같은 현대적인 방식을 가능하게 합니다.

 

3. Kafka with Strimzi 유용한 기능 3가지

3-1. 선언적(Declarative) 토픽 및 사용자 관리

Strimzi는 카프카 클러스터뿐만 아니라 토픽(KafkaTopic)과 사용자(KafkaUser)까지 쿠버네티스 리소스로 관리할 수 있게 해줍니다.

  • 동작 방식: 사용자는 KafkaTopic 또는 KafkaUser라는 YAML 파일을 작성하여, 토픽의 파티션 수, 복제 계수 또는 사용자의 인증 방식, 권한(ACL) 등을 정의합니다.
  • Strimzi의 역할: Strimzi Operator는 이 YAML 파일을 감지하고, Topic OperatorUser Operator를 통해 카프카 클러스터에 해당 토픽과 사용자를 자동으로 생성하고 관리합니다.
  • 장점:
    • 운영 효율성: 별도로 kafka-topics.sh 같은 명령어를 사용하거나 Kafka 내부 설정을 수동으로 변경할 필요가 없습니다.
    • GitOps 적용: 토픽과 사용자 설정을 Git 저장소에 YAML 파일로 보관하고, GitOps 파이프라인을 통해 배포할 수 있습니다. 이는 "코드로 인프라 관리(Infrastructure as Code)"를 가능하게 합니다.

 

3-2. 유연한 리스너 설정 및 외부 접속 지원

Strimzi는 카프카 리스너를 유연하게 설정하여 클러스터 내부 및 외부에서 안전하게 접속할 수 있도록 지원합니다. 이는 클라우드 환경에서 매우 중요한 기능입니다.

  • 동작 방식: Kafka CRD 파일의 listeners 섹션에 plain, tls, external 등의 리스너를 정의할 수 있습니다. external 리스너는 NodePort, LoadBalancer, Route 등 다양한 타입을 지원합니다.
  • Strimzi의 역할: Operator는 사용자가 정의한 리스너 설정에 따라 쿠버네티스 Service, Ingress, Route 등의 리소스를 자동으로 생성합니다. 예를 들어, type: loadbalancer로 설정하면 클라우드 로드 밸런서를 자동으로 프로비저닝하여 외부에서 카프카에 접속할 수 있게 해줍니다.
  • 장점:
    • 단순한 설정: 복잡한 네트워크 설정을 YAML 파일 몇 줄로 쉽게 구성할 수 있습니다.
    • 다양한 환경 지원: 클라우드(GKE, AWS, Azure 등) 환경에서 외부 접속을 위한 다양한 방법을 손쉽게 제공합니다.

 

3-3. 자동화된 Kafka 및 KRaft 모드 관리

Strimzi는 Kafka의 새로운 아키텍처인 KRaft(Kafka Raft) 모드를 완벽하게 지원하며, 이와 관련된 모든 복잡성을 숨겨줍니다.

  • KRaft란?: 기존의 ZooKeeper 대신 Kafka의 자체 Raft 프로토콜을 사용해 메타데이터를 관리하는 모드입니다. ZooKeeper의 운영 부담을 없애고 클러스터의 안정성과 확장성을 높입니다.
  • Strimzi의 역할:
    • 간편한 KRaft 전환: Kafka CRD 파일에서 kafkaNodePools를 사용해 컨트롤러와 브로커 역할을 분리하는 것만으로 KRaft 모드를 쉽게 설정할 수 있습니다.
    • KRaft 클러스터 관리: Operator는 컨트롤러와 브로커 노드 풀의 상태를 지속적으로 모니터링하고, 필요에 따라 스케일링, 업그레이드, 장애 복구를 자동으로 처리합니다.
  • 장점:
    • 운영 부담 감소: ZooKeeper를 별도로 관리할 필요가 없어 운영 복잡성이 크게 줄어듭니다.
    • 최신 기술 활용: 카프카의 최신 기능과 아키텍처를 복잡한 설정 없이 바로 적용할 수 있습니다.

 

4. Kafka with Strimzi 구성 방법

Strimzi를 이용해 Kafka 클러스터를 구성하는 과정은 크게 3단계로 나눌 수 있습니다.

 

1단계: Strimzi Operator 설치

Helm을 사용하여 Strimzi Operator를 쿠버네티스 클러스터에 설치합니다. 이 Operator가 Kafka 클러스터 관리를 담당하게 됩니다.

helm repo add strimzi https://strimzi.io/charts/

helm repo update

helm install strimzi-operator strimzi/strimzi-kafka-operator --version 0.47.0 --namespace kafka --create-namespace

 

2단계: Kafka CRD 파일 작성

Kafka 클러스터의 원하는 상태를 YAML 파일로 정의합니다. 이 파일은 클러스터의 버전, 노드 수, 저장 공간, 리스너 설정 등을 명시합니다. 아래 예시는 KRaft 모드와 컨트롤러/브로커 분리를 포함합니다.

# kraft-cluster.yaml
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
  name: controller
  labels:
    strimzi.io/cluster: my-cluster
spec:
  replicas: 3
  roles:
    - controller
  storage:
    type: jbod
    volumes:
      - id: 0
        type: ephemeral
        kraftMetadata: shared
---

apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
  name: broker
  labels:
    strimzi.io/cluster: my-cluster
spec:
  replicas: 3
  roles:
    - broker
  storage:
    type: jbod
    volumes:
      - id: 0
        type: ephemeral
        kraftMetadata: shared
---

apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
  name: my-cluster
  annotations:
    strimzi.io/node-pools: enabled
    strimzi.io/kraft: enabled
spec:
  kafka:
    version: 3.9.0
    metadataVersion: 3.9-IV0
    listeners:
      - name: plain
        port: 9092
        type: internal
        tls: false
      - name: tls
        port: 9093
        type: internal
        tls: true
    config:
      offsets.topic.replication.factor: 3
      transaction.state.log.replication.factor: 3
      transaction.state.log.min.isr: 2
      default.replication.factor: 3
      min.insync.replicas: 2
  entityOperator:
    topicOperator: {}
    userOperator: {}

 

3단계: 클러스터 배포 및 확인

작성한 YAML 파일을 kubectl apply 명령어로 적용하면, Strimzi Operator가 이 파일을 읽어 클러스터 배포를 자동으로 진행합니다.

kubectl apply -f kraft-cluster.yaml -n kafka

 

배포가 완료되면 kubectl get pods 명령어로 Pod상태를 확인합니다.

kubectl get pods -n kafka
kubectl get pods -n kafka -l strimzi.io/cluster=my-cluster