K8S搭建redis主从集群

1. 创建NFS存储

创建NFS存储主要是为了给Redis提供稳定的后端存储,当Redis的Pod重启或迁移后,依然能获得原先的数据。这里,我们先要创建NFS,然后通过使用PV为Redis挂载一个远程的NFS路径。

安装NFS

#将需要在挂载的服务器中安装NFS
yum -y install nfs-utils(主包提供文件系统)
yum -y install rpcbind(提供rpc协议)

新增/etc/exports文件,用于设置需要共享的路径:

vim /etc/exports
/home/nfs/pv1 *(rw,sync,no_subtree_check,no_root_squash)
/home/nfs/pv2 *(rw,sync,no_subtree_check,no_root_squash)
/home/nfs/pv3 *(rw,sync,no_subtree_check,no_root_squash)
/home/nfs/pv4 *(rw,sync,no_subtree_check,no_root_squash)
/home/nfs/pv5 *(rw,sync,no_subtree_check,no_root_squash)
/home/nfs/pv6 *(rw,sync,no_subtree_check,no_root_squash)

创建相应目录

mkdir -p /home/nfs/pv{1..6}

启动NFS和rpcbind服务

systemctl enable rpcbind.service
systemctl enable nfs-server.service
systemctl start rpcbind.service
systemctl start nfs-server.service
exportfs -r
systemctl reload nfs-server

查看存储端共享

showmount -e [IP]
2. 创建PV

每一个Redis Pod都需要一个独立的PV来存储自己的数据,因此可以创建一个pv.yaml文件,包含6个PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv1
spec:
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.23
    path: "/home/nfs/pv1"

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv2
spec:
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.23
    path: "/home/nfs/pv2"

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv3
spec:
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.23
    path: "/home/nfs/pv3"

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv4
spec:
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.23
    path: "/home/nfs/pv4"

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv5
spec:
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.23
    path: "/home/nfs/pv5"

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv6
spec:
  capacity:
    storage: 200M
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.1.23
    path: "/home/nfs/pv6"

创建PV

kubectl create -f pv.yaml 
3. 创建Configmap

这里,我们可以直接将Redis的配置文件转化为Configmap,这是一种更方便的配置读取方式。配置文件redis.conf如下

appendonly yes
cluster-enabled yes
cluster-config-file /var/lib/redis/nodes.conf
cluster-node-timeout 5000
dir /var/lib/redis
port 6379

创建名为redis-conf的Configmap:

kubectl create configmap redis-conf --from-file=redis.conf
4. 创建Headless service

Headless service是StatefulSet实现稳定网络标识的基础,我们需要提前创建。准备文件headless-service.yml如下:

apiVersion: v1
kind: Service
metadata:
  name: redis-service
  labels:
    app: redis
spec:
  ports:
  - name: redis-port
    port: 6379
  clusterIP: None
  selector:
    app: redis
    appCluster: redis-cluster

创建

kubectl create -f headless-service.yml

在这里插入图片描述
服务名称为redis-service,其CLUSTER-IP为None,表示这是一个“无头”服务。

5. 创建Redis集群节点(v=6.2.6)

创建好Headless service后,就可以利用StatefulSet创建Redis 集群节点,这也是本文的核心内容。我们先创建redis.yml文件:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-app
spec:
  serviceName: "redis-service"
  replicas: 6
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      terminationGracePeriodSeconds: 20
      affinity:
        podAntiAffinity:
          preferredDuringSchedulingIgnoredDuringExecution:
            - weight: 100
              podAffinityTerm:
                labelSelector:
                  matchExpressions:
                    - key: app
                      operator: In
                      values:
                        - redis
                topologyKey: kubernetes.io/hostname
      containers:
        - name: redis
          image: redis
          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" ]
        resources:
          requests:
            storage: 200M

如上,总共创建了6个Redis节点(Pod),其中3个将用于master,另外3个分别作为master的slave;Redis的配置通过volume将之前生成的redis-conf这个Configmap,挂载到了容器的/etc/redis/redis.conf;Redis的数据存储路径使用volumeClaimTemplates声明(也就是PVC),其会绑定到我们先前创建的PV上。

创建

kubectl apply -f redis.yaml

在这里插入图片描述
另外,根据StatefulSet的规则,我们生成的Redis的6个Pod的hostname会被依次命名为 [statefulset名称]-[序号]

如图所示:可以看到这些Pods在部署时是以{0…N-1}的顺序依次创建的。注意,直到redis-app-0状态启动后达到Running状态之后,redis-app-1 才开始启动。

同时,每个Pod都会得到集群内的一个DNS域名,格式为[podname].[service name].[namespace].svc.cluster.local,也即

