当前位置: 首页 > news >正文

k8s运维实践:高可用Redis Cluster(三主三从)与Proxy部署方案

k8s运维实践:高可用Redis Cluster(三主三从)与Proxy部署方案

文章目录

  • k8s运维实践:高可用Redis Cluster(三主三从)与Proxy部署方案
  • 一、Redis Cluster与Proxy简介
  • 二、Redis Cluster实战部署
    • 1. 创建Namespace(redis-cluster-namespace.yaml)
    • 2. 创建ConfigMap(redis-cluster-config.yaml)
    • 3. 创建Service(redis-cluster-svc.yaml)
    • 4. 创建StatefulSet(redis-cluster-statefulset.yaml)
    • 5. 创建 Job(init-cluster-job.yaml)
    • 6. 部署所有资源
  • 三、验证Redis Cluster部署
    • 1. 验证Pod状态
    • 2. 验证集群初始化
    • 3. 验证基础功能
  • 四、Redis Cluster Proxy实战部署
    • 1. Redis Proxy 的价值
    • 2. 创建Redis Cluster Proxy(redis-cluster-proxy-deploy.yaml)
    • 3. 部署资源
  • 五、验证Redis Cluster Proxy部署
    • 1. 验证Pod状态
    • 2. 验证Proxy路由
  • 总结


随着容器化和微服务架构的普及,系统架构日益复杂,传统的单机数据库部署模式已难以满足高可用和高性能的需求。Redis Cluster 通过分片与主从复制机制,实现了数据的水平扩展与高可用性,而 Redis Proxy 则可以为集群客户端提供统一访问入口,简化应用侧的集群访问逻辑。

在本系列中,我们将围绕 Redis Cluster 在 Kubernetes 中的部署与实践展开介绍。本篇将聚焦于在 Kubernetes 上部署 Redis Cluster,并配置 Redis Cluster Proxy,实现对多节点 Redis 集群的统一访问,为后续的高可用运维、性能调优和集群监控打下基础。

一、Redis Cluster与Proxy简介

Redis Cluster 通过 分片(Sharding)主从复制(Replication) 来实现高可用与水平扩展。整个集群被划分为 16384 个槽位(slots),每个节点负责其中一部分槽位,客户端根据 key 的哈希值自动路由到对应节点。为了保证高可用,每个主节点(Master)通常配有一个或多个从节点(Replica),在主节点故障时从节点可自动提升为新的主节点。
Redis Cluster Proxy 就是“应用与 Redis Cluster 之间的适配层”,让应用像使用单机 Redis 一样去访问分布式 Redis 集群,可以极大简化开发和运维工作。
在 Kubernetes 环境下,Redis Cluster + Proxy 的组合不仅能满足 高可用(HA)可扩展性 的需求,还能简化应用侧的访问逻辑,是容器化环境下 Redis 的主流部署方式。

二、Redis Cluster实战部署

1. 创建Namespace(redis-cluster-namespace.yaml)

创建名为redis-cluster的命名空间,用于隔离部署 Redis 集群及相关组件的资源

apiVersion: v1
kind: Namespace
metadata:name: redis-cluster

2. 创建ConfigMap(redis-cluster-config.yaml)

定义 Redis Cluster 的配置文件,用于设置节点端口、集群模式、持久化方式、最大内存策略等核心参数,确保集群能够在 Kubernetes 环境下稳定运行

apiVersion: v1
kind: ConfigMap
metadata:name: redis-confignamespace: redis-cluster
data:redis.conf: |port 6379requirepass Hwj123masterauth Hwj123# 开启cluster 模式cluster-enabled yes# 指定 cluster 配置文件(自动生成)cluster-config-file nodes.conf# 节点超时时间cluster-node-timeout 5000appendonly yesappendfilename "appendonly.aof"appendfsync everysecrdbcompression yesdir /dataloglevel noticelogfile ""protected-mode no

3. 创建Service(redis-cluster-svc.yaml)

在 Redis Cluster 中通常需要两类 Service:

  • Headless Service (redis-headless):通过 clusterIP: None 实现无头服务,主要用于 StatefulSet 中的 Pod 之间进行集群节点发现和内部通信。
  • 访问 Service (redis-access):通过 NodePort 暴露 Redis 端口(6379),方便外部客户端直接访问集群。
