第 12/15 天
引言
在企业级微服务架构中,消息队列是解耦生产者与消费者、削峰填谷、异步通信的核心中间件。Apache Kafka 作为分布式流处理平台的标杆,凭借高吞吐、低延迟、可持久化、水平扩展的特性,被广泛应用于日志聚合、事件溯源、实时数据管道等场景。本篇是「Ceph+K8s 中间件实战」系列第 12 天,我们将基于 Bitnami 官方 Helm Chart,在已经接入 Ceph RBD 块存储的 Kubernetes 集群上部署一个多节点 Kafka 集群,并完成架构设计、持久化配置、登录验证与日常巡检。
设计架构
组件拓扑
本方案部署 3 节点 Kafka 集群(KRaft 模式,无需独立 ZooKeeper),每个 Broker 独占一个 Pod,数据通过 Ceph RBD 持久化到 Ceph 分布式存储池中,天然获得多副本高可用保障。
| 组件 | 副本数 | 角色 | 存储 |
|---|---|---|---|
| Kafka Broker (KRaft) | 3 | combined controller+broker | Ceph RBD PVC |
| Client(临时) | 1 | 生产/消费测试 | 无 |
数据流向
生产者 → Kafka Broker(Leader) → Followers 同步 → Ceph RBD PVC → Ceph OSD(多副本)
↓
消费者拉取
Kafka 的分区日志以 segment 文件形式写入 PVC,由 Ceph RBD 的块设备承载。Ceph 层通过 CRUSH 算法将数据多副本分散到不同 OSD 节点,即使单个 K8s 节点宕机,只要 Ceph 集群健康,数据不丢、Pod 可漂移重建。

