๐ง ๋ค์ด๊ฐ๊ธฐ์
Strimzi - Apache Kafka on Kubernetes
Kafka on Kubernetes in a few minutes Strimzi provides a way to run an Apache Kafka cluster on Kubernetes in various deployment configurations. Use the Quick Starts to get started now! Secure by Default Built-in security TLS, SCRAM-SHA, and OAuth authentica
strimzi.io
GitHub - strimzi/strimzi-kafka-operator: Apache Kafka® running on Kubernetes
Apache Kafka® running on Kubernetes. Contribute to strimzi/strimzi-kafka-operator development by creating an account on GitHub.
github.com
์ต๊ทผ Kafka๋ฅผ Strimzi๋ก ๊ตฌ์ถํ๋ฉด์ ๊ธฐ์กด์ Helm Chart๊ฐ ์๋ Operator๋ก ์ ์ ํ๊ฒ ๋์๋ค. ์ฒ์์๋ "๋ ๋ค YAML ์์ฑํด์ apply ํ๋ ๊ฑด ๋๊ฐ์๋ฐ ๋ญ๊ฐ ๋ค๋ฅด์ง?"๋ผ๋ ์๋ฌธ์ด ์์๋ค. ์ง์ ์ด์ํด๋ณด๋ ๊ทธ ์ฐจ์ด๊ฐ ๋ช ํํด์ก๋ค.
๐ธ 1. Operator Pattern์ด๋
1.1 ํต์ฌ ๊ฐ๋
Operator pattern
Operators are software extensions to Kubernetes that make use of custom resources to manage applications and their components. Operators follow Kubernetes principles, notably the control loop. Motivation The operator pattern aims to capture the key aim of
kubernetes.io
Kubernetes ๊ณต์ ๋ฌธ์์ ๋ฐ๋ฅด๋ฉด, Operator๋ Custom Resource๋ฅผ ์ฌ์ฉํ์ฌ ์ ํ๋ฆฌ์ผ์ด์ ๊ณผ ๊ทธ ์ปดํฌ๋ํธ๋ฅผ ๊ด๋ฆฌํ๋ ์ํํธ์จ์ด ํ์ฅ์ด๋ค. Operator๋ Kubernetes์ ํต์ฌ ์์น, ํนํ Control Loop๋ฅผ ๋ฐ๋ฅธ๋ค.
Operator Pattern์ ์ดํดํ๋ ค๋ฉด ๋ค ๊ฐ์ง ํต์ฌ ๊ฐ๋ ์ ์์์ผ ํ๋ค.
1.1.1 CRD (Custom Resource Definition)
CRD๋ Kubernetes API๋ฅผ ํ์ฅํ๋ ๋ฐฉ๋ฒ์ด๋ค. ๊ธฐ๋ณธ ๋ฆฌ์์ค์ธ Pod, Service, Deployment ์ธ์ ์๋ก์ด ๋ฆฌ์์ค ํ์ ์ ์ ์ํ ์ ์๋ค.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: kafkas.kafka.strimzi.io
spec:
group: kafka.strimzi.io
names:
kind: Kafka
plural: kafkas
scope: Namespaced
versions:
- name: v1beta2
served: true
storage: true
์ด CRD๋ฅผ ํด๋ฌ์คํฐ์ ๋ฑ๋กํ๋ฉด, ์ด์ Kafka๋ผ๋ ์๋ก์ด Kind๋ฅผ ์ฌ์ฉํ ์ ์๊ฒ ๋๋ค.
1.1.2 CR (Custom Resource)
CR์ CRD๋ก ์ ์๋ ํ์ ์ ์ธ์คํด์ค๋ค. ์ค์ ๋ก ์ฌ์ฉ์๊ฐ ์ ์ธํ๋ ๋ฆฌ์์ค๊ฐ ๋๋ค.
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
spec:
kafka:
version: 3.7.0
replicas: 3
listeners:
- name: plain
port: 9092
type: internal
storage:
type: persistent-claim
size: 100Gi
zookeeper:
replicas: 3
storage:
type: persistent-claim
size: 100Gi
1.1.3 Custom Controller
Controller๋ ํด๋ฌ์คํฐ์ ์ํ๋ฅผ ์ง์์ ์ผ๋ก ๊ฐ์ํ๋ฉด์ ํ์ฌ ์ํ(Current State)๋ฅผ ์ํ๋ ์ํ(Desired State)๋ก ๋ง์ถ๋ ์ญํ ์ ํ๋ค. Kubernetes์ ๊ธฐ๋ณธ Controller(์: Deployment Controller)์ ๋์ผํ ๋ฐฉ์์ผ๋ก ๋์ํ๋ค.

