パート 2: Strimzi Operator
サポート対象バージョン: Strimzi 0.45+, Kubernetes 1.28+
最終更新: July 9, 2026
Lab 環境のセットアップ
このドキュメントの例に沿って進めるには、以下のツールと環境が必要です。
必要なツール
- kubectl v1.28 以降
- Helm v3.12 以降
- 稼働中の Kubernetes cluster (Amazon EKS 推奨)
- Amazon EBS CSI driver がインストールされた cluster (ストレージ用)
Strimzi とは?
Strimzi は、Operator pattern を使用して Apache Kafka を Kubernetes 上で実行する CNCF Incubating project であり、Kafka cluster のライフサイクル全体を宣言的に管理します。Kafka broker を通常の StatefulSet として手作業で構築することもできますが、実運用では反復的でエラーが起きやすい作業が数多く発生します。
- broker と controller 全体にわたる rolling upgrade と設定変更の順序制御
- TLS 証明書の発行、更新、ローテーション
- partition rebalancing と scale in/out の際のデータの安全な移動
- user (ACL)、topic、connector などの補助リソースの宣言的管理
Strimzi は、これらすべてを CRD (Custom Resource Definitions) — Kafka、KafkaNodePool、KafkaTopic、KafkaUser、KafkaConnect — の背後に抽象化します。目的の状態を YAML で宣言すると、Operator が cluster の実際の状態を継続的に reconcile して一致させます。これは、手書きの StatefulSet と大量の shell script を組み合わせるよりも、はるかに信頼性と再現性の高いアプローチです。
主要コンポーネント
- Cluster Operator:
Kafka、KafkaNodePool、KafkaConnectなどの cluster level resource を監視し、基盤となる StatefulSet、Pod、Service、ConfigMap を作成および管理します - Topic Operator:
KafkaTopiccustom resource を実際の Kafka topic と同期します (単方向 — CR が信頼できる情報源であり、実際の topic に適用されます) - User Operator:
KafkaUsercustom resource に基づいて、SCRAM-SHA-512 または TLS authentication credential と ACL を管理します - Entity Operator: Topic Operator と User Operator を 1 つの Pod にまとめ、Kafka cluster ごとに 1 回 deploy します
インストール
オプション 1: Helm Chart (推奨)
# Add the Strimzi Helm repository
helm repo add strimzi https://strimzi.io/charts/
helm repo update
# Install the Cluster Operator into the kafka namespace
helm install strimzi-kafka-operator strimzi/strimzi-kafka-operator \
--namespace kafka \
--create-namespace \
--version 0.45.0
# Verify the installation
kubectl get pods -n kafka
kubectl get crd | grep strimziオプション 2: YAML / OperatorHub によるインストール
Helm を使わずにインストールすることも、OperatorHub 経由で OLM (Operator Lifecycle Manager) を通じてインストールすることもできます。
# Apply the install YAML targeting a specific namespace
kubectl create namespace kafka
curl -L https://github.com/strimzi/strimzi-kafka-operator/releases/download/0.45.0/strimzi-cluster-operator-0.45.0.yaml \
| sed 's/namespace: .*/namespace: kafka/' \
| kubectl apply -f - -n kafkaデフォルトでは、Cluster Operator は deploy された namespace のみを監視します。追加の namespace を監視するには、Operator Deployment の STRIMZI_NAMESPACE environment variable にカンマ区切りの namespace list を設定するか、cluster 全体を監視する場合は * を設定します。
kubectl set env deployment/strimzi-cluster-operator \
-n kafka STRIMZI_NAMESPACE=kafka,kafka-staging主要 CRD
Kafka と KafkaNodePool
Strimzi 0.45+ 以降では、KRaft mode (ZooKeeper なしの Kafka) がデフォルトであり、broker/controller role を別々の KafkaNodePool resource に分割することが標準的な deployment 形態になっています。従来の Kafka.spec.zookeeper block は KRaft では不要です。代わりに、各 node pool がそれぞれ role (controller、broker、または combined dual-role)、resource、storage を独立して宣言します。
# Controller-only node pool (3 nodes, forming a quorum)
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: persistent-claim
size: 20Gi
class: gp3-kafka
deleteClaim: false
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "2"
memory: 2Gi
---
# Broker-only node pool (3 nodes)
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: persistent-claim
size: 100Gi
class: gp3-kafka
deleteClaim: false
resources:
requests:
cpu: "2"
memory: 4Gi
limits:
cpu: "4"
memory: 4Gi
---
# The Kafka cluster itself (KRaft, no ZooKeeper)
apiVersion: kafka.strimzi.io/v1beta2
kind: Kafka
metadata:
name: my-cluster
namespace: kafka
annotations:
strimzi.io/kraft: enabled
strimzi.io/node-pools: 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 つの broker と 3 つの controller が quorum を形成します。これは、KRaft controller quorum が majority vote を必要とするためです。本番 deployment では、通常 controller の数を奇数 (3 または 5) にします。小規模 cluster では、専用の controller node を使わずに単一の dual-role pool (roles: [controller, broker]) を実行できますが、本番では resource contention を避け、障害を分離するために、controller と broker の role を別々の node pool に分けることが推奨されます。
KafkaTopic
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaTopic
metadata:
name: orders
namespace: kafka
labels:
strimzi.io/cluster: my-cluster
spec:
partitions: 12
replicas: 3
config:
retention.ms: 604800000
min.insync.replicas: 2KafkaUser
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaUser
metadata:
name: order-service
namespace: kafka
labels:
strimzi.io/cluster: my-cluster
spec:
authentication:
type: scram-sha-512
authorization:
type: simple
acls:
- resource:
type: topic
name: orders
operations: [Read, Write, Describe]KafkaConnect
topic や user とは異なり、KafkaConnect は source/sink connector (たとえば Debezium や S3 sink) を実行する別個の worker cluster を定義します。個々の connector は、KafkaConnector custom resource を通じて宣言的に管理されます。
EKS Deployment の考慮事項
1. EBS gp3-based StorageClass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: gp3-kafka
provisioner: ebs.csi.aws.com
parameters:
type: gp3
iops: "3000"
throughput: "250"
encrypted: "true"
volumeBindingMode: WaitForFirstConsumer
allowVolumeExpansion: true
reclaimPolicy: Retainbroker は継続的な sequential write が中心となるため、workload が gp3 の baseline throughput (125 MiB/s) を超える場合は、それに応じて throughput と iops を引き上げてください。KafkaNodePool.spec.storage は JBOD (Just a Bunch Of Disks) をサポートしており、broker ごとに複数の persistent-claim volume を attach して、I/O を複数の EBS volume に分散できます。
2. Pod Anti-Affinity / Topology Spread による AZ 分散
broker Pod が同じ AZ に配置されると、AZ outage によって quorum や partition availability が失われる可能性があります。KafkaNodePool.spec.template.pod の下に topologySpreadConstraints を追加し、broker を AZ 全体に均等に分散させます。
apiVersion: kafka.strimzi.io/v1beta2
kind: KafkaNodePool
metadata:
name: broker
labels:
strimzi.io/cluster: my-cluster
spec:
replicas: 3
roles: [broker]
template:
pod:
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
strimzi.io/cluster: my-cluster
strimzi.io/name: my-cluster-broker
storage:
type: jbod
volumes:
- id: 0
type: persistent-claim
size: 100Gi
class: gp3-kafka3. Listener と External Exposure
cluster 内に留まる traffic には internal listener (plain または TLS) を使用し、external client が access する必要がある場合にのみ、別の loadbalancer または nodeport type listener を追加します。
listeners:
- name: plain
port: 9092
type: internal
tls: false
- name: tls
port: 9093
type: internal
tls: true
- name: external
port: 9094
type: loadbalancer
tls: true
configuration:
bootstrap:
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
service.beta.kubernetes.io/aws-load-balancer-scheme: internaltype: loadbalancer では、Strimzi は bootstrap endpoint 用に NLB-backed Service を 1 つ、broker ごとに 1 つずつ provision します。access を VPC 内に留める必要がある場合は internal scheme を使用し、完全な public access が必要な場合にのみ internet-facing に切り替えます。cost と load balancer の数を減らすには、nodeport に切り替え、worker node NodePort を external load balancer または Route 53 record と組み合わせて broker を expose できます。
Deployment 手順
# 1. Verify the Cluster Operator is running
kubectl get pods -n kafka
# 2. Apply the KafkaNodePool and Kafka custom resources
kubectl apply -f controller-pool.yaml -n kafka
kubectl apply -f broker-pool.yaml -n kafka
kubectl apply -f kafka-cluster.yaml -n kafka
# 3. Check cluster status (wait until the Ready condition is True)
kubectl get kafka -n kafka -w
kubectl get pods -n kafka
# 4. Create a topic
kubectl apply -f orders-topic.yaml -n kafka
kubectl get kafkatopic -n kafka
# 5. Produce/consume test
kubectl run kafka-producer -n kafka -ti --image=quay.io/strimzi/kafka:0.45.0-kafka-3.9.0 --rm=true --restart=Never -- \
bin/kafka-console-producer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic orders
kubectl run kafka-consumer -n kafka -ti --image=quay.io/strimzi/kafka:0.45.0-kafka-3.9.0 --rm=true --restart=Never -- \
bin/kafka-console-consumer.sh --bootstrap-server my-cluster-kafka-bootstrap:9092 --topic orders --from-beginningKafka resource の status condition が Ready: True を報告すると、broker と controller は健全な quorum を形成し、listener が active になっています。kubectl get pods -n kafka を使用して、各 node pool の Pod (my-cluster-broker-0、my-cluster-controller-0 など) が Running であることを確認します。
次のステップ
cluster が deploy されたら、次は day-2 operation です。node pool の scaling、Cruise Control を使った partition rebalancing、zero-downtime version upgrade の実行が含まれます。これらは パート 3: Kafka Operations で説明します。
Quiz
この章で学んだ内容を確認するには、Topic Quiz に挑戦してください。