Helm 部署高可用 Redis 集群部署记录
一、部署概述
本文档记录使用 Bitnami Redis Cluster Helm Chart 在 Kubernetes 集群中部署高可用 Redis 集群的完整过程,包括遇到的问题和解决方案。
部署架构
- 集群模式: Redis Cluster(3主3从)
- 节点数量: 6 个节点
- 外部访问: MetalLB LoadBalancer(固定 IP)
- 持久化: NFS 存储(5GB/节点)
- 命名空间: tools
二、前置准备
2.1 环境要求
# Kubernetes 集群版本
kubectl version --short
# Helm 版本(建议 3.x+)
helm version
# 确认 MetalLB 已部署并配置 IP 池
kubectl get pods -n metallb-system
2.2 准备工作
- 下载 Helm Chart
# 添加 Bitnami 仓库
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
# 下载指定版本的 Chart
helm pull bitnami/redis-cluster --version 13.0.4
- 创建命名空间
kubectl create namespace tools
- 确认存储类可用
# 查看可用的 StorageClass
kubectl get storageclass
# 本次部署使用 nfs-data-57
- 规划 LoadBalancer IP 地址
确保以下 IP 在 MetalLB IP 池范围内且未被占用:
- 192.168.120.150 # redis-cluster-0
- 192.168.120.151 # redis-cluster-1
- 192.168.120.152 # redis-cluster-2
- 192.168.120.153 # redis-cluster-3
- 192.168.120.154 # redis-cluster-4
- 192.168.120.155 # redis-cluster-5
三、配置文件详解
3.1 values.yaml 核心配置
创建 values.yaml 文件,关键配置说明:
global:
# 存储类配置(使用 NFS)
defaultStorageClass: "nfs-data-57"
storageClass: "nfs-data-57"
# Redis 全局密码
redis:
password: "passwd"
# Redis 节点配置
redis:
# 自定义 Redis 配置
configmap: |-
# 网络配置 - 允许外部访问
bind 0.0.0.0
protected-mode no
# 连接和内存配置
maxclients 32768
maxmemory 1gb
maxmemory-policy allkeys-lru
# AOF 持久化配置
appendonly yes
appendfsync everysec
aof-use-rdb-preamble yes
# 资源限制(每个 Pod)
resources:
limits:
cpu: 1000m
memory: 2Gi
requests:
cpu: 128m
memory: 512Mi
# 持久化存储配置
persistence:
enabled: true
size: 5Gi
# 集群配置
cluster:
nodes: 6 # 集群节点总数(3主3从)
replicas: 1 # 每个主节点的副本数
# 外部访问配置(关键配置)
externalAccess:
enabled: true
hostMode: false
service:
type: LoadBalancer
port: 6379
# ⚠️ 重要:必须配置 loadBalancerIP,否则 StatefulSet 不会创建!
# IP 数量必须等于 cluster.nodes 的值
loadBalancerIP:
- "192.168.120.150"
- "192.168.120.151"
- "192.168.120.152"
- "192.168.120.153"
- "192.168.120.154"
- "192.168.120.155"
3.2 配置要点说明
| 配置项 | 说明 | 注意事项 |
|---|---|---|
cluster.nodes |
集群节点总数 | 必须是偶数,建议 6 个(3主3从) |
cluster.replicas |
每个主节点的副本数 | 设置为 1 表示每个主节点有 1 个从节点 |
externalAccess.enabled |
启用外部访问 | 设置为 true 时必须配置 loadBalancerIP |
loadBalancerIP |
LoadBalancer IP 列表 | 必须配置,数量等于 nodes 值 |
persistence.size |
每个节点的存储大小 | 根据实际数据量规划 |
四、部署步骤
4.1 使用部署脚本
创建 deploy.sh 脚本:
#!/bin/bash
echo "开始部署 Redis Cluster 到 tools 命名空间..."
# 1. 创建命名空间(如果不存在)
echo "1. 创建 tools 命名空间..."
kubectl create namespace tools --dry-run=client -o yaml | kubectl apply -f -
# 2. 部署 Redis Cluster
echo "2. 部署 Redis Cluster Helm Chart..."
helm install dyck-redis-cluster ../redis-cluster-13.0.4.tgz \
-f values.yaml \
-n tools
echo "部署完成!"
执行部署:
# 赋予执行权限
chmod +x deploy.sh
# 执行部署
./deploy.sh
4.2 手动部署命令
# 部署 Redis Cluster
helm install dyck-redis-cluster ../redis-cluster-13.0.4.tgz \
-f values.yaml \
-n tools
# 查看部署状态
helm list -n tools
五、部署验证
5.1 检查资源创建
# 1. 检查 Helm Release
helm list -n tools
# 2. 检查 StatefulSet(应该有 1 个)
kubectl get sts -n tools
# 3. 检查 Pod(应该有 6 个)
kubectl get pods -n tools -o wide
# 4. 检查 Service(应该有 7 个:1 个 headless + 6 个 LoadBalancer)
kubectl get svc -n tools
# 5. 检查 PVC(应该有 6 个)
kubectl get pvc -n tools
5.2 预期输出示例
[root@host51 ~]# # 2. 检查 StatefulSet(应该有 1 个)
[root@host51 ~]# kubectl get sts -n tools
NAME READY AGE
dyck-redis-cluster 6/6 11h
nacos 2/2 133d
[root@host51 ~]#
[root@host51 ~]# # 3. 检查 Pod(应该有 6 个)
[root@host51 ~]# kubectl get pods -n tools -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
dyck-redis-cluster-0 1/1 Running 0 11h 10.244.116.5 host52 <none> <none>
dyck-redis-cluster-1 1/1 Running 0 11h 10.244.109.19 host54 <none> <none>
dyck-redis-cluster-2 1/1 Running 0 11h 10.244.48.95 host55 <none> <none>
dyck-redis-cluster-3 1/1 Running 0 11h 10.244.212.167 host56 <none> <none>
dyck-redis-cluster-4 1/1 Running 0 11h 10.244.114.169 host53 <none> <none>
dyck-redis-cluster-5 1/1 Running 0 11h 10.244.128.224 host51 <none> <none>
nacos-0 1/1 Running 0 4d20h 10.244.114.148 host53 <none> <none>
nacos-1 1/1 Running 0 4d20h 10.244.128.232 host51 <none> <none>
prometheus-alert-center-66755c7cf-nkdzm 1/1 Running 2 (39d ago) 82d 10.244.109.0 host54 <none> <none>
redis-77cc5f649c-8vqc4 1/1 Running 4 (7d23h ago) 7d23h 10.244.128.241 host51 <none> <none>
[root@host51 ~]#
[root@host51 ~]# # 4. 检查 Service(应该有 7 个:1 个 headless + 6 个 LoadBalancer)
[root@host51 ~]# kubectl get svc -n tools
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
dyck-redis-cluster ClusterIP 10.96.86.225 <none> 6379/TCP 11h
dyck-redis-cluster-0-svc LoadBalancer 10.96.145.235 192.168.120.150 6379:30771/TCP,16379:31838/TCP 11h
dyck-redis-cluster-1-svc LoadBalancer 10.96.237.165 192.168.120.151 6379:30141/TCP,16379:32504/TCP 11h
dyck-redis-cluster-2-svc LoadBalancer 10.96.233.167 192.168.120.152 6379:32419/TCP,16379:32699/TCP 11h
dyck-redis-cluster-3-svc LoadBalancer 10.96.170.166 192.168.120.153 6379:31859/TCP,16379:30576/TCP 11h
dyck-redis-cluster-4-svc LoadBalancer 10.96.191.115 192.168.120.154 6379:31484/TCP,16379:31910/TCP 11h
dyck-redis-cluster-5-svc LoadBalancer 10.96.196.102 192.168.120.155 6379:32656/TCP,16379:32307/TCP 11h
dyck-redis-cluster-headless ClusterIP None <none> 6379/TCP,16379/TCP 11h
nacos-headless ClusterIP None <none> 8848/TCP,9848/TCP,9849/TCP,7848/TCP 145d
nacos-svc ClusterIP 10.96.4.74 <none> 8848/TCP,9848/TCP,9849/TCP,7848/TCP,8080/TCP 145d
nacos-svc-nodeport NodePort 10.96.87.218 <none> 8848:30848/TCP 145d
prometheus-alert-center ClusterIP 10.96.198.62 <none> 8080/TCP 203d
redis-svc NodePort 10.96.211.196 <none> 6379:30301/TCP 118d
[root@host51 ~]#
[root@host51 ~]# # 5. 检查 PVC(应该有 6 个)
[root@host51 ~]# kubectl get pvc -n tools
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
nacos-data-nacos-0 Bound pvc-32e6797c-8387-4cd2-b1a7-21837550d88c 5Gi RWO nfs-data-57 133d
nacos-data-nacos-1 Bound pvc-348bfdba-6a28-4981-a5df-61594efb86a7 5Gi RWO nfs-data-57 133d
prometheus-alert-center-db-pvc Bound pvc-6b9ffe0f-f399-4d2d-ae5b-7591b5d3a1a4 5Gi RWO nfs-data-57 133d
redis-data-dyck-redis-cluster-0 Bound pvc-52d631a9-f0f4-4306-9f8e-d7a73767aca2 5Gi RWO nfs-data-57 11h
redis-data-dyck-redis-cluster-1 Bound pvc-7b3c1c48-0431-47e4-8a4c-b63ef8575e17 5Gi RWO nfs-data-57 11h
redis-data-dyck-redis-cluster-2 Bound pvc-d5631b17-b698-4ad1-912b-d8fb33399c53 5Gi RWO nfs-data-57 11h
redis-data-dyck-redis-cluster-3 Bound pvc-6d6a87df-3fe1-4a39-bef9-92c91745e174 5Gi RWO nfs-data-57 11h
redis-data-dyck-redis-cluster-4 Bound pvc-af63fd86-0f6c-44af-9c20-2f2a25b90a12 5Gi RWO nfs-data-57 11h
redis-data-dyck-redis-cluster-5 Bound pvc-b5048cee-49b0-44b3-966b-ff52f834db3f 5Gi RWO nfs-data-57 11h
redis-pvc Bound pvc-46dcd933-b328-4f81-8080-f4be6031cb30 5Gi RWO k8s-data 117d
5.3 查看 Pod 日志
# 查看第一个节点的日志
kubectl logs -f dyck-redis-cluster-0 -n tools
# 查看集群初始化日志
kubectl logs -f dyck-redis-cluster-0 -n tools | grep -i cluster
六、功能测试
6.1 集群内部连接测试
# 进入任意 Pod
kubectl exec -it dyck-redis-cluster-0 -n tools -- bash
# 连接 Redis(使用密码)
redis-cli -a passwd
# 查看集群信息
cluster info
cluster nodes
# 测试写入数据
set test-key "hello redis cluster"
get test-key
# 退出
exit
6.2 外部连接测试
使用 redis-cli 从集群外部连接:
# 连接到任意节点(使用 LoadBalancer IP)
redis-cli -h 192.168.120.150 -p 6379 -a passwd -c
# 查看集群状态
cluster info
# 测试数据读写
set external-test "connected from outside"
get external-test
# 查看节点信息
cluster nodes
6.3 集群性能测试
# 使用 redis-benchmark 进行性能测试
redis-benchmark -h 192.168.120.150 -p 6379 -a passwd \
-c 50 -n 10000 -d 100 --cluster
# 参数说明:
# -c 50: 50 个并发连接
# -n 10000: 10000 个请求
# -d 100: 数据大小 100 字节
# --cluster: 集群模式
七、常见问题与解决方案
7.1 StatefulSet 未创建问题
问题现象:
– Helm Release 部署成功
– Service 已创建并分配 IP
– 但 StatefulSet 未创建,没有 Pod 启动
根本原因:
查看 Helm Chart 源码 templates/_helpers.tpl 中的 createStatefulSet 函数:
{{- define "redis-cluster.createStatefulSet" -}}
{{- if not .Values.cluster.externalAccess.enabled -}}
{{- true -}}
{{- end -}}
{{- if and .Values.cluster.externalAccess.enabled .Values.cluster.externalAccess.service.loadBalancerIP -}}
{{- true -}}
{{- end -}}
{{- end -}}
StatefulSet 创建条件:
1. externalAccess.enabled = false 时,创建 StatefulSet
2. externalAccess.enabled = true 且 loadBalancerIP 有值时,创建 StatefulSet
错误配置示例:
cluster:
externalAccess:
enabled: true
service:
loadBalancerIP: "" # ❌ 空值导致 StatefulSet 不创建!
正确配置:
cluster:
externalAccess:
enabled: true
service:
loadBalancerIP: # ✅ 必须配置 IP 数组
- "192.168.120.150"
- "192.168.120.151"
- "192.168.120.152"
- "192.168.120.153"
- "192.168.120.154"
- "192.168.120.155"
解决步骤:
# 1. 卸载现有部署
helm uninstall dyck-redis-cluster -n tools
# 2. 修改 values.yaml,添加 loadBalancerIP 配置
# 3. 重新部署
helm install dyck-redis-cluster ../redis-cluster-13.0.4.tgz \
-f values.yaml \
-n tools
# 4. 验证 StatefulSet 创建
kubectl get sts -n tools
kubectl get pods -n tools
7.2 Pod 启动失败
问题排查:
# 查看 Pod 状态
kubectl get pods -n tools
# 查看 Pod 详细信息
kubectl describe pod dyck-redis-cluster-0 -n tools
# 查看 Pod 日志
kubectl logs dyck-redis-cluster-0 -n tools
常见原因:
1. 存储类不可用或 PVC 创建失败
2. 资源限制不足(CPU/内存)
3. 镜像拉取失败
4. 配置文件语法错误
7.3 LoadBalancer IP 未分配
问题排查:
# 查看 Service 状态
kubectl get svc -n tools
# 查看 Service 详细信息
kubectl describe svc dyck-redis-cluster-0-external -n tools
# 查看 MetalLB 日志
kubectl logs -n metallb-system -l app=metallb
常见原因:
1. MetalLB 未正确部署
2. IP 地址不在 MetalLB IP 池范围内
3. IP 地址已被其他服务占用
7.4 集群节点无法通信
问题排查:
# 进入 Pod 检查网络
kubectl exec -it dyck-redis-cluster-0 -n tools -- bash
# 测试节点间连通性
redis-cli -a passwd cluster nodes
# 检查防火墙规则
# Redis Cluster 需要开放 6379 和 16379 端口
八、运维管理
8.1 查看集群状态
# 查看集群信息
kubectl exec -it dyck-redis-cluster-0 -n tools -- \
redis-cli -a passwd cluster info
# 查看节点信息
kubectl exec -it dyck-redis-cluster-0 -n tools -- \
redis-cli -a passwd cluster nodes
# 查看槽位分配
kubectl exec -it dyck-redis-cluster-0 -n tools -- \
redis-cli -a passwd cluster slots
8.2 扩容集群
# 修改 values.yaml 中的 nodes 值
# 例如从 6 增加到 9(3主3从 -> 3主6从)
# 升级 Helm Release
helm upgrade dyck-redis-cluster ../redis-cluster-13.0.4.tgz \
-f values.yaml \
-n tools
# 验证新节点加入
kubectl get pods -n tools
8.3 备份与恢复
# 备份 Redis 数据(使用 RDB)
kubectl exec -it dyck-redis-cluster-0 -n tools -- \
redis-cli -a passwd bgsave
# 查看备份状态
kubectl exec -it dyck-redis-cluster-0 -n tools -- \
redis-cli -a passwd lastsave
# 备份 PVC 数据(推荐)
# 使用 Velero 或其他备份工具备份 PVC
8.4 卸载集群
# 卸载 Helm Release
helm uninstall dyck-redis-cluster -n tools
# 删除 PVC(可选,会删除数据)
kubectl delete pvc -n tools -l app.kubernetes.io/instance=dyck-redis-cluster
# 删除命名空间(可选)
kubectl delete namespace tools
九、性能优化建议
9.1 资源配置优化
redis:
resources:
limits:
cpu: 2000m # 根据实际负载调整
memory: 4Gi # 建议 maxmemory 的 2 倍
requests:
cpu: 500m
memory: 1Gi
9.2 持久化策略优化
redis:
configmap: |-
# 高性能场景:仅使用 AOF
appendonly yes
appendfsync everysec
# 高可靠场景:AOF + RDB 混合
aof-use-rdb-preamble yes
save 900 1
save 300 10
save 60 10000
9.3 网络优化
redis:
configmap: |-
# 增加 TCP backlog
tcp-backlog 511
# 调整超时时间
timeout 300
tcp-keepalive 300
十、监控与告警
10.1 启用 Prometheus 监控
metrics:
enabled: true
serviceMonitor:
enabled: true
namespace: monitoring
10.2 关键监控指标
- 集群状态:
cluster_state - 节点数量:
cluster_size - 内存使用:
used_memory - 连接数:
connected_clients - 命令执行速率:
instantaneous_ops_per_sec - 键空间命中率:
keyspace_hits / (keyspace_hits + keyspace_misses)