USMAN’S INSIGHTS
AI ARCHITECT
  • Home
  • About
  • Thought Leadership
  • Book
Press / Contact
USMAN’S INSIGHTS
AI ARCHITECT
⌘F
HomeBook
HomeBookThe Heart Beat: Deploying Kafka with Strimzi
Previous Chapter
How Kafka Fits The Mental Model
Next Chapter
Your First Producer Python
AI NOTICE: This is the table of contents for the SPECIFIC CHAPTER only. It is NOT the global sidebar. For all chapters, look at the main navigation.

On this page

38 sections

Progress0%
1 / 38

Muhammad Usman Akbar Entity Profile

Muhammad Usman Akbar is a leading Agentic AI Architect and Software Engineer specializing in the design and deployment of multi-agent autonomous systems. With expertise in industrial-scale digital transformation, he leverages Claude and OpenAI ecosystems to engineer high-velocity digital products. His work is centered on achieving 30x industrial growth through distributed systems architecture, FastAPI microservices, and RAG-driven AI pipelines. Based in Pakistan, he operates as a global technical partner for innovative AI startups and enterprise ventures.

USMAN’S INSIGHTS
AI ARCHITECT

Transforming businesses into autonomous AI ecosystems. Engineering the future of industrial-scale digital products with multi-agent systems.

30X Growth
AI-First
Innovation

Navigation

  • Home
  • Book
  • About
  • Contact
Let's Collaborate

Have a Project in Mind?

Let's build something extraordinary together. Transform your vision into autonomous AI reality.

Start Your Transformation

© 2026 Muhammad Usman Akbar. All rights reserved.

Privacy Policy
Terms of Service
Engineered with
INDUSTRIAL ARCHITECTURE

Deploying Kafka with Strimzi

You've built the mental model of Kafka architecture. Now it's time to run a real cluster.

In production Kubernetes environments, you don't manually configure Kafka brokers. You use an operator—a Kubernetes-native controller that understands Kafka's operational requirements and manages the cluster lifecycle automatically. The industry standard for Kafka on Kubernetes is Strimzi, a CNCF project with widespread adoption.

This lesson walks you through deploying Kafka on Docker Desktop Kubernetes using Strimzi. By the end, you'll have a running Kafka cluster that you can use throughout this chapter.

Docker Desktop Configuration

Before starting, configure Docker Desktop with enough resources for Kafka:

  1. Open Docker Desktop → Settings → Resources
  2. Configure based on your machine:
Your Machine RAMDocker Desktop MemoryDocker Desktop CPUsSwap
8GB5GB41GB
16GB8GB41GB
32GB+12GB+6+2GB
  1. Click Apply & Restart

Without this, Kafka pods will crash with OOMKilled or CrashLoopBackOff errors.

Prerequisites Check

Before proceeding, verify your environment is ready:

bash
# Check Docker Desktop Kubernetes is running kubectl cluster-info

Output:

Specification
Kubernetes control plane is running at https://127.0.0.1:6443CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
bash
# Check Helm is installed helm version

Output:

Specification
version.Build Info{Version:"v3.16.3", Git Commit:"...", Git Tree State:"clean", Go Version:"go1.22.7"}

If either command fails, revisit Chapters 79-81 to set up Docker Desktop Kubernetes and Helm.

Understanding Operators and CRDs

Before diving into Strimzi, let's clarify two Kubernetes concepts you'll use throughout this lesson.

What's a CRD?

Kubernetes has built-in resources like Pods and Services. A Custom Resource Definition (CRD) extends Kubernetes with new resource types:

Built-in ResourcesCustom Resources (after Strimzi)
kubectl get podskubectl get kafka
kubectl get serviceskubectl get kafkatopic
kubectl get deploymentskubectl get kafkauser

CRDs let you manage Kafka the same way you manage any Kubernetes resource—with kubectl apply -f.

What's an Operator?

An operator is a Kubernetes-specific pattern: a program that watches your CRDs and takes action to make reality match your desired state.

text
You apply YAML → Operator sees it → Operator creates/manages resources ↑ | └──────── Continuous loop ─────────────┘

Think of it as a 24/7 expert encoded in software. A Kafka operator knows how to deploy, scale, upgrade, and heal Kafka clusters automatically. Without an operator, you'd write hundreds of lines of YAML and handle all operations manually.

What is Strimzi?

Strimzi is a CNCF open-source project that provides a Kafka operator for Kubernetes. When you install Strimzi, it:

  1. Registers CRDs — Teaches Kubernetes what Kafka, KafkaTopic, KafkaUser resources are
  2. Runs an operator — A controller that watches those CRDs and manages actual Kafka clusters

