k8s实战案例之部署redis cluster(设置密码版)
  1pC2C06v0rDZ 2023年11月02日 54 0


1.1、PV/PVC及Redis Cluster-StatefulSet

k8s实战案例之部署redis cluster(设置密码版)_redis

redis cluster相比redis单机要稍微复杂一点,我们也是通过pv/pvc将redis cluster数据存放在存储系统中,不同于redis单机,redis cluster对存入的数据会做crc16计算,然后和16384做取模计算,得出一个数字,这个数字就是存入redis cluster的一个槽位;即redis cluster将16384个槽位,平均分配给集群所有master节点,每个master节点存放整个集群数据的一部分;这样一来就存在一个问题,如果master宕机,那么对应槽位的数据也就不可用,为了防止master单点故障,我们还需要对master做高可用,即专门用一个slave节点对master做备份,master宕机的情况下,对应slave会接管master继续向集群提供服务,从而实现redis cluster master的高可用;如上图所示,我们使用3主3从的redis cluster,redis0,1,2为master,那么3,4,5就对应为0,1,2的slave,负责备份各自对应的master的数据;这六个pod都是通过k8s集群的pv/pvc将数据存放在存储系统中;

1.2、创建PV

1.2.1、在nfs上准备redis cluster 数据目录

注意要在k8s所有节点上安装nfs工具,才有mount功能 yum install -y nfs-utils

1.2.2、动态创建pv

https://blog.csdn.net/qq_46403377/article/details/126638917

1.3、部署redis cluster

1.3.1、创建configmap

apiVersion: v1
kind: ConfigMap
metadata:
  name: redis-conf
  namespace: unis
data:
  redis.conf: |       ###这个名字需要跟items中key一致,这样才能调用
    bind 0.0.0.0
    port 6379
    daemonize no
    pidfile /var/lib/redis/redis.pid
    logfile /var/lib/redis/redis_log
    dbfilename dump.rdb
    dir /var/lib/redis
    cluster-enabled yes 
    cluster-node-timeout 5000 
    appendonly yes
    maxmemory 50M
    maxmemory-policy allkeys-lfu


1.3.2、部署redis cluster

root@k8s-master:~/k8s-data/yaml/magedu/redis-cluster# cat redis.yaml 
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-app
  namespace: unis
spec:
  serviceName: "redis-service"
  replicas: 6
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      containers:
      - name: redis
        image: redis:6.2.5
        command:
          - "redis-server"
        args:
          - "/etc/redis/redis.conf"
          - "--protected-mode"
          - "no"
        resources:
          requests:
            cpu: "100m"
            memory: "100Mi"
        ports:
            - name: redis
              containerPort: 6379
              protocol: "TCP"
            - name: cluster
              containerPort: 16379
              protocol: "TCP"
        volumeMounts:
          - name: "redis-conf"
            mountPath: "/etc/redis"
          - name: "redis-data"
            mountPath: "/var/lib/redis"
      volumes:
      - name: "redis-conf"
        configMap:
          name: "redis-conf"
          items:
            - key: "redis.conf"
              path: "redis.conf"
  volumeClaimTemplates:
  - metadata:
      name: redis-data
    spec:
      accessModes: [ "ReadWriteMany" ]
      storageClassName: managed-nfs-storage
      resources:
        requests:
          storage: 200M
  selector:
    matchLabels:
      app: redis
---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
  namespace: unis
  labels:
    app: redis
spec:
  selector:   #标签要对应StatefulSet metadata下的标签
    app: redis
    appCluster: redis-cluster
  ports:
  - name: redis
    port: 6379
  clusterIP: None

上述配置清单,主要用sts控制器创建了6个pod副本,每个副本都使用configmap中的配置文件作为redis配置文件,使用pvc模板指定pod在k8s上自动关联pv,并在magedu名称空间创建pvc,即只要k8s上有空余的pv,对应pod就会在magedu这个名称空间按pvc模板信息创建pvc;当然我们可以使用存储类自动创建pvc,也可以提前创建好pvc,一般情况下使用sts控制器,我们可以使用pvc模板的方式来指定pod自动创建pvc(前提是k8s有足够的pv可用);

应用配置清单部署redis cluster

k8s实战案例之部署redis cluster(设置密码版)_redis_02

使用sts控制器创建pod,pod名称是sts控制器的名称-id,使用pvc模板创建pvc的名称为pvc模板名称-pod名称,即pvc模板名-sts控制器名-id;

1.4、初始化redis cluster

1.4.1、在k8s上创建临时容器,安装redis cluster 初始化工具

root@k8s-master01:~# kubectl run -it ubuntu1804 --image=ubuntu:18.04 --restart=Never -n  bash
If you don't see a command prompt, try pressing enter.
root@k8s-master01:~# kubectl exec -it ubuntu1804 -n unis /bin/bash
root@ubuntu1804:/#
root@ubuntu1804:/# apt update
# 安装必要工具
root@ubuntu1804:/# apt install python2.7 python-pip redis-tools dnsutils iputils-ping net-tools
# 更新pip
root@ubuntu1804:/# pip install --upgrade pip
# 使用pip安装redis cluster初始化工具redis-trib
root@ubuntu1804:/# pip install redis-trib==0.5.1

