第 10/15 天
引言
在分布式系统领域,Zookeeper 是最经典的分布式协调服务之一。它由 Apache 开源,最初源自 Yahoo 研究院,为分布式应用提供统一的配置管理、命名服务、分布式同步和组服务等核心能力。无论是 Kafka、HBase、Hadoop,还是 Dubbo、Solr,都将 Zookeeper 作为底层一致性协调基石。
在前一篇 Nacos 的实战中我们提到,许多中间件(尤其 Kafka)底层都依赖 Zookeeper 进行元数据管理和 Leader 选举。当我们将 Zookeeper 部署到 Kubernetes 集群,并使用 Ceph RBD 提供持久化存储时,便构建了一套高可用、数据可靠的分布式协调底座。
本篇是「Ceph+K8s 中间件实战」系列第 10 天,将完整讲解 Zookeeper 集群在 K8s 上的架构设计、Bitnami Helm Chart 部署、Ceph RBD 持久化配置,以及登录验证与日常巡检命令。

设计架构
组件拓扑
Zookeeper 集群(又称 Ensemble)在 K8s 上的部署架构涉及以下组件:
| 组件 | 说明 | 数量 |
|---|---|---|
| Zookeeper Server | 协调服务核心节点,参与 Leader 选举与数据复制 | 3(奇数,集群模式) |
| Headless Service | 为 StatefulSet 提供稳定 Pod DNS(zk-0.zk-headless) |
1 |
| ClusterIP Service | 为客户端提供负载均衡访问入口(端口 2181) | 1 |
| PVC(Ceph RBD) | 每个 Pod 独立持久卷,存储事务日志与快照数据 | 3 |
| ConfigMap | 存放集群配置参数(myid、tickTime 等) | 1 |
数据流向
Zookeeper 采用 ZAB(Zookeeper Atomic Broadcast)协议 保证数据一致性,数据流向如下:
- 客户端写入:客户端连接任意 Zookeeper 节点(Follower),发起写请求。
- 转发 Leader:若连接的是 Follower,写请求被转发至 Leader 节点。
- 生成事务 Proposal:Leader 为请求生成全局唯一递增的事务 ID(zxid),生成 Proposal。
- 广播投票:Leader 通过 ZAB 协议向所有 Follower 发送 Proposal,Follower 写入本地事务日志后回复 ACK。
- 半数确认提交:Leader 收到超过半数 ACK 后提交事务,并通知所有 Follower 提交。
- 响应客户端:最终写成功结果返回客户端。
数据持久化方面,每个事务先写入 事务日志(transaction log),定期生成 数据快照(snapshot)。在 K8s 中,这些数据存储在 Ceph RBD 支撑的 PVC 中,确保 Pod 重建后数据不丢失。
高可用机制
Zookeeper 的高可用建立在以下机制上:
- 奇数节点:3 节点可容忍 1 个节点故障,5 节点可容忍 2 个节点故障。本方案使用 3 节点,满足多数中小规模场景。
- Leader 选举:集群启动或 Leader 故障时,通过 FastLeaderElection 算法在几秒内选出新 Leader,期间集群短暂不可用但自动恢复。
- 数据复制:所有写操作在半数以上节点确认后才提交,保证强一致性。
- StatefulSet + Headless Service:K8s 层面通过 StatefulSet 保证每个 Pod 拥有稳定网络标识(
zk-{ordinal}.zk-headless.default.svc.cluster.local),这是集群互相发现和选举的基础。 - Ceph RBD 持久卷:即使 Pod 被重新调度到其他节点,PVC 会重新挂载,事务日志和快照得以保留,避免数据丢失导致的集群状态不一致。
存储规划
| 存储类型 | 用途 | StorageClass | 大小 | 访问模式 |
|---|---|---|---|---|
| Ceph RBD | Zookeeper 数据目录 /bitnami/zookeeper |
ceph-rbd-sc |
8Gi / 节点 | ReadWriteOnce |
生产环境建议事务日志和数据快照分开存储(可挂载独立 PV 到不同目录),事务日志写入性能对 Zookeeper 吞吐影响较大。本篇为演示便利使用同一 PVC。
部署实战
前置条件确认
部署前确认 Ceph RBD StorageClass 已就绪(参考第 2 天配置):
# 确认 Ceph RBD StorageClass 存在
kubectl get storageclass ceph-rbd-sc
# 确认 CSI Driver 正常运行
kubectl get pods -n kube-system | grep ceph-csi
# 确认测试 PVC 可正常绑定
kubectl get pvc | grep ceph
预期输出应显示 ceph-rbd-sc StorageClass 存在,且 CSI Driver Pod 全部 Running。
添加 Bitnami Helm 仓库
Bitnami 维护了高质量、持续更新的 Zookeeper Helm Chart,是社区首选:
# 添加 Bitnami Helm 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
# 更新本地 Chart 索引
helm repo update
# 搜索 zookeeper chart,确认版本
helm search repo bitnami/zookeeper –versions | head -10
编写 values.yaml 自定义配置
创建 zk-values.yaml,重点配置 Ceph RBD 持久化、副本数、资源限制和认证:
# zk-values.yaml — Zookeeper 集群 Helm 部署配置
replicaCount: 3
# 镜像配置
image:
registry: docker.io
repository: bitnami/zookeeper
tag: 3.9.2-debian-12-r0
pullPolicy: IfNotPresent
# 持久化配置 — 核心:指向 Ceph RBD StorageClass
persistence:
enabled: true
storageClass: "ceph-rbd-sc"
accessModes:
– ReadWriteOnce
size: 8Gi
mountPath: /bitnami/zookeeper
# 资源限制
resources:
requests:
cpu: 250m
memory: 256Mi
limits:
cpu: "1"
memory: 512Mi
# 集群参数
tickTime: 2000
initLimit: 10
syncLimit: 5
maxClientCnxns: 60
autopurge:
purgeInterval: 1
snapRetainCount: 3
# 客户端认证(可选,生产建议开启)
auth:
client:
enabled: true
clientUser: "admin"
clientPassword: "ZkAdmin@2026"
quorum:
enabled: true
quorumUser: "quorum"
quorumPassword: "QuorumSec@2026"
# 暴露客户端端口
service:
type: ClusterIP
ports:
client: 2181
tls: 3181
follower: 2888
election: 3888
# 日志级别
logLevel: INFO
# 优雅终止宽限期
terminationGracePeriodSeconds: 120
Helm 安装部署
# 创建专用命名空间
kubectl create namespace middleware
# 使用自定义 values 部署 Zookeeper 集群
helm install zk bitnami/zookeeper
–namespace middleware
–values zk-values.yaml
–version 12.1.6
# 查看部署状态
helm list -n middleware
验证 Pod / Service / PVC 状态
# 查看 StatefulSet Pod 状态(等待全部 Running)
kubectl get pods -n middleware -l app.kubernetes.io/instance=zk -w
# 预期输出:
# NAME READY STATUS RESTARTS AGE
# zk-0 1/1 Running 0 2m
# zk-1 1/1 Running 0 1m
# zk-2 1/1 Running 0 45s
# 查看 Service
kubectl get svc -n middleware -l app.kubernetes.io/instance=zk
# 查看 Headless Service DNS
kubectl get svc -n middleware zk-headless
# 查看 PVC 绑定状态(确认全部 Bound)
kubectl get pvc -n middleware -l app.kubernetes.io/instance=zk
// PVC 预期输出示例
// NAME STATUS VOLUME CAPACITY STORAGECLASS AGE
// data-zk-0 Bound pvc-a1b2c3d4-xxxx-ceph-rbd 8Gi ceph-rbd-sc 3m
// data-zk-1 Bound pvc-e5f6g7h8-xxxx-ceph-rbd 8Gi ceph-rbd-sc 2m
// data-zk-2 Bound pvc-i9j0k1l2-xxxx-ceph-rbd 8Gi ceph-rbd-sc 1m
所有 PVC 显示 Bound 且 STORAGECLASS 为 ceph-rbd-sc,表明 Ceph RBD 已成功为每个 Zookeeper Pod 分配独立持久卷。