apiVersion: v1
kind: Service
metadata:name: redis-headlessnamespace: redis-cluster
spec:clusterIP: Noneselector:app: redisports:- port: 6379
---
apiVersion: v1
kind: Service
metadata:name: redis-accessnamespace: redis-cluster
spec:type: NodePortselector:app: redisports:- port: 6379          # Pod 内部端口targetPort: 6379    # Pod 容器端口nodePort: 30079     # 指定 NodePort

4. 创建StatefulSet(redis-cluster-statefulset.yaml)

部署 Redis Cluster 节点,使用 StatefulSet 确保每个 Pod 都有固定的网络标识和持久化存储。该配置共创建 6 个副本,每个 Pod 挂载持久化卷存储数据,并通过 ConfigMap 加载 redis.conf 配置文件。结合前面创建的 Headless Service,可以实现集群节点间的自动发现与通信

apiVersion: apps/v1
kind: StatefulSet
metadata:name: redisnamespace: redis-cluster
spec:serviceName: redis-headless  # 绑定的无头服务(用于稳定的 DNS 解析)replicas: 6  # 6个副本(用于3主3从)selector:matchLabels:app: redistemplate:metadata:labels:app: redisspec:affinity:nodeAffinity:  # 节点亲和性requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: "kubernetes.io/hostname"operator: "NotIn"values:- "k8s-node-4-gpu"containers:- name: redisimage: harbor.local/k8s/redis:7.2command: [ "redis-server", "/usr/local/etc/redis/redis.conf" ]ports:- containerPort: 6379volumeMounts:- name: datamountPath: /data- name: configmountPath: /usr/local/etc/redis/redis.confsubPath: redis.confvolumes:- name: configconfigMap:name: redis-configvolumeClaimTemplates:- metadata:name: dataspec:accessModes: [ "ReadWriteOnce" ]storageClassName: nfs-storage  # 使用的存储类(NFS)resources:requests:storage: 1Gi

5. 创建 Job(init-cluster-job.yaml)

在 Redis Cluster 所有 Pod 启动完成后,需要执行初始化操作将各节点组建为一个完整的集群。这里通过 Kubernetes 的 Job 来完成初始化任务:

  • 等待 Redis Pod 就绪后,调用 redis-cli --cluster create 命令。
  • 将 6 个节点自动组建为 Redis Cluster,并设置副本数(--cluster-replicas 1)。
  • 使用 --cluster-yes 自动确认集群创建过程,避免交互式输入。

该 Job 只需在集群初始化时执行一次,执行完成后会自动退出。

apiVersion: batch/v1
kind: Job
metadata:name: redis-init-clusternamespace: redis-cluster
spec:template:spec:containers:- name: redis-initimage: harbor.local/k8s/redis:7.2command:- sh- -c- |echo "Waiting for Redis pods to be ready...";sleep 10;redis-cli --cluster create \redis-0.redis-headless.redis-cluster.svc.cluster.local:6379 \redis-1.redis-headless.redis-cluster.svc.cluster.local:6379 \redis-2.redis-headless.redis-cluster.svc.cluster.local:6379 \redis-3.redis-headless.redis-cluster.svc.cluster.local:6379 \redis-4.redis-headless.redis-cluster.svc.cluster.local:6379 \redis-5.redis-headless.redis-cluster.svc.cluster.local:6379 \--cluster-replicas 1 -a Hwj123 --cluster-yesrestartPolicy: OnFailure

6. 部署所有资源

kubectl apply -f redis-cluster-namespace.yaml
kubectl apply -f redis-cluster-config.yaml
kubectl apply -f redis-cluster-svc.yaml
kubectl apply -f redis-cluster-statefulset.yaml
kubectl apply -f init-cluster-job.yaml

三、验证Redis Cluster部署

1. 验证Pod状态

kubectl get pod -n redis-cluster -owide

在这里插入图片描述

2. 验证集群初始化

kubectl logs -f -n redis-cluster redis-init-cluster-zl7qr

在这里插入图片描述

3. 验证基础功能