1.4.2、初始化redis cluster

 域名写法:pod_name.svc_name.ns_name.svc.cluster.local ,创建headless无头服务后pod通过域名进行相互访问

root@ubuntu1804:/# redis-trib.py create  `dig +short redis-app-0.redis-service.unis.svc.cluster.local`:6379  `dig +short redis-app-1.redis-service.unis.svc.cluster.local`:6379  `dig +short redis-app-2.redis-service.unis.svc.cluster.local`:6379

k8s实战案例之部署redis cluster(设置密码版)_ubuntu_03

在k8s上我们使用sts创建pod,对应pod的名称是固定不变的,所以我们初始化redis 集群就直接使用redis pod名称就可以直接解析到对应pod的IP地址;在传统虚拟机或物理机上初始化redis集群,我们可用直接使用IP地址,原因是物理机或虚拟机IP地址是固定的,在k8s上pod的IP地址是不固定的;

1.4.3、给master指定slave

  • 给redis-0指定slave为 redis-3,给redis-1指定slave为 redis-4,给redis-2指定slave为 redis-5
root@ubuntu1804:/# redis-trib.py replicate  --master-addr `dig +short redis-app-0.redis-service.unis.svc.cluster.local`:6379  --slave-addr `dig +short redis-app-3.redis-service.unis.svc.cluster.local`:6379
root@ubuntu1804:/# redis-trib.py replicate  --master-addr `dig +short redis-app-1.redis-service.unis.svc.cluster.local`:6379  --slave-addr `dig +short redis-app-4.redis-service.unis.svc.cluster.local`:6379
root@ubuntu1804:/# redis-trib.py replicate  --master-addr `dig +short redis-app-2.redis-service.unis.svc.cluster.local`:6379  --slave-addr `dig +short redis-app-5.redis-service.unis.svc.cluster.local`:6379

k8s实战案例之部署redis cluster(设置密码版)_ubuntu_04


1.5、验证redis cluster状态

1.5.1、进入redis cluster 任意pod 查看集群信息

通过rancher进入pod的shell里面

root@redis-app-0:/data# redis-cli

127.0.0.1:6379>cluster info

127.0.0.1:6379>cluster nodes

k8s实战案例之部署redis cluster(设置密码版)_redis_05

集群节点信息中记录了master节点id和slave id,其中slave后面会对应master的id,表示该slave备份对应master数据;


1.5.4、验证redis cluster读写数据是否正常?

1.5.4.1、手动连接redis cluster 进行数据读写

k8s实战案例之部署redis cluster(设置密码版)_数据_06

手动连接redis 集群master节点进行数据读写,存在一个问题就是当我们写入的key经过crc16计算对16384取模后,对应槽位可能不在当前节点,redis它会告诉我们该key该在哪里去写;从上面的截图可用看到,有的可以写入,有的提示去别的master节点写入,说明redis cluster 是可用正常读写数据的

然后我们需要设置密码,通过redis-cli连接各个节点去执行命令,无需重启,即可生效,效果和在redis.conf里面添加密码参数一样,还有一个问题就是,pod重启以后,密码就会全部失效,需要重新执行以下命令

redis-cli
127.0.0.1:6379>config set masterauth 123456 
127.0.0.1:6379>config set requirepass 123456
127.0.0.1:6379>config rewrite   #这条命令会无法执行,修改replica-read-only no也不管用,官网说启动的时候指定配置文件才行,但是我指定了也无法修改

1.5.4.2、使用python脚本连接redis cluster 进行数据读写(这一步我没有进行,可自行验证)

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# cat redis-client-test.py
#!/usr/bin/env python
#coding:utf-8
#Author:Zhang ShiJie
#python 2.7/3.8
#pip install redis-py-cluster

import sys,time
from rediscluster import RedisCluster
def init_redis():
    startup_nodes = [
        {'host': '192.168.0.34', 'port': 36379},
        {'host': '192.168.0.35', 'port': 36379},
        {'host': '192.168.0.36', 'port': 36379},
        {'host': '192.168.0.34', 'port': 36379},
        {'host': '192.168.0.35', 'port': 36379},
        {'host': '192.168.0.36', 'port': 36379},
    ]
    try:
        conn = RedisCluster(startup_nodes=startup_nodes,
                            # 有密码要加上密码哦
                            decode_responses=True, password='')
        print('连接成功!!!!!1', conn)
        #conn.set("key-cluster","value-cluster")
        for i in range(100):
            conn.set("key%s" % i, "value%s" % i)
            time.sleep(0.1)
            data = conn.get("key%s" % i)
            print(data)

        #return conn

    except Exception as e:
        print("connect error ", str(e))
        sys.exit(1)

init_redis()
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster#