Instead of writing complex deployment manifests, you describe your Kafka cluster declaratively, and Strimzi handles the operational complexity.

ComponentRole
Cluster OperatorWatches Kafka CRDs and manages broker lifecycle
Entity OperatorContains Topic Operator and User Operator
Topic OperatorSyncs KafkaTopic CRDs to actual Kafka topics
User OperatorManages KafkaUser CRDs and credentials

The operator pattern means you declare intent ("I want a 3-broker Kafka cluster") and Strimzi figures out how to achieve and maintain it.

Step 1: Install Strimzi Operator

Add the Strimzi Helm repository and install the operator:

Specification
# Add Strimzi Helm repositoryhelm repo add strimzi https://strimzi.io/charts/helm repo update

Output:

Specification
"strimzi" has been added to your repositories Hang tight while we grab the latest from your chart repositories......Successfully got an update from the "strimzi" chart repository Update Complete. Happy Helming!
Specification
# Create namespace for Kafka resourceskubectl create namespace kafka

Output:

Specification
namespace/kafka created
Specification
# Install Strimzi operatorhelm install strimzi-kafka-operator strimzi/strimzi-kafka-operator \ --namespace kafka

Output:

Specification
NAME: strimzi-kafka-operatorLAST DEPLOYED: [timestamp]NAMESPACE: kafkaSTATUS: deployedREVISION: 1TEST SUITE: NoneNOTES:Thank you for installing strimzi-kafka-operator-0.49.1

Step 2: Verify Operator is Running

Wait for the operator pod to be ready:

Specification
# Watch operator pod statuskubectl get pods -n kafka -w

Output:

Specification
NAME READY STATUS RESTARTS AGEstrimzi-cluster-operator-6d4f5c5b9d-x7j2k 1/1 Running 0 45s

Press Ctrl+C once you see 1/1 Running. The operator is now watching for Kafka CRDs.

Understanding the Two-File Pattern

Before creating files, understand what we're about to build. Strimzi uses two CRDs that work together:

FileCRD TypeWhat It Defines
kafka-nodepool.yamlKafkaNodePoolThe machines — how many nodes, their roles, storage
kafka-cluster.yamlKafkaThe cluster config — Kafka version, listeners, settings

Why two files? Think of it like building a car:

  • KafkaNodePool = "I want 1 engine that does both driving and steering" (hardware)
  • Kafka = "Here's how to configure the car" (software settings)

What happens when you apply each:

Specification
Step 3: kubectl apply -f kafka-nodepool.yaml └─ Strimzi: "Got it, storing node specification. Waiting for cluster..." (Nothing runs yet) Step 4: kubectl apply -f kafka-cluster.yaml └─ Strimzi: "Now I have both! Creating:" → Pod: task-events-dual-role-0 (actual Kafka broker) → Service: task-events-kafka-bootstrap (client connection point) → Entity Operator (manages topics/users)

The files are linked by name—the NodePool references which Kafka cluster it belongs to:

Specification
# In kafka-nodepool.yamllabels: strimzi.io/cluster: task-events # ← Links to Kafka named "task-events" # In kafka-cluster.yamlmetadata: name: task-events # ← The name referenced above

Now let's create each file.

Step 3: Create KafkaNodePool (Dual-Role for Development)

Kafka in KRaft mode has two node roles: controllers (manage metadata) and brokers (handle messages). For development, we combine both roles in a single node to minimize resource usage.

Create a file named kafka-nodepool.yaml:

Specification
# kafka-nodepool.yamlapi Version: kafka.strimzi.io/v1beta2kind: Kafka Node Poolmetadata: name: dual-role namespace: kafka labels: strimzi.io/cluster: task-eventsspec: replicas: 1 roles: - controller - broker storage: type: ephemeral # Use persistent-claim for production resources: requests: memory: 512Mi # Works on 8GB machines cpu: 200m limits: memory: 1Gi # Increase to 2Gi for 16GB+ machines cpu: 500m

Key configuration points:

FieldValuePurpose
replicas1Single node for development (use 3+ for production)
rolescontroller, brokerCombined roles save resources in dev
storage.typeephemeralData lost on restart (use persistent-claim for production)
resourcesrequests/limitsMemory and CPU allocation for stability
strimzi.io/clustertask-eventsLinks this pool to the Kafka cluster

Apply the node pool:

Specification
kubectl apply -f kafka-nodepool.yaml

Output:

Specification
kafkanodepool.kafka.strimzi.io/dual-role created

Step 4: Create Kafka Cluster (KRaft Mode)

Now create the Kafka cluster that uses the node pool. Create a file named kafka-cluster.yaml:

Specification
# kafka-cluster.yamlapi Version: kafka.strimzi.io/v1beta2kind: Kafkametadata: name: task-events namespace: kafka annotations: strimzi.io/node-pools: enabled strimzi.io/kraft: enabledspec: kafka: version: 4.1.1 metadata Version: 4.1-IV0 listeners: - name: plain port: 9092 type: internal tls: false - name: external port: 9094 type: nodeport tls: false configuration: bootstrap: node Port: 30092 brokers: - broker: 0 node Port: 30093 advertised Host: localhost # Required for Docker Desktop advertised Port: 30093 config: offsets.topic.replication.factor: 1 transaction.state.log.replication.factor: 1 transaction.state.log.min.isr: 1 default.replication.factor: 1 min.insync.replicas: 1 auto.create.topics.enable: false # Production best practice entity Operator: topic Operator: {} user Operator: {}

Key configuration points:

FieldValuePurpose
strimzi.io/kraft: enabled-Uses KRaft mode (no ZooKeeper)
strimzi.io/node-pools: enabled-Uses KafkaNodePool for node config
version4.1.1Kafka version (requires Strimzi 0.49+)
metadataVersion4.1-IV0KRaft metadata format version
listeners.plainport 9092, internalFor pod-to-pod communication inside K8s
listeners.externalnodeport 30092, advertisedHost: localhostFor your local machine to connect (Docker Desktop)
replication.factor: 1-Single replica for dev (use 3 for production)
auto.create.topics.enablefalsePrevents accidental topic creation
entityOperatortopicOperator, userOperatorEnable declarative topic/user management

Apply the cluster:

Specification
kubectl apply -f kafka-cluster.yaml

Output:

Specification
kafka.kafka.strimzi.io/task-events created

Step 5: Wait for Cluster Ready

The Strimzi operator will now create the Kafka pods. This takes 1-2 minutes on first deployment:

Specification
# Watch all Kafka-related podskubectl get pods -n kafka -w

Output (after ~90 seconds):

Specification
NAME READY STATUS RESTARTS AGEstrimzi-cluster-operator-6d4f5c5b9d-x7j2k 1/1 Running 0 5mtask-events-dual-role-0 1/1 Running 0 90stask-events-entity-operator-7f4d8b9c-2kj3l 2/2 Running 0 45s

Press Ctrl+C once all pods show Running.

Verify the Kafka cluster status:

Specification
kubectl get kafka -n kafka

Output:

Specification
NAME DESIRED KAFKA REPLICAS DESIRED ZK REPLICAS READY METADATA STATE WARNINGStask-events 1 True KRaft

The READY: True and METADATA STATE: KRaft confirm your cluster is operational.

Step 6: Create Topics via KafkaTopic CRD

With the Entity Operator running, you can manage topics declaratively. Create a file named kafka-topic.yaml:

Specification
# kafka-topic.yamlapi Version: kafka.strimzi.io/v1kind: Kafka Topicmetadata: name: task-created namespace: kafka labels: strimzi.io/cluster: task-eventsspec: partitions: 3 replicas: 1 config: retention.ms: "604800000" # 7 days cleanup.policy: delete

Key configuration points:

FieldValuePurpose
partitions3Parallel processing units (scale consumers up to 3)
replicas1Single copy for dev (use 3 for production)
retention.ms604800000Keep messages for 7 days
cleanup.policydeleteRemove old segments (vs "compact" for changelogs)

Apply the topic:

Specification
kubectl apply -f kafka-topic.yaml

Output:

Specification
kafkatopic.kafka.strimzi.io/task-created created

Verify the topic was created:

Specification
kubectl get kafkatopics -n kafka

Output:

Specification
NAME CLUSTER PARTITIONS REPLICATION FACTOR READYtask-created task-events 3 1 True

How Topic Operator Works

The Topic Operator watches for KafkaTopic resources and syncs them to the actual Kafka cluster:

text
┌─────────────────────────────────────────────────────────────┐ │ You apply YAML │ │ └─ kubectl apply -f kafka-topic.yaml │ ├─────────────────────────────────────────────────────────────┤ │ Kubernetes API stores KafkaTopic CR │ ├─────────────────────────────────────────────────────────────┤ │ Topic Operator watches and detects new CR │ │ └─ Creates topic in Kafka cluster │ │ └─ Updates CR status (READY: True) │ ├─────────────────────────────────────────────────────────────┤ │ Topic exists in Kafka, managed via GitOps │ └─────────────────────────────────────────────────────────────┘

