基于k8s搭建Redis Cluster集群3主3从

本文基于k8s、Redis7.0搭建Redis Cluster集群3主3从,此教程无需创建configMap通过命令方式指定所需参数

一、部署Redis Cluster

文中引入的local-pvc是上文中已创建好的,也可以换成您已有的nfs或其他存储,如您的集群没有其他存储请移步基于k8s搭建本地存储(PVC)

1、创建statefulsets有状态应用(STS)

(1)编辑redis-cluster.yaml内容如下
---
apiVersion: v1
kind: Service                                     #先创建一个无头service
metadata:
  labels:                                         #service本身的标签
    app: redis-headless-svc
  name: redis-hl-svc                                 #service的名称,下面创建的StatefulSet就要引用这个service名称
spec:
  ports:
    - port: 6379                                    #service本身的端口
      protocol: TCP
      targetPort: 6379                              #目标端口6379,redis默认端口是6379,这里为了安全改成了6379
  selector:
    app: redis-sts                                    #标签选择器要与下面创建的pod的标签一样
  type: ClusterIP
  clusterIP: None                                 #clusterIP为None表示创建的service为无头service
---
apiVersion: apps/v1
kind: StatefulSet                                 #创建StatefulSet资源
metadata:
  labels:                                         #StatefulSet本身的标签
    app: redis-sts
  name: redis-sts                                 #资源名称
  namespace: default                              #资源所属命名空间
spec:
  selector:                                       #标签选择器,要与下面pod模板定义的pod标签保持一致
    matchLabels:
      app: redis-sts
  replicas: 6                                     #副本数为6,redis集群模式最少要为6个节点,构成33serviceName: redis-hl-svc                          #指定使用service为上面我们创建的无头service的名称
  template:
    metadata:
      labels:                                     #pod的标签,上面的无头service的标签选择器和sts标签选择器都要与这个相同
        app: redis-sts
    spec:
      #     affinity:
      #       podAntiAffinity:                         #定义pod反亲和性,目的让6个pod不在同一个主机上,实现均衡分布,这里我的node节点不够,所以不定义反亲和性
      #         preferredDuringSchedulingIgnoredDuringExecution:
      #         - weight: 100
      #           podAffinityTerm:
      #             labelSelector:
      #              matchExpressions:
      #               - key: app
      #                 operator: In
      #                 values:
      #                 - redis-sts
      #             topologyKey: kubernetes.io/hostname
      containers:
        - name: redis                               #容器名称
          image: redis:7.0                       #redis镜像
          imagePullPolicy: IfNotPresent             #镜像拉取策略
          command:                                  #定义容器的启动命令和参数
            - "redis-server"
          args:
            - "--masterauth"
            - "123456"
            - "--requirepass"
            - "123456"
            - "--cluster-enabled"
            - "yes"
            - "--protected-mode"
            - "no"
            - "--cluster-announce-ip"				 #这个参数和下面的这个参数
            - "$(POD_IP)"							 #这个参数是为了解决pod重启ip变了之后,redis集群状态无法自动同步问题
          env:
            - name: POD_IP							 #POD_IP值引用自status.podIP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.namespace
          ports:                                    #定义容器端口
            - name: redis-6379                        #为端口取个名称为http
              containerPort: 6379                     #容器端口
          volumeMounts:
            - name: "redis-data"                      #指定使用的卷名称,这里使用的是下面定义的pvc模板的名称
              mountPath: "/data"                      #redis数据的挂载点
              subPathExpr: $(POD_NAMESPACE)/$(POD_NAME)
              readOnly: false
      restartPolicy: Always
      volumes:
        - name: "redis-conf"                        #挂载一个名为redis-conf的configMap卷,这个cm卷已经定义好了
          configMap:
            name: "redis-cm"
            defaultMode: 0755
            items:
              - key: "redis.conf"
                path: "redis.conf"
        - name: redis-data
          persistentVolumeClaim:
            claimName: local-pvc

(2)创建svc、sts
kubectl create -f .\redis-cluster.yaml
(3)查看svc、sts、pods
kubectl get sts,svc,pods

可以看到6个pod都起来了

在这里插入图片描述

2、自动创建redis集群,构成3主3从集群模式

#在redis任意一个pod执行初始化命令,可以进入到pod里面执行也可以直接在外面执行

#其中为了获取每个pod的ip,使用kubectl get pods -l app=redis-sts -o jsonpath='{range.items[*]}{.status.podIP}:6379 {end}'获取

#本次采用自动创建redis的形式,也就是说不指定哪个是主哪个是从节点,让redis自动分配,生产环境中也建议使用该种方式

(1)执行创建集群命令
kubectl exec -it redis-sts-0 -- redis-cli -a 123456 --cluster create --cluster-replicas 1 $(kubectl get pods -l app=redis-sts -o jsonpath='{range.items[*]}{.status.podIP}:6379 {end}')
(2)检查集群信息
# 可以进入任意一个节点pod中进行验证集群状态
kubectl exec -it redis-sts-0 -- redis-cli -a 123456--cluster check  $(kubectl get pods -l app=redis-sts -o jsonpath='{range.items[0]}{.status.podIP}:6379 {end}')

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

3、验证pod挂掉,重新创建之后,redis集群是否正常

(1)开始手动删除pod,模拟pod挂掉后重新创建后ip改变了,redis集群是否正常
kubectl  delete pod redis-sts-1
kubectl  get pods -l app=redis-sts -o wide

可以看出pod IP发生了变化
在这里插入图片描述

(2)查看redis集群状态,看看pod的ip变了,redis集群状态是否正常
kubectl exec -it redis-sts-0 bash
redis-cli -a 123456 --cluster check 10.1.1.64:6379
redis-cli -a 123456 -c
cluster nodes

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

4、问题思考

cluster-announce-ip 对外暴露的是podIP,所以在集群外并不能访问,怎么才能即在集群内可以访问又在集群外可以访问呢

觉得不错点个赞

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