Strimzi는 Kubernetes 환경에서 Apache Kafka를 쉽게 배포하고 관리할 수 있도록 도와주는 오픈소스입니다.
helm으로 이용하여 kafka 환경을 구성하는 방법은 아래와 같습니다.
Kafka 클러스터를 배포하기 전에, 먼저 Strimzi Kafka Operator를 설치해야 합니다. helm을 이용하여 처리하는 명령어는 아래와 같습니다.
kubectl create namespace kafka
helm repo add strimzi https://strimzi.io/charts/
helm repo update
helm install strimzi-kafka-operator strimzi/strimzi-kafka-operator -n kafka
kafka 네임스페이스를 생성하고, Strimzi의 Helm 차트를 추가한 후, Kafka Operator를 설치하였습니다.
Kafka 클러스터의 기본 설정을 정의하는 Kafka 리소스를 생성합니다.
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: kafka-cluster-1
namespace: kafka
annotations:
strimzi.io/kraft: enabled ## 어노테이션을 달아줘야 kraft 모드 사용 가능
strimzi.io/node-pools: enabled
spec:
kafka:
version: 3.9.0
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
여기서 listeners 설정을 통해 Kafka 브로커에 대한 내부 통신을 설정할 수 있습니다.
plain (9092, tls: false): 내부 통신 시 암호화 없이 사용tls (9093, tls: true): TLS(SSL) 기반의 보안 통신 활성화Strimzi는 Kafka 클러스터를 관리하기 위해 KafkaNodePool을 활용합니다. 여기서는 컨트롤러 노드와 브로커 노드를 개별적으로 설정하였습니다.
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: controller-pool
namespace: kafka
labels:
strimzi.io/cluster: kafka-cluster-1
spec:
replicas: 3
roles:
- controller
storage:
type: ephemeral
resources:
requests:
memory: 2Gi
cpu: "1"
limits:
memory: 4Gi
cpu: "2"
storage.type: ephemeral : 스토리지 값을 필수로 적어주셔야 합니다. 저는 권한 때문에 임시로 사용하는 방법을 택하였습니다. 실제 프로덕션 환경이라면 pvc로 해주시면 됩니다.
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: broker-pool
namespace: kafka
labels:
strimzi.io/cluster: kafka-cluster-1
spec:
replicas: 5
roles:
- broker
storage:
type: ephemeral
resources:
requests:
memory: 2Gi
cpu: "1"
limits:
memory: 4Gi
cpu: "2"
이 설정들을 통해 컨트롤러 노드를 3개, 브로커 노드를 5개로 설정하였습니다.
Kafka 클러스터 상태를 GUI로 쉽게 확인할 수 있도록 Kafka UI를 배포하였습니다.
apiVersion: apps/v1
kind: Deployment
metadata:
name: kafka-ui
spec:
replicas: 1
selector:
matchLabels:
app: kafka-ui
template:
metadata:
labels:
app: kafka-ui
spec:
containers:
- name: kafka-ui
image: provectuslabs/kafka-ui:latest
ports:
- containerPort: 8080
env:
- name: KAFKA_CLUSTERS_0_NAME
value: "kafka-cluster-1"
- name: KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS
value: "kafka-cluster-1-kafka-bootstrap.kafka.svc.cluster.local:9092" # FQDN 사용
Kafka UI에 접근할 수 있도록 Service를 생성하였습니다.
apiVersion: v1
kind: Service
metadata:
name: kafka-ui
spec:
selector:
app: kafka-ui
ports:
- name: http
port: 80
targetPort: 8080
type: NodePort
현재 저는 로컬에서 minikube를 사용하고 있으며 도커 드라이브를 이용하고 있기에 porf-forward 또는 minikube service로 열어주어야 접근이 가능하기에 저는 후자를 이용하여 열어서 사용하였습니다.
❯ kubectl get kafka
NAME DESIRED KAFKA REPLICAS DESIRED ZK REPLICAS READY METADATA STATE WARNINGS
kafka-cluster-1 True KRaft True
DESIRED ZK REPLICAS: KRaft 모드이므로 Zookeeper 관련 정보는 없음.READY: True 값이므로 Kafka 클러스터가 정상적으로 실행 중.METADATA STATE: KRaft 값이므로 KRaft 모드로 동작 중.❯ kubectl get kafkanodepools.kafka.strimzi.io
NAME DESIRED REPLICAS ROLES NODEIDS
broker-pool 5 ["broker"] [0,1,2,3,4]
controller-pool 3 ["controller"] [5,6,7]
broker-pool: 5개의 Kafka 브로커가 존재하며, Node ID는 [0,1,2,3,4].controller-pool: 3개의 Kafka 컨트롤러가 있으며, Node ID는 [5,6,7].[kafka@kafka-cluster-1-broker-pool-0 bin]$ ./kafka-broker-api-versions.sh --bootstrap-server kafka-cluster-1-kafka-bootstrap:9092 | grep broker
kafka-cluster-1-broker-pool-1.kafka-cluster-1-kafka-brokers.kafka.svc:9092 (id: 1 rack: null) -> (
kafka-cluster-1-broker-pool-0.kafka-cluster-1-kafka-brokers.kafka.svc:9092 (id: 0 rack: null) -> (
kafka-cluster-1-broker-pool-3.kafka-cluster-1-kafka-brokers.kafka.svc:9092 (id: 3 rack: null) -> (
kafka-cluster-1-broker-pool-4.kafka-cluster-1-kafka-brokers.kafka.svc:9092 (id: 4 rack: null) -> (
kafka-cluster-1-broker-pool-2.kafka-cluster-1-kafka-brokers.kafka.svc:9092 (id: 2 rack: null) -> (
[kafka@kafka-cluster-1-controller-pool-5 bin]$ ./kafka-metadata-quorum.sh --bootstrap-server kafka-cluster-1-kafka-bootstrap:9092 describe --status
ClusterId: ********
LeaderId: 5
LeaderEpoch: 1
HighWatermark: 7087
MaxFollowerLag: 0
MaxFollowerLagTimeMs: 0
CurrentVoters: [{"id": 5, "directoryId": null, "endpoints": ["CONTROLPLANE-9090://kafka-cluster-1-controller-pool-5.kafka-cluster-1-kafka-brokers.kafka.svc.cluster.local:9090"]},
{"id": 6, "directoryId": null, "endpoints": ["CONTROLPLANE-9090://kafka-cluster-1-controller-pool-6.kafka-cluster-1-kafka-brokers.kafka.svc.cluster.local:9090"]},
{"id": 7, "directoryId": null, "endpoints": ["CONTROLPLANE-9090://kafka-cluster-1-controller-pool-7.kafka-cluster-1-kafka-brokers.kafka.svc.cluster.local:9090"]}]
CurrentObservers: [{"id": 3, ...
{"id": 1, ...
{"id": 4, ...
{"id": 0, ...
{"id": 2, ...
ClusterId: Kafka 클러스터의 고유 IDLeaderId: 현재 Kafka 컨트롤러 리더는 ID 5 (controller-pool-5).CurrentVoters: 컨트롤러 선출 과정에서 투표권을 가진 노드 리스트 (ID 5, 6, 7).CurrentObservers: 브로커 역할을 하는 노드들 (ID 0, 1, 2, 3, 4).controller-pool-5 노드)이며, 나머지 6, 7번 컨트롤러가 대기 중ID 0~4)가 정상적으로 동작 중