kubectl exec -it -n redis-cluster redis-0 -- /bin/bashroot@redis-0:/data# redis-cli -c
127.0.0.1:6379> auth Hwj123
OK
127.0.0.1:6379> client list
id=20 addr=10.100.3.165:37282 laddr=10.100.3.163:6379 fd=28 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=21 addr=10.100.3.165:37292 laddr=10.100.3.163:6379 fd=29 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=22 addr=10.100.3.165:37298 laddr=10.100.3.163:6379 fd=30 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=5 addr=10.100.2.219:52984 laddr=10.100.3.163:6379 fd=23 name= age=82790 idle=0 flags=S db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=20474 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=1 omem=20504 tot-mem=42904 events=r cmd=replconf user=default redir=-1 resp=2 lib-name= lib-ver=
id=15 addr=10.100.3.165:37234 laddr=10.100.3.163:6379 fd=12 name= age=81214 idle=575 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=scan user=default redir=-1 resp=2 lib-name= lib-ver=
id=16 addr=10.100.3.165:37244 laddr=10.100.3.163:6379 fd=24 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=17 addr=10.100.3.165:37258 laddr=10.100.3.163:6379 fd=25 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=18 addr=10.100.3.165:37262 laddr=10.100.3.163:6379 fd=26 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=19 addr=10.100.3.165:37278 laddr=10.100.3.163:6379 fd=27 name= age=81214 idle=81214 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=0 qbuf-free=0 argv-mem=0 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=1928 events=r cmd=cluster|nodes user=default redir=-1 resp=2 lib-name= lib-ver=
id=24 addr=127.0.0.1:49596 laddr=127.0.0.1:6379 fd=31 name= age=8 idle=0 flags=N db=0 sub=0 psub=0 ssub=0 multi=-1 qbuf=26 qbuf-free=20448 argv-mem=10 multi-mem=0 rbs=1024 rbp=0 obl=0 oll=0 omem=0 tot-mem=22426 events=r cmd=client|list user=default redir=-1 resp=2 lib-name= lib-ver=
127.0.0.1:6379> set aa bb
OK
127.0.0.1:6379> get aa
"bb"

在这里插入图片描述

四、Redis Cluster Proxy实战部署

在前面的步骤中,我们已经成功在 Kubernetes 上部署了 Redis Cluster,并通过 StatefulSet 管理多个节点。虽然集群具备了高可用和水平扩展能力,但在应用侧访问 Redis Cluster时,仍然会遇到以下问题:

1. 客户端需要感知集群拓扑

  • Redis Cluster 是基于 16384 个槽位(slot)分片的,每个 key 会被映射到不同节点
  • 如果客户端直接连接单个节点,就会遇到 MOVEDASK 重定向,需要自己实现转发逻辑
  • 这要求应用必须使用支持 Redis Cluster 协议的客户端,否则访问很麻烦

2. 节点扩缩容时拓扑会变化

  • 当我们对 Redis Cluster 进行扩容或缩容时,槽位会被重新分配
  • 客户端必须实时刷新集群拓扑信息,否则可能访问失败
  • 在大规模微服务系统中,这会显著增加客户端的复杂度和出错风险

3. 无法直接使用 NodePort/LoadBalancer 简化访问

  • Redis Cluster 是多节点分布式的,单一 Service 并不能屏蔽集群的分片机制
  • 客户端即使通过 NodePort 连接,也还是会遇到 MOVED,无法像访问单机 Redis 那样简单

1. Redis Proxy 的价值

Redis Cluster Proxy 的出现,正是为了解决这些痛点:

  • 统一入口:对外暴露一个 统一 的地址(如 redis-proxy:7777),应用端像访问单机 Redis 一样使用,无需关心槽位
  • 自动路由:Proxy 会解析请求的 key,找到对应的节点并转发请求,屏蔽集群内部的复杂性
  • 拓扑变化无感:当集群扩缩容时,Proxy 会自动感知并更新路由表,应用侧无需改动
  • 简化应用开发:应用可以使用任何标准的 Redis 客户端(即使不支持 cluster 模式),也能无障碍访问集群

2. 创建Redis Cluster Proxy(redis-cluster-proxy-deploy.yaml)

这里我们通过 Deployment 部署 Redis Cluster Proxy,并通过 Service 将其对外暴露:

  • 启动一个 Proxy 实例(可根据需求水平扩展)
  • 在容器启动参数中配置认证密码(–auth)和 Redis Cluster 节点地址,Proxy 会自动从指定节点获取集群拓扑信息
  • 暴露 Proxy 的端口(7777),这里采用 NodePort 方式对外提供访问,也可以根据环境换成 LoadBalancer 或 Ingress
  • 应用只需连接 Proxy 的统一入口(如 NodeIP:30090),即可透明访问整个 Redis Cluster,无需关心集群拓扑与槽位分布