Controller๋ Watch ๋ฉ์ปค๋์ฆ์ ํตํด CR์ ๋ณ๊ฒฝ์ ๊ฐ์งํ๊ณ , Reconcile ํจ์๋ฅผ ์คํํ์ฌ ์ํ๋ฅผ ๋๊ธฐํํ๋ค. ์ด ๋ฃจํ๊ฐ ๋์์์ด ๋์๊ฐ๋ฉด์ ์์คํ ์ ์ผ๊ด์ฑ์ ์ ์งํ๋ค.
1.1.4 Operator
Operator๋ CRD์ Controller๋ฅผ ๋ฌถ์ด์ ํน์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ด์ ์ง์(Operational Knowledge)์ ์ฝ๋๋ก ๊ตฌํํ ๊ฒ์ด๋ค. ๋จ์ํ ๋ฆฌ์์ค๋ฅผ ์์ฑํ๋ ๊ฒ์ ๋์ด, ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์ ๋๋ฉ์ธ ์ง์์ ํฌํจํ๋ค.
Strimzi์ ๊ฒฝ์ฐ, Operator๊ฐ Java๋ก ์์ฑ๋์ด ์๋ค. CR์ ์ ์๋ ์คํ์ ์ฝ๊ณ , ๊ทธ์ ๋ง๊ฒ StatefulSet, Service, ConfigMap ๋ฑ์ ์์ฑํ๊ณ ๊ด๋ฆฌํ๋ค. ์ง์ Operator๋ฅผ ๋ง๋ค ์ผ์ ๊ฑฐ์ ์๊ฒ ์ง๋ง, ๋์ ์๋ฆฌ๋ฅผ ์ดํดํ๋ฉด ํธ๋ฌ๋ธ์ํ ์ ๋์์ด ๋๋ค.
๐ธ 2. Helm Chart vs Operator
2.1 ๊ทผ๋ณธ์ ์ธ ์ฐจ์ด
๋ ๋ค Kubernetes์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐฐํฌํ๋ ๋๊ตฌ์ง๋ง, ๋์ ๋ฐฉ์์ด ๊ทผ๋ณธ์ ์ผ๋ก ๋ค๋ฅด๋ค.