高可用机制
- Broker 级高可用:3 节点集群,设置
default.replication.factor=3、min.insync.replicas=2,单 Broker 故障不影响读写。 - 分区 Leader 选举:KRaft 模式下由 Controller 仲裁分区 Leader 切换,毫秒级完成故障转移。
- 存储级高可用:Ceph RBD 数据在 OSD 层 3 副本,与 K8s 节点物理位置解耦。
- Pod 重调度:K8s Deployment/StatefulSet 机制保证 Pod 异常后自动在健康节点重建并挂载同一 PVC。
存储规划
- StorageClass:
ceph-rbd-sc(前面章节已创建,provisioner: rbd.csi.ceph.com) - 每个 Broker PVC:
50Gi - 数据目录:
/bitnami/kafka/data - 副本因子:
replication.factor=3
部署实战
1. 添加 Bitnami Helm 仓库
# 添加 Bitnami 官方 Chart 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 搜索确认 kafka chart 可用
helm search repo bitnami/kafka –versions | head -n 10
预期输出包含 bitnami/kafka 及最新版本号(如 26.4.x)。
2. 编写 values.yaml 自定义配置
# kafka-values.yaml —— Ceph RBD 持久化 Kafka 集群
replicaCount: 3
# KRaft 模式(Kafka 3.3+ 内置元数据管理,无需 ZooKeeper)
kraft:
enabled: true
# 监听器配置
listenerSecurityProtocolMap: |
INTERNAL: PLAINTEXT
CONTROLLER: PLAINTEXT
listeners: |
INTERNAL://:9092
CONTROLLER://:9093
advertisedListeners: |
INTERNAL://kafka-0.kafka-headless.kafka.svc.cluster.local:9092
# 资源限制
resources:
requests:
cpu: "500m"
memory: "1Gi"
limits:
cpu: "2000m"
memory: "3Gi"
# JVM 堆
heapOpts: "-Xmx2g -Xms2g"
# Kafka 关键参数
config:
num.partitions: 12
default.replication.factor: 3
min.insync.replicas: 2
log.retention.hours: 168
log.segment.bytes: 1073741824
auto.create.topics.enable: false
# Ceph RBD 持久化
persistence:
enabled: true
storageClass: "ceph-rbd-sc"
accessModes:
– ReadWriteOnce
size: 50Gi
# ServiceAccount 与 RBAC
serviceAccount:
create: true
# Headless Service 用于 Broker 间通信
service:
type: ClusterIP
ports:
client: 9092
controller: 9093
关键点:
storageClass: "ceph-rbd-sc"让每个 Broker 的数据落盘到 Ceph 块存储;kraft.enabled: true使用 KRaft 模式省去 ZooKeeper 依赖;min.insync.replicas=2配合default.replication.factor=3保证生产者 acks=all 时的数据可靠性。
3. Helm 安装部署
# 创建独立命名空间
kubectl create namespace middleware
# 部署 Kafka 集群
helm install kafka bitnami/kafka
–namespace middleware
–version 26.4.0
-f kafka-values.yaml
–timeout 10m
# 等待所有 Pod 就绪
kubectl wait –for=condition=ready pod -l app.kubernetes.io/name=kafka
-n middleware –timeout=300s
4. 验证 Pod / Service / PVC 状态
# 查看 Pod 状态,应有 3 个 Running
kubectl get pods -n middleware -l app.kubernetes.io/name=kafka
# 查看 Service
kubectl get svc -n middleware | grep kafka
# 查看 PVC,应有 3 个 Bound 状态的 Ceph RBD 卷
kubectl get pvc -n middleware -l app.kubernetes.io/name=kafka
# 查看 StorageClass 确认使用 Ceph RBD
kubectl get sc ceph-rbd-sc
预期输出:
NAME READY STATUS RESTARTS AGE
kafka-0 1/1 Running 0 3m
kafka-1 1/1 Running 0 3m
kafka-2 1/1 Running 0 3m
登录验证
1. 进入容器查看集群元数据
# 获取集群元数据,确认 3 个 broker 已注册
kubectl exec -n middleware kafka-0 —
kafka-metadata-quorum.sh –bootstrap-server kafka-0.kafka-headless.middleware.svc.cluster.local:9092
describe –status
# 列出所有 Broker
kubectl exec -n middleware kafka-0 —
kafka-broker-api-versions.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092 | grep -E "^kafka-"
2. 创建测试 Topic 并生产消费
# 创建一个 3 分区 3 副本的测试 topic
kubectl exec -n middleware kafka-0 —
kafka-topics.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–create –topic test-ceph-kafka
–partitions 3 –replication-factor 3
# 查看 topic 详情与分区 Leader 分布
kubectl exec -n middleware kafka-0 —
kafka-topics.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–describe –topic test-ceph-kafka
# 启动生产者写入测试消息
kubectl exec -n middleware kafka-0 —
kafka-console-producer.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–topic test-ceph-kafka <<'EOF'
hello ceph kafka
hello k8s middleware
persistent on ceph rbd
EOF
# 消费者读取验证
kubectl exec -n middleware kafka-0 —
kafka-console-consumer.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–topic test-ceph-kafka –from-beginning –max-messages 3
预期输出应能看到三条消息被正确消费,证明集群端到端可用。
3. 验证 Ceph RBD 持久化
# 查看 Broker 数据落盘路径
kubectl exec -n middleware kafka-0 — ls -lh /bitnami/kafka/data
# 查看 Ceph 后端的 RBD image
kubectl exec -n middleware kafka-0 — df -h | grep kafka
# 在 Ceph 端确认 RBD image 存在(在 Ceph 客户端执行)
rbd ls -p kubernetes-pvc | grep kafka
日常巡检
1. 集群健康检查
# Pod 状态巡检
kubectl get pods -n middleware -l app.kubernetes.io/name=kafka -o wide
# KRaft 仲裁状态
kubectl exec -n middleware kafka-0 —
kafka-metadata-quorum.sh –bootstrap-server localhost:9092
describe –status | grep -E "LeaderId|HighWatermark"
# Controller 活跃节点
kubectl exec -n middleware kafka-0 —
kafka-metadata-quorum.sh –bootstrap-server localhost:9092 describe –active-controllers
2. Topic 与分区巡检
# 列出所有 topic
kubectl exec -n middleware kafka-0 —
kafka-topics.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092 –list
# 检查所有 topic 的副本分布与 ISR
kubectl exec -n middleware kafka-0 —
kafka-topics.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092 –describe | grep -E "UnderReplicated|OfflinePartition"
若
UnderReplicatedPartitions出现非 0 值,说明有副本同步滞后,需排查 Broker 或 Ceph IO。
3. 消费者组与堆积监控
# 列出所有消费者组
kubectl exec -n middleware kafka-0 —
kafka-consumer-groups.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092 –list
# 查看指定消费者组 lag(堆积量)
kubectl exec -n middleware kafka-0 —
kafka-consumer-groups.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–describe –group my-consumer-group | grep -v TOPIC
4. 日志与容量巡检
# 查看 Kafka 运行日志
kubectl logs -n middleware kafka-0 –tail=100
# 查看 PVC 使用率
kubectl exec -n middleware kafka-0 — df -h /bitnami/kafka/data
# 集群级 PVC 容量概览
kubectl get pvc -n middleware -l app.kubernetes.io/name=kafka
-o custom-columns=NAME:.metadata.name,STATUS:.status.phase,CAPACITY:.status.capacity.storage,SC:.spec.storageClassName
# 磁盘 IO 性能巡检
kubectl exec -n middleware kafka-0 — iostat -xm 2 3 | grep -E "rbd|Device"
常见问题
FAQ 1:Pod 一直 Pending,PVC 无法绑定
现象:kubectl get pvc 显示 Pending,Events 提示 storageclass "ceph-rbd-sc" not found。
排查与解决:
# 确认 StorageClass 名称拼写正确
kubectl get sc
# 确认 Ceph-CSI provisioner Pod 正常运行
kubectl get pods -n ceph-csi | grep rbd
# 确认 Ceph RBD pool 存在且可写
ceph osd pool ls | grep kubernetes-pvc
常见原因:StorageClass 名拼写错误、Ceph-CSI 未部署、Ceph pool 权限不足。按上述顺序逐一排查。
FAQ 2:KRaft 集群无法选主,Broker 日志报 controller quorum 异常
现象:多节点同时退出后重新加入,日志反复出现 Unable to begin fence 或 Controller id is already registered。
排查与解决:
# 检查各节点 controllerQuorum voters 配置是否一致
kubectl exec -n middleware kafka-0 — cat /opt/bitnami/kafka/config/kraft/controller.properties | grep voters
# 检查 9093 端口连通性
kubectl exec -n middleware kafka-0 — nc -zv kafka-1.kafka-headless.middleware.svc.cluster.local 9093
# 查看 KRaft 日志
kubectl logs -n middleware kafka-0 | grep -i "quorum|controller"
通常是 listeners / advertisedListeners 配置中 controller 端口不一致,或 Headless Service DNS 解析异常导致。确保所有节点 CONTROLLER://:9093 配置完全一致。
FAQ 3:生产者写入报 NOT_ENOUGH_REPLICAS
现象:acks=all 时写入失败,提示 NOT_ENOUGH_REPLICAS。
排查与解决:
# 检查 ISR 数量
kubectl exec -n middleware kafka-0 —
kafka-topics.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–describe –topic test-ceph-kafka
# 检查 min.insync.replicas 与 replication.factor 配置
kubectl exec -n middleware kafka-0 —
kafka-configs.sh –bootstrap-server kafka.kafka.svc.cluster.local:9092
–entity-type topics –entity-name test-ceph-kafka –describe
通常是 ISR 数量低于 min.insync.replicas,往往因 Ceph IO 滞后或某 Broker 节点负载过高。临时降配(min.insync.replicas=1)可恢复写入,但需尽快排查根因。
总结
本篇我们在已接入 Ceph RBD 的 K8s 集群上,通过 Bitnami 官方 Helm Chart 部署了一个 3 节点 KRaft 模式 Kafka 集群。核心要点回顾:
- 架构层面:KRaft 模式去除了 ZooKeeper 依赖,3 Broker 同时承担 controller + broker 角色,结构更简洁。
- 存储层面:每个 Broker 通过
storageClass: ceph-rbd-sc将日志持久化到 Ceph 块存储,获得数据多副本保障。 - 可靠性层面:
default.replication.factor=3+min.insync.replicas=2配合 Ceph 层副本,形成应用层与存储层双重高可用。 - 运维层面:提供了从 Pod、PVC、KRaft 仲裁、Topic ISR、消费者 lag 到 Ceph RBD image 的全链路巡检命令。
Kafka 作为事件驱动架构的骨干,其稳定性直接决定上下游业务连续性。结合 Ceph RBD 的可靠存储底座,我们在 K8s 上获得了一个生产可用的消息流平台。
下期预告
下一篇「Ceph+K8s 中间件实战 | 第 13 天」将聚焦 K8s 部署 GitLab 代码托管平台,使用官方 gitlab/gitlab Helm Chart,配合 Ceph RBD 持久化代码仓库与 CI 产物,讲解 GitLab 在 K8s 上的组件拓扑、高可用架构与日常运维巡检。
系列目录
.series-toc { font-size: 0.95em; line-height: 1.8; }
.series-toc a { text-decoration: none; }
.series-toc .done { color: #28a745; }
.series-toc .current { color: #0366d6; font-weight: bold; }
.series-toc .upcoming { color: #999; }
- 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述 ✅
- 第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战) ✅
- 第 3 天:K8s 接入 CephFS 共享文件存储(多读场景与性能调优) ✅
- 第 4 天:K8s 部署 MySQL 高可用集群(Ceph RBD 持久化 + 架构设计 + 登录巡检) ✅
- 第 5 天:K8s 部署 Redis Cluster 集群(Ceph RBD + 架构设计 + 巡检命令) ✅
- 第 6 天:K8s 部署 Redis Sentinel 哨兵模式(高可用架构 + 登录验证) ✅
- 第 7 天:K8s 部署 MinIO 对象存储集群(分布式架构 + 运维巡检) ✅
- 第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录) ✅
- 第 9 天:K8s 部署 Nacos 注册配置中心(集群架构 + 登录巡检) ✅
- 第 10 天:K8s 部署 Zookeeper 集群(分布式协调架构 + 运维命令) ✅
- 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检) ✅
- 第 12 天:K8s 部署 Kafka 集群(Ceph RBD + 消息队列架构 + 运维) 📌 本文
- 第 13 天:K8s 部署 GitLab 代码托管平台(Ceph RBD 持久化 + 架构 + 巡检) 🕐
- 第 14 天:K8s 部署 ClickHouse 列式数据库集群(Ceph RBD + 架构设计) 🕐
- 第 15 天:K8s 中间件统一监控与运维巡检总结(Prometheus + Grafana 全景) 🕐

















暂无评论内容