Ceph+K8s 中间件实战 | 第 10 天:K8s 部署 Zookeeper 集群(分布式协调架构 + 运维命令)

第 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 持久化配置,以及登录验证与日常巡检命令。

K8s Logo

设计架构

组件拓扑

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)协议 保证数据一致性,数据流向如下:

  1. 客户端写入:客户端连接任意 Zookeeper 节点(Follower),发起写请求。
  2. 转发 Leader:若连接的是 Follower,写请求被转发至 Leader 节点。
  3. 生成事务 Proposal:Leader 为请求生成全局唯一递增的事务 ID(zxid),生成 Proposal。
  4. 广播投票:Leader 通过 ZAB 协议向所有 Follower 发送 Proposal,Follower 写入本地事务日志后回复 ACK。
  5. 半数确认提交:Leader 收到超过半数 ACK 后提交事务,并通知所有 Follower 提交。
  6. 响应客户端:最终写成功结果返回客户端。

数据持久化方面,每个事务先写入 事务日志(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 分配独立持久卷。

K8s Logo

登录验证

连接 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 上的完整部署:

  1. 架构设计:讲解了 ZAB 协议的数据流向、Leader 选举的高可用机制,以及 3 节点奇数集群的容灾能力。StatefulSet + Headless Service 提供稳定网络标识,Ceph RBD PVC 保证事务日志持久化。
  2. Helm 部署:使用 Bitnami 官方 Chart bitnami/zookeeper,通过 values.yaml 精确配置了 Ceph RBD StorageClass、副本数、资源限制和客户端认证,一条 helm install 完成部署。
  3. 登录验证:通过 zkCli.sh 连接集群,使用 zkServer.sh status 确认 Leader/Follower 角色,用四字命令 stat、ruok、mntr 轻量级巡检。
  4. 日常巡检:提供了涵盖 Pod 状态、角色检查、日志排查、性能监控、容量巡检和故障恢复演练的完整脚本。

Zookeeper 作为分布式协调基石,其稳定运行直接影响依赖它的 Kafka、HBase 等中间件。在生产环境中,务必关注延迟指标(zk_avg_latency)、Watch 数量和磁盘使用,定期进行故障演练验证高可用切换。

下期预告

明天我们将进入 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检)。Elasticsearch 是最流行的分布式搜索与分析引擎,在日志聚合、全文检索、可观测性场景中广泛应用。我们将使用 Bitnami Chart 或官方 ECK Operator 部署 ES 集群,配置 Ceph RBD 持久化,讲解分片(Shard)、副本(Replica)的高可用设计。敬请期待!

系列目录

  1. 第 1 天:Ceph 分布式存储回顾与 K8s 存储体系概述 ✅ 已发布
  2. 第 2 天:K8s 接入 Ceph RBD 块存储(CSI Driver + StorageClass 配置实战) ✅ 已发布
  3. 第 3 天:K8s 接入 CephFS 共享文件存储(多读场景与性能调优) ✅ 已发布
  4. 第 4 天:K8s 部署 MySQL 高可用集群(Ceph RBD 持久化 + 架构设计 + 登录巡检) ✅ 已发布
  5. 第 5 天:K8s 部署 Redis Cluster 集群(Ceph RBD + 架构设计 + 巡检命令) ✅ 已发布
  6. 第 6 天:K8s 部署 Redis Sentinel 哨兵模式(高可用架构 + 登录验证) ✅ 已发布
  7. 第 7 天:K8s 部署 MinIO 对象存储集群(分布式架构 + 运维巡检) ✅ 已发布
  8. 第 8 天:K8s 部署 MongoDB 副本集集群(Ceph RBD + 架构设计 + 登录) ✅ 已发布
  9. 第 9 天:K8s 部署 Nacos 注册配置中心(集群架构 + 登录巡检) ✅ 已发布
  10. 第 10 天:K8s 部署 Zookeeper 集群(分布式协调架构 + 运维命令) 📍 本文
  11. 第 11 天:K8s 部署 Elasticsearch 集群(Ceph RBD + 架构设计 + 巡检) 📅 即将发布
  12. 第 12 天:K8s 部署 Kafka 集群(Ceph RBD + 消息队列架构 + 运维) 📅 即将发布
  13. 第 13 天:K8s 部署 GitLab 代码托管平台(Ceph RBD 持久化 + 架构 + 巡检) 📅 即将发布
  14. 第 14 天:K8s 部署 ClickHouse 列式数据库集群(Ceph RBD + 架构设计) 📅 即将发布
  15. 第 15 天:K8s 中间件统一监控与运维巡检总结(Prometheus + Grafana 全景) 📅 即将发布
微信二维码
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发
头像 - 恒星
欢迎您留下宝贵的见解!
提交
头像 - 恒星

昵称

取消
昵称表情代码图片快捷回复

    暂无评论内容