redis-app-0.redis-service.default.svc.cluster.local
redis-app-1.redis-service.default.svc.cluster.local
...以此类推...

在K8S集群内部,这些Pod就可以利用该域名互相通信。我们可以使用ubuntu镜像的nslookup检验这些域名:
在这里插入图片描述
另外可以发现,我们之前创建的pv都被成功绑定了:
在这里插入图片描述

6. 初始化Redis集群

创建好6个Redis Pod后,我们还需要利用常用的Redis-tribe工具进行集群的初始化

由于Redis集群必须在所有节点启动后才能进行初始化,而如果将初始化逻辑写入Statefulset中,则是一件非常复杂而且低效的行为。我们可以在K8S上创建一个额外的容器,专门用于进行K8S集群内部某些服务的管理控制。
这里,我们专门启动一个Ubuntu的容器,可以在该容器中安装Redis-tribe,进而初始化Redis集群.

因为官方的ubuntu镜像里面的redis初始化的工具是没有的,我已经将初始化时需要的环境都打好了
https://download.csdn.net/download/zxc_123_789/80630356

下载此tar包后将其加载为镜像,然后运行此镜像

kubectl run -it ubuntu --image=ubuntu --restart=Never /bin/bash

初始化集群:
可以使用nslookup redis-app-0.redis-service命令查看每个节点对应的IP
在这里插入图片描述

然后,创建只有Master节点的集群:

redis-trib.py create 10.244.4.16:6379  10.244.1.66:6379 10.244.6.14:6379

其次,为每个Master添加Slave

redis-trib.py replicate --master-addr  10.244.4.16:6379  --slave-addr 10.244.3.25:6379
redis-trib.py replicate --master-addr  10.244.1.66:6379  --slave-addr 10.244.5.27:6379
redis-trib.py replicate --master-addr  10.244.6.14:6379  --slave-addr 10.244.2.71:6379

至此,我们的Redis集群就真正创建完毕了,连到任意一个Redis Pod中检验一下:

kubectl exec -it redis-app-0 bash

在这里插入图片描述
另外,还可以在NFS上查看Redis挂载的数据:
在这里插入图片描述

7. 创建用于访问Service

前面我们创建了用于实现StatefulSet的Headless Service,但该Service没有Cluster Ip,因此不能用于外界访问。所以,我们还需要创建一个Service,专用于为Redis集群提供访问和负载均衡:

apiVersion: v1
kind: Service
metadata:
  name: redis-access-service
  labels:
    app: redis
spec:
  ports:
    - name: redis-port
      protocol: "TCP"
      port: 6379
      targetPort: 6379
  selector:
    app: redis
    appCluster: redis-cluster

如上,该Service名称为 redis-access-service,在K8S集群中暴露6379端口,并且会对labels name为app: redisappCluster: redis-cluster的pod进行负载均衡。

至此,k8s中的3主3从的redis集群环境就搭建好了.

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
在Kubernetes上部署Redis主从集群可以采用不同的方法。一种常见的方法是使用StatefulSet来部署Redis。StatefulSet是为了解决有状态服务的问题而设计的,它可以为每个Pod分配固定的名称和稳定的网络标识。在Redis的部署中,可以使用StatefulSet来管理Redis主从节点。同时,可以使用Headless Service来为StatefulSet提供服务,Headless Service不会分配Cluster IP,而是返回所有Pod的Endpoint列表。这样可以确保在主从切换时,客户端可以正确地访问到Redis节点。\[3\] 另一种方法是在Kubernetes上创建一个额外的容器,专门用于进行Redis集群的管理控制。可以在该容器中安装Redis-tribe工具,通过该工具来初始化Redis集群。这种方法可以避免将初始化逻辑写入StatefulSet中,从而简化部署过程。\[2\] 需要注意的是,在Kubernetes上部署Redis Sentinel可能没有意义。因为在容器中,Pod的IP地址在重启时会发生变化,而Sentinel是以IP地址来进行探测和配置的。这导致Sentinel无法识别宕机后重新启动的Master节点,从而无法加入集群。虽然可以通过固定Pod的IP地址或使用NodePort来解决这个问题,但在Kubernetes中,Pod的重启和活性检测已经可以保证Redis主从的高可用性。因此,个人认为在Kubernetes上部署Sentinel没有意义。\[3\] #### 引用[.reference_title] - *1* *3* [k8s上部署高可用redis集群--三主三从](https://blog.csdn.net/Hlroliu/article/details/105859200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [K8S搭建redis主从集群](https://blog.csdn.net/zxc_123_789/article/details/122924616)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值