登录验证
连接 Zookeeper 集群
# 进入任一 Pod 的交互式 zkCli 命令行(开启认证时需带用户名密码)
kubectl exec -it zk-0 -n middleware — zkCli.sh
-server zk-0.zk-headless.middleware.svc.cluster.local:2181
-u admin:ZkAdmin@2026
# 或者从集群内其他 Pod 连接(通过 ClusterIP Service 负载均衡)
kubectl run zk-client –rm -it –image=bitnami/zookeeper:3.9.2-debian-12-r0
–restart=Never –namespace middleware —
zkCli.sh -server zk.middleware.svc.cluster.local:2181
-u admin:ZkAdmin@2026
验证集群状态
# 查看 Zookeeper 服务端版本与运行模式
kubectl exec -it zk-0 -n middleware — zkServer.sh version
# 查看集群各节点角色(Leader / Follower)
for i in 0 1 2; do
echo "=== zk-$i ==="
kubectl exec zk-$i -n middleware — zkServer.sh status 2>&1 | grep -E "Mode|Zookeeper"
done
# 预期输出:
# === zk-0 ===
# Mode: follower
# === zk-1 ===
# Mode: leader
# === zk-2 ===
# Mode: follower
四字命令(Four Letter Words)巡检
Zookeeper 提供轻量级四字命令用于集群健康检查。Bitnami Chart 默认启用了白名单:
# stat 命令:查看连接数、节点角色等概要信息
kubectl exec zk-0 -n middleware — bash -c
'echo stat | nc zk-0.zk-headless.middleware.svc.cluster.local 2181'
# ruok 命令:检查节点是否正常(返回 imok)
kubectl exec zk-0 -n middleware — bash -c
'echo ruok | nc zk-1.zk-headless.middleware.svc.cluster.local 2181'
# mntr 呡令:输出集群监控指标(Leader、Watch 数、延迟等)
kubectl exec zk-0 -n middleware — bash -c
'echo mntr | nc zk-1.zk-headless.middleware.svc.cluster.local 2181'
mntr 输出示例(关键字段):
zk_version 3.9.2
zk_avg_latency 2
zk_max_latency 45
zk_min_latency 0
zk_packets_received 1280
zk_packets_sent 1289
zk_num_alive_connections 3
zk_outstanding_requests 0
zk_server_state leader
zk_znode_count 15
zk_watch_count 4
日常巡检
健康检查
#!/bin/bash
# zk-health-check.sh — Zookeeper 日常健康巡检脚本
NS="middleware"
echo "========================================="
echo "Zookeeper 集群健康巡检 – $(date)"
echo "========================================="
# 1. Pod 状态检查
echo -e "n[1] Pod 状态:"
kubectl get pods -n $NS -l app.kubernetes.io/instance=zk
-o wide | awk '{print $1, $2, $3, $4, $7}'
# 2. 各节点角色检查(确保有且仅有 1 个 Leader)
echo -e "n[2] 集群角色:"
for i in 0 1 2; do
MODE=$(kubectl exec zk-$i -n $NS — zkServer.sh status 2>&1 | grep "Mode:" | awk '{print $2}')
echo " zk-$i: $MODE"
done
# 3. ruok 健康探测
echo -e "n[3] 健康探测 (ruok):"
for i in 0 1 2; do
RESULT=$(kubectl exec zk-$i -n $NS — bash -c "echo ruok | nc localhost 2181" 2>/dev/null)
echo " zk-$i: ${RESULT:-FAIL}"
done
# 4. PVC 状态检查
echo -e "n[4] PVC 持久卷状态:"
kubectl get pvc -n $NS -l app.kubernetes.io/instance=zk
-o custom-columns=NAME:.metadata.name,STATUS:.status.phase,CAPACITY:.status.capacity.storage,SC:.spec.storageClassName
日志查看
# 查看指定节点最近日志
kubectl logs zk-1 -n middleware –tail=100
# 实时跟踪 Leader 节点日志
kubectl logs -f zk-1 -n middleware
# 搜索异常关键字
kubectl logs zk-0 -n middleware | grep -iE "ERROR|WARN|exception"
kubectl logs zk-1 -n middleware | grep -iE "ERROR|WARN|exception"
kubectl logs zk-2 -n middleware | grep -iE "ERROR|WARN|exception"
# 查看事务日志目录磁盘使用(数据目录在 PVC 内)
kubectl exec zk-0 -n middleware — du -sh /bitnami/zookeeper/data/
kubectl exec zk-0 -n middleware — ls -lh /bitnami/zookeeper/data/version-2/
性能与容量巡检
# 查看集群延迟与吞吐指标(mntr)
kubectl exec zk-0 -n middleware — bash -c
'echo mntr | nc zk.middleware.svc.cluster.local 2181' |
grep -E "latency|packets|connections|outstanding|znode|watch"
# 检查 Watch 数量(过高可能影响性能)
kubectl exec zk-0 -n middleware — bash -c
'echo wchs | nc zk.middleware.svc.cluster.local 2181'
# 检查各节点连接详情(stat)
kubectl exec zk-1 -n middleware — bash -c
'echo stat | nc zk.middleware.svc.cluster.local 2181'
# Ceph RBD PVC 容量监控
kubectl exec zk-0 -n middleware — df -h /bitnami/zookeeper
# 查看快照与事务日志文件数量(autopurge 是否生效)
kubectl exec zk-0 -n middleware — bash -c
'ls /bitnami/zookeeper/data/version-2/ | wc -l'
模拟故障恢复演练
# 模拟 Leader 故障:删除 Leader Pod,观察自动选举
# 先确认当前 Leader
kubectl exec zk-0 -n $NS — zkServer.sh status 2>&1 | grep Mode
# 假设 zk-1 是 Leader,强制删除
kubectl delete pod zk-1 -n middleware –grace-period=0 –force
# 观察新 Leader 选举过程
watch -n 1 'for i in 0 1 2; do echo -n "zk-$i: "; kubectl exec zk-$i -n middleware — zkServer.sh status 2>&1 | grep -o "Mode:.*"; done'
# 预期:zk-1 被删除后重新拉起,期间 zk-0 或 zk-2 被选为新 Leader,
# 集群在数秒内恢复可用。Ceph RBD PVC 在 Pod 重建后自动重新挂载,数据不丢失。
常见问题
Q1: Zookeeper 集群 Pod 一直处于 CrashLoopBackOff,日志报 “Cannot open channel to X at election address”?
A: 这通常是集群节点间无法通信导致选举失败。排查步骤:①确认 Headless Service 存在且 DNS 解析正常(kubectl exec zk-0 -- nslookup zk-headless);②检查 2888(follower)和 3888(election)端口是否被 NetworkPolicy 拦截;③确认所有 Pod 的 myid 文件值唯一且正确;④若重建过集群但旧 PVC 数据残留,需清理 PVC 后重新部署(kubectl delete pvc data-zk-0 data-zk-1 data-zk-2 -n middleware),否则 myid 与快照不匹配会导致选举异常。
Q2: PVC 一直 Pending,无法绑定 Ceph RBD 卷?
A: ①确认 ceph-rbd-sc StorageClass 名称与 values.yaml 中 persistence.storageClass 完全一致;②检查 Ceph CSI Driver Pod 是否 Running(kubectl get pods -n kube-system | grep ceph);③在 Ceph 侧确认 RBD pool 可用且有足够空间(ceph osd pool stats);④查看 PVC 事件获取详细错误(kubectl describe pvc data-zk-0 -n middleware)。
Q3: 四字命令(ruok / mntr)无响应或被拒绝?
A: Zookeeper 3.5+ 默认仅允许 stat, ruok, conf, isro 等命令,需要在配置中显式启用 4lw.commands.whitelist=* 或指定需要的命令。Bitnami Chart 中可通过 values 设置 fourLetterCommandsWhiteList: "*" 开启全部(生产环境建议仅开启必要的命令)。另外确认是否有 NetworkPolicy 或防火墙拦截了 2181 端口的 TCP 连接。
总结
本篇我们完成了 Zookeeper 集群在 K8s 上的完整部署:
- 架构设计:讲解了 ZAB 协议的数据流向、Leader 选举的高可用机制,以及 3 节点奇数集群的容灾能力。StatefulSet + Headless Service 提供稳定网络标识,Ceph RBD PVC 保证事务日志持久化。
- Helm 部署:使用 Bitnami 官方 Chart
bitnami/zookeeper,通过 values.yaml 精确配置了 Ceph RBD StorageClass、副本数、资源限制和客户端认证,一条helm install完成部署。 - 登录验证:通过
zkCli.sh连接集群,使用zkServer.sh status确认 Leader/Follower 角色,用四字命令stat、ruok、mntr轻量级巡检。 - 日常巡检:提供了涵盖 Pod 状态、角色检查、日志排查、性能监控、容量巡检和故障恢复演练的完整脚本。
Zookeeper 作为分布式协调基石,其稳定运行直接影响依赖它的 Kafka、HBase 等中间件。在生产环境中,务必关注延迟指标(zk_avg_latency)、Watch 数量和磁盘使用,定期进行故障演练验证高可用切换。
下期预告
明天我们将进入 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检)。Elasticsearch 是最流行的分布式搜索与分析引擎,在日志聚合、全文检索、可观测性场景中广泛应用。我们将使用 Bitnami Chart 或官方 ECK Operator 部署 ES 集群,配置 Ceph RBD 持久化,讲解分片(Shard)、副本(Replica)的高可用设计。敬请期待!
系列目录
- 第 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 全景) 📅 即将发布

















暂无评论内容