运行脚本,向redis cluster 写入数据

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# python redis-client-test.py
Traceback (most recent call last):
  File "/root/k8s-data/yaml/magedu/redis-cluster/redis-client-test.py", line 8, in <module>
    from rediscluster import RedisCluster
ModuleNotFoundError: No module named 'rediscluster'
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster#

这里提示没有找到rediscluster模块,解决办法就是通过pip安装redis-py-cluster模块即可;

安装redis-py-cluster模块

k8s实战案例之部署redis cluster(设置密码版)_数据_07


运行脚本连接redis cluster进行数据读写

k8s实战案例之部署redis cluster(设置密码版)_数据_08


连接redis pod,验证数据是否正常写入?

k8s实战案例之部署redis cluster(设置密码版)_redis_09


k8s实战案例之部署redis cluster(设置密码版)_数据_10


k8s实战案例之部署redis cluster(设置密码版)_ubuntu_11

从上面的截图可用看到三个reids cluster master pod各自都存放了一部分key,并非全部;说明刚才我们用python脚本把数据正常写入了redis cluster;

验证在slave 节点是否可用正常读取数据?

k8s实战案例之部署redis cluster(设置密码版)_数据_12

从上面的截图可以了解到在slave节点是不可以读取数据;

到slave对应的master节点读取数据

k8s实战案例之部署redis cluster(设置密码版)_ubuntu_13

上述验证说明了redis cluster 只有master可以读写数据,slave只是对master数据做备份,不可以在slave上读写数据;

1.6、验证验证redis cluster高可用

1.6.1、在k8s node节点将redis:4.0.14镜像上传至本地harbor

  • 修改镜像tag
root@k8s-node01:~# nerdctl tag redis:4.0.14 harbor.ik8s.cc/redis-cluster/redis:4.0.14
  • 上传redis镜像至本地harbor
root@k8s-node01:~# nerdctl push harbor.ik8s.cc/redis-cluster/redis:4.0.14
INFO[0000] pushing as a reduced-platform image (application/vnd.docker.distribution.manifest.list.v2+json, sha256:1ae9e0f790001af4b9f83a2b3d79c593c6f3e9a881b754a99527536259fb6625) 
WARN[0000] skipping verifying HTTPS certs for "harbor.ik8s.cc" 
index-sha256:1ae9e0f790001af4b9f83a2b3d79c593c6f3e9a881b754a99527536259fb6625:    done           |++++++++++++++++++++++++++++++++++++++| 
manifest-sha256:5bd4fe08813b057df2ae55003a75c39d80a4aea9f1a0fbc0fbd7024edf555786: done           |++++++++++++++++++++++++++++++++++++++| 
config-sha256:191c4017dcdd3370f871a4c6e7e1d55c7d9abed2bebf3005fb3e7d12161262b8:   done           |++++++++++++++++++++++++++++++++++++++| 
elapsed: 1.4 s                                                                    total:  8.5 Ki (6.1 KiB/s)                                       
root@k8s-node01:~#

1.6.2、修改redis cluster部署清单镜像和镜像拉取策略

k8s实战案例之部署redis cluster(设置密码版)_ubuntu_14

修改镜像为本地harbor镜像和拉取策略是方便我们测试redis cluster的高可用;

1.6.3、重新apply redis cluster部署清单

root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster# kubectl apply -f redis.yaml
service/redis unchanged
service/redis-access unchanged
statefulset.apps/redis configured
root@k8s-master01:~/k8s-data/yaml/magedu/redis-cluster#

这里相当于给redis cluster更新,他们之间的集群关系还存在,因为集群关系配置都保存在远端存储之上;

  • 验证pod是否都正常running?
  • 验证集群状态和集群关系

不同于之前,这里rdis-0变成了slave ,redis-3变成了master;从上面的截图我们也发现,在k8s上部署redis cluster pod重建以后(IP地址发生变化),对应集群关系不会发生变化;对应master和salve一对关系始终只是再对应的master和salve两个pod中切换,这其实就是高可用;

1.6.4、停掉本地harbor,删除redis master pod,看看对应slave是否会提升为master?

  • 停止harbor服务
root@harbor:~# systemctl stop harbor
  • 删除redis-3,看看redis-0是否会提升为master?

可用看到我们把redis-3删除(相当于master宕机)以后,对应slave提升为master了;

1.6.5、恢复harbor服务,看看对应redis-3恢复会议后是否还是redis-0的slave呢?

  • 恢复harbor服务
  • 验证redis-3pod是否恢复?

再次删除redis-3以后,对应pod正常被重建,并处于running状态;

  • 验证redis-3的主从关系

可以看到redis-3恢复以后,对应自动加入集群成为redis-0的slave;

cluster reset  重置集群

出处:https://www.cnblogs.com/qiuhom-1874/



【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  eHipUjOuzYYH   2023年12月07日   28   0   0 数据乐观锁redis
  jnZtF7Co41Wg   2023年12月09日   28   0   0 客户端服务端数据
1pC2C06v0rDZ