文章目录
- 简介
- 一.条件及环境说明:
- 二.需求说明:
- 三.实现原理及说明
- 四.详细步骤
- 4.1.创建configmap 配置文件
- 4.2.创建StatefulSet 配置
- 4.3.创建service headless 配置
- 五.安装说明
简介
本文将根据在k8s环境中搭建【伪】单机模式的redis实例。由于共享存储的io性能比较低,所以将共享存储用于数据备份,而采用hostpath的形式进行redis数据的存储,这样有助于提高redis的io性能,本文将讲解如何在一个pod内用两个container作为redis的主从形式来实现单机版、高可用的redis。
一.条件及环境说明:
k8s版本k8s-1.29.4,环境搭建在电信机房,共计六个节点,每个节点有一块非系统盘的ssd盘挂载到/data/路径。有NAS共享存储,该共享存储是使用的阿里云NAS,走专线使用,专线带宽500Mb。
二.需求说明:
- 搭建redis实例:可单机,可主从。
- 高可用:有一个k8s节点死掉之后也不长时间影响使用。
- 高性能:需要高iO,采用共享存储或者是ceph的分布式存储,读写iO会打很大的折扣。
- 数据安全:在发生切换以后,数据要尽可能的保证完整
- 安装简单、管理维护容易
三.实现原理及说明
1.将redis搭建成主从模式,主redis的数据读写落在本地ssd磁盘,从redis的数据数据落在外挂的共享nas存储。
2.然后创建一个statefulset的配置,放置两个container,一个container 作为主redis,挂载到hostpath,以主机名创建目录,并存储rdb文件。另外一个container 作为从redis,挂载nas路径也以主机名创建目录,并存储rdb文件。
3.调整从redis的数据持久化参数save,将数据落盘时间调整到较小的参数,这样保证更新的数据尽快存储到rdb文件。
4.在pod每次发生调度或者重启时,将nas存储的rdb文件拷贝到hostpath路径再启动redis。
注:这样做是让主redis实现高性能的处理业务数据,从redis就负责数据持久化,可能存在如下的问题:1.当主的读写数据io太高时,从redis由于是挂载nas,数据落盘时间会更长一些。
四.详细步骤
4.1.创建configmap 配置文件
配置包含三个文件主redis的配置文件,从redis的配置文件,以及一个根据执行角色执行不同操作的简单脚本,具体配置如下:
redis-master:conf 主redis配置文件,内存配置成256M,配置端口为6379,配置密码:redis#123,存储路径是/data/redis。
redis.conf:从redis配置文件,内存配置成256M,配置端口为6380,配置密码:redis#123,存储路径是/data/redis-2,并配置从6379的端口同步数据,将存储时间调整成60s以内有10个数据变动就进行存储落盘。
run.sh:主要作用就是判断角色并根据主机名创建目录,然后软连接到存储目录。这一步主要是将各自服务的redis数据存放到自己的目录,当创建新的redis的时候不会导致节点上的目录冲突。
apiVersion: v1
kind: ConfigMap
metadata:
name: defaultapp-redis-standalone-config
namespace: default
labels:
appname: default-app
app: defaultapp-redis-standalone-config
data:
redis-master.conf: |
port 6379
maxmemory 256mb
requirepass redis#123
dir /data/redis
redis.conf: |
port 6380
maxmemory 256mb
requirepass redis#123
save 3600 1 300 5 60 10
dir /data/redis-2
replicaof 127.0.0.1 6379
masterauth redis#123
run.sh: |
#!/bin/sh
role=$1
hname=$(hostname)
if [ $role == "master" ];then
echo "run redis master"
ls /etc/redis/ -l
[ -d /home/redis/$hname ] || mkdir -p /home/redis/$hname
[ -d /data ] || mkdir /data
ln -s /home/redis/$hname /data/redis
if [ -f /home/redis-2/$hname/dump.rdb ];then
cp -vf /home/redis-2/$hname/dump.rdb /data/redis/
else
echo "[info] no bak dump.rdb"
fi
redis-server /etc/redis/redis-master.conf
else
echo "run redis slave"
ls /etc/redis/ -l
[ -d /home/redis-2/$hname ] || mkdir -p /home/redis-2/$hname
[ -d /data ] || mkdir /data
ln -s /home/redis-2/$hname /data/redis-2
redis-server /etc/redis/redis.conf
fi
4.2.创建StatefulSet 配置
为什么不用deployment是因为存储路径是根据主机名的目录,deployment的主机名每次重启都会变动,所以才采用statefuleset。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: defaultapp-redis-standalone
namespace: default
labels:
appname: default-app
app: defaultapp-redis-standalone
spec:
serviceName: "defaultapp-redis-standalone"
replicas: 1
selector:
matchLabels:
app: defaultapp-redis-standalone
template:
metadata:
labels:
app: defaultapp-redis-standalone
spec:
containers:
- name: redis-master
image: xxx-registry-vpc.cn-shenzhen.cr.aliyuncs.com/public/redis:7.2.5-alpine3.20
imagePullPolicy: IfNotPresent
command: ["/bin/sh","/etc/redis/run.sh"]
args: ["master"]
ports:
- containerPort: 6379
volumeMounts:
- name: redis-config-volume
mountPath: /etc/redis/
- name: redis-data
mountPath: /home/redis
- name: redis-backup
mountPath: /home/redis-2
readOnly: false
- name: redis-slave
image: xxx-registry-vpc.cn-shenzhen.cr.aliyuncs.com/public/redis:7.2.5-alpine3.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 6380
command: ["/bin/sh","/etc/redis/run.sh"]
args: ["slave"]
volumeMounts:
- name: redis-config-volume
mountPath: /etc/redis/
- name: redis-data
mountPath: /home/redis
- name: redis-backup
mountPath: /home/redis-2
readOnly: false
restartPolicy: Always
volumes:
- name: redis-data
hostPath:
path: /data/redis_data
type: ""
- name: redis-config-volume
configMap:
name: defaultapp-redis-standalone-config
- name: redis-backup
nfs:
server: xxxx-mxx.cn-shenzhen.nas.aliyuncs.com
path: /backup/redis
4.3.创建service headless 配置
创建无头服务,集群内调用可以采用无头服务的名称进行调用。
apiVersion: v1
kind: Service
metadata:
name: defaultapp-redis-standalone
namespace: default
labels:
appname: default-app
app: defaultapp-redis-standalone
spec:
ports:
- port: 6379
clusterIP: None
selector:
app: defaultapp-redis-standalone
如果需要对k8s集群外提供访问可以创建成service服务并配置LoadBalancer或者NodePort的形式。
apiVersion: v1
kind: Service
metadata:
name: defaultapp-redis-standalone-external
namespace: default
labels:
appname: default-app
app: defaultapp-redis-standalone
spec:
ports:
- port: 6379
type: LoadBalancer
selector:
app: defaultapp-redis-standalone
五.安装说明
- 需要先在k8s的节点创建/data/redis_data的路径来存放数据。
- 需要挂载一个共享存储,或者有一个公共路径存放备份文件的地方。
- 使用配置前将配置中的defaultapp替换成自己需要的命名。
- 配置中的镜像地址采用了私有的镜像地址,镜像是dockerhub上下载的redis:7.2.5-alpine3.20镜像到私有镜像仓库的,如果能直通外网的k8s可以直接用redis:7.2.5-alpine3.20。否则配置一个可以通的镜像地址。
- redis.conf或redis-master.conf中的密码redis#123替换成自己的密码。
- 复制配置时注意缩进字符,有不明白的配置欢迎私信