Kubernetes Redis 7.2 集群部署:NFS存储+StatefulSet 6节点配置详解
·
Kubernetes Redis 7.2 集群部署:NFS存储+StatefulSet 6节点配置详解
Redis作为高性能的内存数据库,在分布式系统中扮演着关键角色。本文将深入探讨如何在Kubernetes环境中,利用StatefulSet和NFS存储部署一个高可用的Redis 7.2集群(3主3从架构)。不同于传统手动配置方式,我们将采用Kubernetes原生资源实现自动化部署和管理,显著提升运维效率。
1. 架构设计与核心组件
在Kubernetes中部署Redis集群需要考虑以下几个关键因素:
- 数据持久化 :Redis作为有状态服务,需要确保数据在Pod重启或迁移时不丢失
- 服务发现 :集群节点需要能够相互发现并建立连接
- 高可用性 :主从节点应分布在不同的物理节点上
- 自动化运维 :包括集群初始化、故障恢复等操作
我们选择的解决方案组合如下:
| 组件 | 用途 | 优势 |
|---|---|---|
| StatefulSet | 管理Redis Pod | 提供稳定的网络标识和有序部署 |
| NFS StorageClass | 动态提供持久化存储 | 支持多节点读写,简化PV管理 |
| Headless Service | 内部DNS发现 | 为每个Pod提供唯一域名 |
| ClusterIP Service | 外部访问入口 | 统一访问入口,负载均衡 |
| Init Job | 自动初始化集群 | 替代手动执行redis-cli命令 |
关键配置要点 :
- 每个Redis Pod独占一个PV,确保数据隔离
- 通过Pod反亲和性(Anti-Affinity)分散主节点
- 使用ConfigMap统一管理Redis配置文件
- 通过Job自动完成集群节点握手和槽位分配
2. 环境准备与NFS配置
2.1 NFS服务器设置
首先在任意节点(可以是K8s集群外)部署NFS服务:
# 安装NFS服务端
sudo apt-get install nfs-kernel-server -y
# 创建共享目录
sudo mkdir -p /nfs/redis
sudo chmod -R 777 /nfs/redis
# 配置导出目录
echo "/nfs/redis *(rw,sync,no_subtree_check,no_root_squash)" | sudo tee -a /etc/exports
# 应用配置
sudo exportfs -ra
sudo systemctl restart nfs-kernel-server
2.2 Kubernetes端NFS配置
在Kubernetes集群中创建StorageClass,实现动态PV供给:
# nfs-storageclass.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: redis-nfs-sc
provisioner: example.com/nfs
parameters:
archiveOnDelete: "false"
mountOptions:
- hard
- nfsvers=4.1
提示:如果使用云服务商的托管Kubernetes,建议使用对应的CSI驱动(如AWS EFS CSI)替代原生NFS
3. Redis集群核心配置
3.1 ConfigMap配置
创建包含Redis配置和初始化脚本的ConfigMap:
# redis-configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: redis-cluster-config
data:
redis.conf: |
cluster-enabled yes
cluster-require-full-coverage no
cluster-node-timeout 15000
cluster-config-file /data/nodes.conf
cluster-migration-barrier 1
appendonly yes
protected-mode no
port 6379
dir /data
update-node.sh: |
#!/bin/sh
REDIS_NODES="/data/nodes.conf"
if [ -f "${REDIS_NODES}" ]; then
sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${POD_IP}/" ${REDIS_NODES}
fi
exec "$@"
3.2 StatefulSet配置
这是最核心的部署文件,实现了6节点Redis集群:
# redis-statefulset.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: redis-cluster
spec:
serviceName: redis-cluster
replicas: 6
selector:
matchLabels:
app: redis-cluster
template:
metadata:
labels:
app: redis-cluster
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- redis-cluster
topologyKey: kubernetes.io/hostname
containers:
- name: redis
image: redis:7.2-alpine
command: ["/conf/update-node.sh", "redis-server", "/conf/redis.conf"]
ports:
- containerPort: 6379
name: client
- containerPort: 16379
name: gossip
env:
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
volumeMounts:
- name: conf
mountPath: /conf
readOnly: false
- name: data
mountPath: /data
readOnly: false
volumes:
- name: conf
configMap:
name: redis-cluster-config
defaultMode: 0755
volumeClaimTemplates:
- metadata:
name: data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: redis-nfs-sc
resources:
requests:
storage: 5Gi
关键参数解析 :
-
podAntiAffinity:确保Redis Pod分散在不同节点 -
update-node.sh:动态更新节点配置文件中的IP地址 -
volumeClaimTemplates:为每个Pod自动创建PVC
3.3 服务配置
创建两种Service分别用于集群内部通信和外部访问:
# redis-services.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-cluster
spec:
clusterIP: None
ports:
- port: 6379
targetPort: 6379
name: client
- port: 16379
targetPort: 16379
name: gossip
selector:
app: redis-cluster
---
apiVersion: v1
kind: Service
metadata:
name: redis-access
spec:
type: ClusterIP
ports:
- port: 6379
targetPort: 6379
selector:
app: redis-cluster
4. 集群初始化与验证
4.1 自动初始化Job
传统方式需要手动执行redis-cli命令初始化集群,我们通过Job实现自动化:
# redis-init-job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: redis-cluster-init
spec:
template:
spec:
containers:
- name: cluster-init
image: redis:7.2-alpine
command:
- sh
- -c
- |
sleep 10
redis-cli --cluster create \
redis-cluster-0.redis-cluster:6379 \
redis-cluster-1.redis-cluster:6379 \
redis-cluster-2.redis-cluster:6379 \
redis-cluster-3.redis-cluster:6379 \
redis-cluster-4.redis-cluster:6379 \
redis-cluster-5.redis-cluster:6379 \
--cluster-replicas 1 --cluster-yes
restartPolicy: OnFailure
4.2 部署流程
按顺序应用所有配置文件:
kubectl apply -f nfs-storageclass.yaml
kubectl apply -f redis-configmap.yaml
kubectl apply -f redis-services.yaml
kubectl apply -f redis-statefulset.yaml
# 等待所有Pod就绪
kubectl wait --for=condition=Ready pod -l app=redis-cluster --timeout=300s
# 初始化集群
kubectl apply -f redis-init-job.yaml
4.3 集群验证
检查集群状态:
# 查看Pod运行状态
kubectl get pods -l app=redis-cluster -o wide
# 检查集群节点关系
kubectl exec redis-cluster-0 -- redis-cli cluster nodes
# 测试数据读写
kubectl exec -it redis-cluster-0 -- redis-cli set test-key "hello"
kubectl exec -it redis-cluster-1 -- redis-cli get test-key
5. 高级配置与优化
5.1 资源限制与探针
在生产环境中,应为Redis容器配置资源限制和健康检查:
resources:
limits:
cpu: "2"
memory: "4Gi"
requests:
cpu: "1"
memory: "2Gi"
livenessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
exec:
command:
- redis-cli
- ping
initialDelaySeconds: 5
periodSeconds: 10
5.2 密码认证
增强安全性可启用Redis密码认证:
# 在ConfigMap的redis.conf中添加
requirepass your-strong-password
masterauth your-strong-password
# 初始化Job需要相应修改
redis-cli --cluster create ... -a your-strong-password
5.3 监控与告警
建议配置Prometheus监控Redis集群:
# 添加Annotations暴露指标
annotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9121"
6. 故障排查与维护
6.1 常见问题处理
节点无法加入集群 :
- 检查Pod间网络连通性
- 验证DNS解析是否正常
-
查看Redis日志:
kubectl logs <pod-name>
数据持久化问题 :
-
检查PVC/PV状态:
kubectl get pvc,pv - 验证NFS服务器连接和权限
- 检查存储空间使用情况
6.2 集群扩容
横向扩展Redis集群(从6节点扩展到9节点):
# 扩展StatefulSet
kubectl scale statefulset redis-cluster --replicas=9
# 添加新节点到集群
kubectl exec redis-cluster-0 -- redis-cli --cluster add-node \
redis-cluster-6.redis-cluster:6379 \
redis-cluster-0.redis-cluster:6379
6.3 备份与恢复
建议的备份策略:
- 定期对NFS存储进行快照
- 使用Redis的BGSAVE命令创建RDB备份
-
通过
redis-cli --cluster backup命令导出集群数据
# 示例备份命令
kubectl exec redis-cluster-0 -- redis-cli bgsave
更多推荐


所有评论(0)