Helm์ ํด๋ผ์ด์ธํธ ์ฌ์ด๋ ๋๊ตฌ๋ค. ์ฐจํธ๋ฅผ ๋ ๋๋งํด์ YAML์ ์์ฑํ๊ณ , kubectl apply์ ๋์ผํ๊ฒ API ์๋ฒ์ ์ ๋ฌํ๋ค. ์ค์น๊ฐ ๋๋๋ฉด Helm์ ์ญํ ๋ ๋๋๋ค. ์ดํ ๋ฆฌ์์ค์ ๋ฌธ์ ๊ฐ ์๊ฒจ๋ Helm์ ๊ด์ฌํ์ง ์๋๋ค.
Operator๋ ํด๋ฌ์คํฐ ๋ด๋ถ์์ ์คํ๋๋ Controller๋ค. CR์ด ์์ฑ๋๋ฉด ๊ทธ ์์ ๋ถํฐ ์ง์์ ์ผ๋ก ๋ฆฌ์์ค๋ฅผ ๊ฐ์ํ๊ณ ๊ด๋ฆฌํ๋ค. Pod๊ฐ ์ฃฝ์ผ๋ฉด ๋ค์ ์ด๋ฆฌ๊ณ , ์ค์ ์ด ๋ณ๊ฒฝ๋๋ฉด Rolling Update๋ฅผ ์ํํ๋ค.
2.2 ์ค์ ๋ณ๊ฒฝ ์ ๋์ ๋น๊ต
Helm ๋ฐฉ์์์ Kafka ๋ธ๋ก์ปค ์๋ฅผ 3๊ฐ์์ 5๊ฐ๋ก ๋๋ฆฌ๋ ค๋ฉด ๋ค์ ๊ณผ์ ์ ๊ฑฐ์น๋ค.
# values.yaml ์์
# replicas: 3 -> replicas: 5
helm upgrade kafka bitnami/kafka -f values.yaml
Operator ๋ฐฉ์์์๋ CR๋ง ์์ ํ๋ฉด ๋๋ค.
kubectl edit kafka my-cluster
# spec.kafka.replicas: 3 -> 5 ๋ก ์์ ํ ์ ์ฅ
ํ๋ฉด์ ์ผ๋ก๋ ๋น์ทํด ๋ณด์ด์ง๋ง, ๋ด๋ถ ๋์์ด ๋ค๋ฅด๋ค. Helm์ ๋จ์ํ ์๋ก์ด YAML์ applyํ๋ ๊ฒ์ด๊ณ , Operator๋ ๋ณ๊ฒฝ ์ฌํญ์ ๊ฐ์งํ์ฌ ์์ ํ ๋ฐฉ์์ผ๋ก ์ค์ผ์ผ๋ง์ ์ํํ๋ค.
Strimzi Overview (0.49.1)
Kafka MirrorMaker 2 replicates data (topics, consumer groups, and offsets) between Kafka clusters. Through configuration, you define source and target cluster connections. You can use MirrorMaker 2 in active/passive or active/active cluster configurations.
strimzi.io
Strimzi Operator์ ๊ฒฝ์ฐ, Kafka ๋ธ๋ก์ปค๋ฅผ ์ถ๊ฐํ ๋ Cruise Control์ ํตํด ํํฐ์ ์ฌ๋ฐฐ์น๊น์ง ์๋์ผ๋ก ์ํํ๋ค. Helm์ผ๋ก๋ ์ด๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์ ์์ ์ ์๋ํํ ์ ์๋ค.
2.3 StatefulSet์ ํ๊ณ
์ฌ๊ธฐ์ ํ ๊ฐ์ง ์๋ฌธ์ด ์๊ธด๋ค. StatefulSet๋ Pod ์์ ๋ณด์ฅํ๊ณ , PVC ์ ์งํ๊ณ , Rolling Update ํด์ฃผ๋๋ฐ ์ Operator๊ฐ ํ์ํ ๊น?
StatefulSet์ด ํด์ฃผ๋ ๊ฒ์ Kubernetes ๋ ๋ฒจ์ ์์ ์ด๋ค.
- Pod ์์๋๋ก ์์ฑ (kafka-0 → kafka-1 → kafka-2)
- ์์ ์ ์ธ ๋คํธ์ํฌ ID (kafka-0.kafka-headless.svc)
- PVC ์ ์ง (Pod ์ฌ์์ํด๋ ๋ฐ์ดํฐ ๋ณด์กด)
- ๋กค๋ง ์ ๋ฐ์ดํธ (Pod ํ๋์ฉ ์ฌ์์)
- Pod ์ฃฝ์ผ๋ฉด ์ฌ์์ฑ
StatefulSet์ด ํด์ฃผ์ง ์๋ ๊ฒ์ ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์ ์์ ์ด๋ค.
- Kafka ํํฐ์ ๋ฆฌ๋๊ฐ ๋๊ตฐ์ง ๋ชจ๋ฆ
- ๋ธ๋ก์ปค๊ฐ ์ ์์ ์ผ๋ก ํด๋ฌ์คํฐ์ ์กฐ์ธํ๋์ง ๋ชจ๋ฆ
- ์ ๊ทธ๋ ์ด๋ ์ "์ด ๋ธ๋ก์ปค ์ฌ์์ํด๋ ๋๋์ง" ํ๋จ ๋ชปํจ
- ์ค์ผ์ผ๋ง ์ ํํฐ์ ์ฌ๋ฐฐ์น ์ ํจ
- ํ ํฝ/์ฌ์ฉ์ ์์ฑ ๋ชปํจ
StatefulSet์ "Pod๊ฐ Ready ์ํ์ธ๊ฐ?"๋ง ํ์ธํ์ง, "Kafka ๋ธ๋ก์ปค๊ฐ ISR(In-Sync Replica)์ ์ ์์ ์ผ๋ก ํฉ๋ฅํ๋๊ฐ?"๋ ํ์ธํ์ง ์๋๋ค. Operator๋ ์ด๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ค์ health check๋ฅผ ์ํํ๋ค.
๐ธ 3. Operator๋ ์ธ์ ์ฐ๋๊ฐ
3.1 ๋ณต์กํ ๋ถ์ฐ ์์คํ
Operator๊ฐ ๋น์ ๋ฐํ๋ ์์ญ์ ๋ณต์กํ ๋ถ์ฐ ์์คํ ์ด๋ค. Kafka, Elasticsearch, PostgreSQL ๊ฐ์ ์คํ ์ดํธํ ์ ํ๋ฆฌ์ผ์ด์ ์ด ๋ํ์ ์ด๋ค.
Helm์ผ๋ก Kafka ํ ํฝ์ ์์ฑํ๋ ค๋ฉด ํด๋ฌ์คํฐ์ ์ง์ ์ ์ํด์ผ ํ๋ค.
# Kafka ํด๋ฌ์คํฐ์ ์ง์ ์ ์
kubectl exec -it kafka-0 -- bash
# ํ ํฝ ์์ฑ
kafka-topics.sh --create --topic new-topic \
--bootstrap-server kafka:9092 \
--partitions 3 --replication-factor 2
# ์ค์ ๋ณ๊ฒฝ
kafka-configs.sh --alter --topic new-topic \
--add-config retention.ms=604800000 \
--bootstrap-server kafka:9092
์ด ์ค์ ์ Helm์ด ๊ด๋ฆฌํ์ง ์๋๋ค. Git์ ์ ์ฅํ ์๋ ์๊ณ , GitOps๋ ๋ถ๊ฐ๋ฅํ๋ค.
Operator ๋ฐฉ์์์๋ YAML๋ก ์ ์ธํ๋ค.
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
name: new-topic
labels:
strimzi.io/cluster: my-cluster
spec:
partitions: 3
replicas: 2
config:
retention.ms: "604800000"
kubectl apply -f topic.yaml
์ด์ ํ ํฝ ์ค์ ๋ Git์ ์ ์ฅ๋๊ณ , PR ๋ฆฌ๋ทฐ๋ฅผ ๊ฑฐ์น๊ณ , ArgoCD๋ก ์๋ ๋ฐฐํฌํ ์ ์๋ค. Infrastructure as Code์ ๋ฒ์๊ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ค์ ๊น์ง ํ์ฅ๋๋ค.
3.2 Day 2 Operations ์๋ํ
- Day 1 Operations๋ ์ค์น๋ค.
- Day 2 Operations๋ ์ด์์ด๋ค.
๋ฐฑ์ , ๋ณต๊ตฌ, ์ ๊ทธ๋ ์ด๋, ์ค์ผ์ผ๋ง, ์ฅ์ ๋์ ๊ฐ์ ์์ ์ด Day 2์ ํด๋นํ๋ค.
Helm์ Day 1์ ๊ฐํ๋ค. ์ค์น๋ ์ฝ๋ค. ํ์ง๋ง Day 2๋ถํฐ๋ ์๋ ์์ ์ด ๋ง์์ง๋ค.
Operator๋ Day 2๋ฅผ ์๋ํํ๋ค. Strimzi Operator๊ฐ ์ ๊ณตํ๋ Day 2 ๊ธฐ๋ฅ์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- Rolling Upgrade: Kafka ๋ฒ์ ์ ๊ทธ๋ ์ด๋ ์ ๋ธ๋ก์ปค๋ฅผ ํ๋์ฉ ์์ ํ๊ฒ ์ฌ์์
- Cruise Control ์ฐ๋: ํํฐ์ ์๋ ์ฌ๋ฐฐ์น๋ก ํด๋ฌ์คํฐ ๋ฐธ๋ฐ์ฑ
- User/ACL ๊ด๋ฆฌ: KafkaUser CR๋ก ์ฌ์ฉ์์ ๊ถํ์ ์ ์ธ์ ์ผ๋ก ๊ด๋ฆฌ
- TLS ์ธ์ฆ์ ์๋ ๊ฐฑ์ : ๋ง๋ฃ ์ ์ ์๋์ผ๋ก ์ธ์ฆ์ ๋กํ ์ด์
3.3 Operator๊ฐ ํ์ ์๋ ๊ฒฝ์ฐ
๋ชจ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ Operator๊ฐ ํ์ํ ๊ฒ์ ์๋๋ค. Stateless ์ ํ๋ฆฌ์ผ์ด์ , ๋จ์ํ ๋ง์ดํฌ๋ก์๋น์ค, ์งง์ ์๋ช ์ ๋ฐฐ์น ์ก ๊ฐ์ ๊ฒฝ์ฐ์๋ Helm์ด๋ Kustomize๋ก ์ถฉ๋ถํ๋ค.
Operator๋ฅผ ๋์ ํ๋ฉด ๋ณต์ก๋๊ฐ ์ฌ๋ผ๊ฐ๋ค. Operator ์์ฒด๋ Pod๋ก ์คํ๋๋ฏ๋ก ์ถ๊ฐ ๋ฆฌ์์ค๋ฅผ ์๋นํ๊ณ , ์ฅ์ ํฌ์ธํธ๊ฐ ํ๋ ๋ ์๊ธด๋ค. ๋จ์ํ ์ ํ๋ฆฌ์ผ์ด์ ์ Operator๋ฅผ ์ฐ๋ ๊ฒ์ ์ค๋ฒ์์ง๋์ด๋ง์ด๋ค.
๐ธ 4. OperatorHub
OperatorHub.io | The registry for Kubernetes Operators
operatorhub.io
์ปค๋ฎค๋ํฐ์์ ๋ง๋ Operator๋ฅผ ์ฐพ์๋ณผ ์ ์๋ ๊ณณ์ด OperatorHub์ด๋ค. CNCF ํ๋ก์ ํธ๋ค์ ๊ณต์ Operator๋ถํฐ ๋ฒค๋๊ฐ ์ ๊ณตํ๋ ์์ฉ Operator๊น์ง ๋ค์ํ๊ฒ ๋ฑ๋ก๋์ด ์๋ค.
์ฃผ์ Operator ๋ชฉ๋ก์ ๋ณด๋ฉด ๋ค์๊ณผ ๊ฐ๋ค.
- Strimzi Kafka Operator: Kafka ํด๋ฌ์คํฐ ๊ด๋ฆฌ
- Prometheus Operator: ๋ชจ๋ํฐ๋ง ์คํ ๊ด๋ฆฌ
- Cert-Manager: TLS ์ธ์ฆ์ ์๋ ๋ฐ๊ธ ๋ฐ ๊ฐฑ์
- Postgres Operator (Zalando): PostgreSQL ํด๋ฌ์คํฐ ๊ด๋ฆฌ
- Elasticsearch Operator (ECK): Elastic Stack ๊ด๋ฆฌ
์ง์ Operator๋ฅผ ๋ง๋ค ์ผ์ ๋๋ฌผ์ง๋ง, ํ์ํ๋ค๋ฉด Operator SDK๋ Kubebuilder๋ฅผ ์ฌ์ฉํ ์ ์๋ค.
๐ช ์ ๋ฆฌ
Helm์ ํจํค์ง ๋งค๋์ ๋ค. ํ ํ๋ฆฟ์ ๋ ๋๋งํด์ YAML์ ๋ง๋ค๊ณ , ์ค์น ํ์๋ ์์ ๋๋ค. ๋จ์ํ Stateless ์ ํ๋ฆฌ์ผ์ด์ ๋ฐฐํฌ์ ์ ํฉํ๋ค.
Operator๋ ์๋ํ๋ ์ด์์๋ค. CR์ ๊ฐ์ํ๋ฉด์ ์ง์์ ์ผ๋ก ์ํ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ๋ ๋ฒจ์ ์ด์ ์์ ์ ์๋ํํ๋ค. Kafka, PostgreSQL ๊ฐ์ ๋ณต์กํ ๋ถ์ฐ ์์คํ ์์ ์ง๊ฐ๋ฅผ ๋ฐํํ๋ค.
๋์ ์ํธ ๋ฐฐํ์ ์ด์ง ์๋ค. ๋ง์ ํ์ด Stateless ์ฑ์ Helm์ผ๋ก, Stateful ์ธํ๋ผ๋ Operator๋ก ๊ด๋ฆฌํ๋ ํ์ด๋ธ๋ฆฌ๋ ์ ๋ต์ ์ฌ์ฉํ๋ค. Operator ์์ฒด๋ Helm Chart๋ก ์ค์นํ๋ ๊ฒฝ์ฐ๊ฐ ๋ง๋ค.
๊ฒฐ๊ตญ "์ธ์ ๊น์ง Helm๋ง ์ธ๋?"์ ๋ํ ๋ต์ "Stateful ์ฑ์ Day 2 Operations๋ฅผ ์๋ํํ๊ณ ์ถ์ ๋"๊ฐ ๋๋ค.
๐ ์ถ์ฒ
- Kubernetes ๊ณต์ ๋ฌธ์ - Operator Pattern: https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
- Strimzi ๊ณต์ ๋ฌธ์: https://strimzi.io/docs/operators/latest/overview
- OperatorHub: https://operatorhub.io
- Kubebuilder: https://book.kubebuilder.io
- ์กฐ๋ํ ๋ธ๋ก๊ทธ - Kubernetes Operator: https://bcho.tistory.com/1391