apiVersion: apps/v1
kind: Deployment
metadata:name: redis-cluster-proxynamespace: redis-cluster
spec:replicas: 1selector:matchLabels:app: redis-cluster-proxytemplate:metadata:labels:app: redis-cluster-proxyspec:affinity:nodeAffinity:requiredDuringSchedulingIgnoredDuringExecution:nodeSelectorTerms:- matchExpressions:- key: "kubernetes.io/hostname"operator: "NotIn"values:- "k8s-node-4-gpu"containers:- name: redis-cluster-proxy# 官方镜像地址:ableuler/redis-cluster-proxy:latestimage: harbor.local/k8s/redis-cluster-proxy:latest  command: ["redis-cluster-proxy"]   # 显式指定启动命令# 入口配置,Proxy 会自动发现并代理整个 Redis Clusterargs:- "--auth"- "Hwj123"- "redis-0.redis-headless.redis-cluster.svc.cluster.local:6379"- "redis-1.redis-readless.redis-cluster.svc.cluster.local:6379"- "redis-2.redis-readless.redis-cluster.svc.cluster.local:6379"ports:- containerPort: 7777
---
apiVersion: v1
kind: Service
metadata:name: redis-proxynamespace: redis-cluster
spec:type: NodePort   # 你也可以换成 LoadBalancer/Ingressselector:app: redis-cluster-proxyports:- port: 7777targetPort: 7777nodePort: 30090   # 对外暴露的端口

3. 部署资源

kubectl apply -f redis-cluster-proxy-deploy.yaml

五、验证Redis Cluster Proxy部署

1. 验证Pod状态

kubectl get pod -n redis-cluster
kubectl get svc -n redis-cluster

在这里插入图片描述
在这里插入图片描述

2. 验证Proxy路由

这里我们做个测试,通过客户端工具连接到 Redis Cluster Proxy,执行简单的读写操作(如 SET / GET),以验证 Proxy 的透明访问能力,随后我们进入 redis-0 Pod 查看该 key,可以看到数据实际被分配到 redis-2 Pod 上。经验证,Proxy 成功完成了请求转发与路由
在这里插入图片描述
在这里插入图片描述


总结

🚀 本文介绍了如何在 Kubernetes 集群中部署 Redis Cluster,并通过 StatefulSet、Headless Service、ConfigMap、Job 等资源完成集群的搭建与初始化。随后引入 Redis Cluster Proxy,解决了原生集群客户端需要感知槽位迁移的问题,使应用能够像使用单节点 Redis 一样透明访问集群。

http://www.dtcms.com/a/340062.html

相关文章:

  • 使用 Docker 安装长安链管理平台 + 部署区块链与示例合约
  • daily notes[3]
  • Eigen中Dense 模块简要介绍和实战应用示例(最小二乘拟合直线、协方差矩阵计算和稀疏求解等)
  • 三极管驱动led灯搭配的电阻选取方法
  • 跟随广州AI导游深度探寻广州历史底蕴​
  • 如何做一次AIMD
  • 农田扫描提速37%!基于检测置信度的无人机“智能抽查”路径规划,Coovally一键加速模型落地
  • [OWASP]智能体应用安全保障指南
  • 英伟达显卡驱动怎么更新 详细步骤教程
  • MySQL练习题50题(附带详细教程)
  • Day13_【DataFrame数据组合concat连接】【案例】
  • C5.5:VDB及后面的电路讨论
  • 决策树(2)
  • Yum使用时报错
  • Spring Boot 全局异常处理
  • 快速了解Anaconda系统
  • 08.5【C++ 初阶】实现一个相对完整的日期类--附带源码
  • implement libtime on Windows
  • MyCAT基础概念
  • Python函数总结
  • week2-[一维数组]最大元素
  • 单细胞格式转换 rds 转成 h5ad
  • transformer模型初理解
  • Transformer、BERT、BEiT等模型相关八股及代码【自用】
  • HJ4 字符串分隔
  • 神经网络训练过程详解
  • 电流采样实现方法
  • JavaScript 代码保护与混淆
  • Vue2+Vue3前端开发_Day1
  • 端口映射原理操作详解教程:实现外网访问内网服务,本地路由器端口映射公网ip和软件端口映射域名2种方法