Kubernetes 환경에서 StarRocks와 Kafka를 가장 안정적이고 Production-Ready하게 설치·운영하는 표준 방법은 Operator(Helm Chart)를 활용하는 것입니다.
두 솔루션 모두 K8s Custom Resource(CRD) 기반의 전용 Operator가 잘 구축되어 있어, 배포 및 수명 주기(Scale-out, Config 변경, Failover) 관리가 매우 용이합니다.
Kubernetes 환경에서 Kafka를 배포할 때 업계 표준으로 가장 많이 쓰이는 것은 Strimzi Kafka Operator입니다. Strimzi를 사용하면 Kafka Custom Resource 개체 하나로 클러스터를 선언적으로 관리할 수 있습니다.
# 1. kafka 네임스페이스 생성
kubectl create namespace kafka
# 2. Helm 저장소 추가 및 업데이트
helm repo add strimzi https://strimzi.io/charts/
helm repo update
# 3. Strimzi Operator 배포
helm install strimzi-operator strimzi/strimzi-kafka-operator \
--namespace kafka \
--set watchAnyNamespace=true
kafka-cluster.yaml)참고: 최근 Kafka는 Zookeeper 없이 KRaft 모드를 지원합니다. 아래는 KRaft 기반 3-Node Kafka 클러스터 예시입니다.
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: dual-role
namespace: kafka
labels:
strimzi.io/cluster: my-kafka
spec:
replicas: 3
roles:
- controller
- broker
storage:
type: persistent-claim
size: 200Gi
class: standard # 사용 중인 StorageClass 지정 (예: local-path, rook-ceph, minio-csi 등)
---
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-kafka
namespace: kafka
annotations:
strimzi.io/node-pools: enabled
strimzi.io/kraft: enabled
spec:
kafka:
version: 3.8.0
metadataVersion: 3.8-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: {}
# Kafka 클러스터 생성
kubectl apply -f kafka-cluster.yaml
kafka-topic.yaml)앞서 산정한 파티션 32개, Retention 24시간 설정을 포함한 Topic CRD입니다.
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
name: minio-aistor-object-events
namespace: kafka
labels:
strimzi.io/cluster: my-kafka
spec:
partitions: 32
replicas: 3
config:
retention.ms: "86400000" # 24시간
retention.bytes: "21474836480" # 파티션당 20GB
min.insync.replicas: "2"
compression.type: "zstd"
kubectl apply -f kafka-topic.yaml
my-kafka-kafka-bootstrap.kafka.svc.cluster.local:9092StarRocks 공식 Helm 차트는 Operator 방식과 Classic 방식을 모두 지원하지만, StarRocks Kubernetes Operator를 통한 배포가 FE(Frontend) 및 BE(Backend)의 자동 Discovery 및 스케일링을 안전하게 처리해 줍니다.
# 1. starrocks 네임스페이스 생성
kubectl create namespace starrocks
# 2. Helm 저장소 추가
helm repo add starrocks-community https://starrocks.github.io/starrocks-kubernetes-operator
helm repo update
# 3. Operator 설치
helm install starrocks-operator starrocks-community/kube-starrocks \
--namespace starrocks \
--set operator.enabled=true \
--set starrocksCluster.enabled=false # 커스텀 배포를 위해 Cluster 자동생성은 false
starrocks-cluster.yaml)FE 3대(메타데이터/쿼리 플래너)와 BE 3대(컴퓨팅/스토리지) 구성 예시입니다.
apiVersion: starrocks.com/v11
kind: StarRocksCluster
metadata:
name: starrocks-cluster
namespace: starrocks
spec:
starRocksFeSpec:
replicas: 3
image:
repository: starrocks/fe-ubuntu
tag: v3.3.2
limits:
cpu: "8"
memory: "16Gi"
requests:
cpu: "4"
memory: "8Gi"
storageVolumes:
- name: fe-meta
storageClassName: standard # StorageClass 지정
storageSize: 100Gi
mountPath: /opt/starrocks/fe/meta
starRocksBeSpec:
replicas: 3
image:
repository: starrocks/be-ubuntu
tag: v3.3.2
limits:
cpu: "16"
memory: "64Gi"
requests:
cpu: "8"
memory: "32Gi"
storageVolumes:
- name: be-storage
storageClassName: standard # NVMe/빠른 SSD 권장
storageSize: 500Gi
mountPath: /opt/starrocks/be/storage
# StarRocks 클러스터 배포
kubectl apply -f starrocks-cluster.yaml
# Pod 생성 확인 (FE, BE가 각각 Running 및 Ready가 될 때까지 확인)
kubectl get pods -n starrocks -w
StarRocks FE 접속 정보:
starrocks-cluster-fe-search.starrocks.svc.cluster.local:9030starrocks-cluster-fe-search.starrocks.svc.cluster.local:8030설치가 완료되면 StarRocks MySQL CLI에 접속하여 Kafka Topic을 인제스천하는 Routine Load를 생성합니다.
-- 1. StarRocks CLI 접속 (기본 계정: root, 패스워드 없음)
-- mysql -h starrocks-cluster-fe-search.starrocks.svc.cluster.local -P 9030 -u root
CREATE DATABASE IF NOT EXISTS minio_audit;
USE minio_audit;
-- 2. Target 테이블 생성 (JSON 이벤트 데이터 연동용)
CREATE TABLE IF NOT EXISTS object_events (
`event_time` DATETIME,
`bucket_name` VARCHAR(100),
`object_key` VARCHAR(1024),
`1st_depth_prefix` VARCHAR(255) AS AS_1st_depth(object_key), -- 필요시 생성 컬럼 활용
`object_size` BIGINT,
`action` VARCHAR(50)
) ENGINE=OLAP
DUPLICATE KEY(`event_time`, `bucket_name`)
DISTRIBUTED BY HASH(`bucket_name`) BUCKETS 16
PROPERTIES (
"replication_num" = "3"
);
-- 3. Routine Load 파이프라인 생성 (Kafka -> StarRocks)
CREATE ROUTINE LOAD minio_audit.minio_event_load ON object_events
COLUMNS(event_time, bucket_name, object_key, object_size, action)
PROPERTIES
(
"format" = "json",
"desired_concurrent_number" = "16", -- StarRocks 인제스천 병렬 스레드 수
"max_batch_interval" = "5",
"max_batch_size" = "209715200"
)
FROM KAFKA
(
"kafka_broker_list" = "my-kafka-kafka-bootstrap.kafka.svc.cluster.local:9092",
"kafka_topic" = "minio-aistor-object-events",
"property.group.id" = "starrocks-minio-consumer-group",
"kafka_partitions" = "0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31",
"property.kafka.default.offsets" = "OFFSET_END"
);
limits.memory 초과로 인한 OOMKilled가 발생하지 않도록 메모리를 충분히 할당하고 JVM / Native Memory 튜닝을 진행해야 합니다.