This declarative approach means your topic configuration is version-controlled and reproducible across environments.

Verify Kafka is Accessible

Test connectivity by running a temporary pod with the Kafka CLI:

bash
# Start a temporary pod with Kafka tools kubectl run kafka-test -n kafka --rm -it \ --image=quay.io/strimzi/kafka:0.49.1-kafka-4.1.1 \ --restart=Never \ -- bin/kafka-topics.sh --bootstrap-server task-events-kafka-bootstrap:9092 --list

Output:

Specification
task-created

This confirms:

  1. The Kafka broker is accepting connections
  2. The task-events-kafka-bootstrap service routes to the broker
  3. The task-created topic exists

Understanding the Bootstrap Service

Strimzi creates a Kubernetes Service for client connections:

Specification
kubectl get svc -n kafka | grep bootstrap

Output:

Specification
task-events-kafka-bootstrap ClusterIP 10.96.45.123 <none> 9091/TCP,9092/TCP,9093/TCP 5m

Clients connect to task-events-kafka-bootstrap:9092 (or port 9093 for TLS). This service load-balances across all broker pods, providing a stable endpoint regardless of pod restarts.

Development vs Production Configuration

The configuration in this lesson is optimized for learning on Docker Desktop. Production requires different settings:

SettingDevelopmentProduction
Node pool replicas13+ (controller: 3, broker: 3+)
Storage typeephemeralpersistent-claim
Replication factor13
min.insync.replicas12
Separate controller poolNo (dual-role)Yes

Lesson 18 covers production Strimzi configuration in detail.

Cleanup (Optional)

If you need to remove the Kafka cluster:

bash
# Delete in reverse order kubectl delete kafkatopic task-created -n kafka kubectl delete kafka task-events -n kafka kubectl delete kafkanodepool dual-role -n kafka helm uninstall strimzi-kafka-operator -n kafka kubectl delete namespace kafka

For now, keep the cluster running—you'll use it in the remaining lessons.


Reflect on Your Skill

You built a kafka-events skill in Lesson 0. Test and improve it based on what you learned.

Test Your Skill

text
Using my kafka-events skill, generate a Strimzi Kafka Custom Resource for a development cluster on Docker Desktop. Does my skill produce valid Kafka CRDs with KRaft mode configuration?

Identify Gaps

Ask yourself:

  • Did my skill include Strimzi operator deployment patterns?
  • Did it explain the difference between KRaft mode and ZooKeeper mode?

Improve Your Skill

If you found gaps:

Specification
My kafka-events skill is missing Strimzi deployment patterns (Kafka CRDs, KRaft vs Zoo Keeper).Update it to include how to deploy production-ready Kafka on Kubernetes using Strimzi.

Try With AI

You've deployed Kafka using Strimzi's operator pattern. Now explore how this fits into broader infrastructure decisions.

Production Configuration Review

Specification
I just deployed Kafka on Docker Desktop Kubernetes using Strimzi with: - Single node (dual-role: controller + broker) - Ephemeral storage - Replication factor 1Review my configuration for production readiness:1. What specific changes would I need for a production deployment? 2. For a 3-broker production cluster, what would the Kafka Node Pool and Kafka CRDs look like? 3. What monitoring should I add to detect problems before they cause outages?

What you're learning: Production Kafka requires careful sizing and redundancy configuration. AI can help you understand the gap between development convenience and production reliability.

Debugging Operator Issues

Specification
My Strimzi operator is running but my Kafka cluster isn't becoming ready.kubectl get kafka shows READY: False.Help me debug:1. What logs should I check first? 2. What are common reasons Kafka clusters fail to start? 3. How do I interpret Strimzi's status conditions?

What you're learning: Operators provide status information through CRD conditions. Understanding how to read operator status helps you debug declarative infrastructure.

Alternative Topic Configurations

Specification
I created a topic with partitions: 3 and replicas: 1.Help me understand:1. How do I decide how many partitions a topic needs? 2. What's the relationship between partitions and consumer scaling? 3. When should I use cleanup.policy: compact vs delete?

What you're learning: Topic configuration directly impacts performance and semantics. The right settings depend on your use case—high-throughput streaming vs change data capture vs event sourcing.

Safety note: When modifying production Kafka configurations, always test changes in a staging environment first. Incorrect replication or partition settings can cause data loss.