KubeSphere部署redis集群

一、部署前准备

(一)KubeSphere部署redis集群思路

参考上一篇文章的部署思路:KubeSphere安装mysql-CSDN博客

(二)部署方法参考

1、参考Docker Hub的中docker部署redis的方法

部署方法按照Docker Hub官网部署redis的步骤进行,官网地址:https://hub.docker.com/

docker部署redis命令如下:

docker run -d --name my-persistent-redis -p 6379:6379 -v /data/redis:/data redis:latest redis-server --appendonly yes

(三)将redis镜像上传到阿里云私有仓库

#登录
docker login --username=xxx registry.cn-hangzhou.aliyuncs.com

#打标签
docker tag redis:6.2.6 registry.cn-hangzhou.aliyuncs.com/yangbin-docker/redis:6.2.6

#上传
docker push registry.cn-hangzhou.aliyuncs.com/yangbin-docker/redis:6.2.6

二、KubeSphere部署redis集群步骤

1、创建项目(NameSpace)

2、创建保密字典(Secret)

用于连接阿里云redis私有镜像

 

3、创建redis配置字典

 配置文件内容如下:

daemonize no
supervised no
protected-mode no
bind 0.0.0.0
port 6379
cluster-announce-bus-port 16379
cluster-enabled yes
appendonly yes
cluster-node-timeout 5000
dir /data
cluster-config-file /data/nodes.conf
requirepass redis_123
masterauth  redis_123
pidfile /data/redis.pid
loglevel notice
logfile /data/redis_log

4、点击工作负载,选择StatefulSet(有状态副本集)

因为redis是开源服务所以最好是选择有状态副本集

4.1、填写创建的名称---> 选择项目(选择指定的项目方便管理)

 

4.2、添加容器
步骤一:选择上述创建的阿里云保密字典,填写容器仓库名称和版本号
步骤二:确认私有镜像链接是否正确(能搜索出镜像的详细信息说明配置正确)
步骤三:定义容器的名称(可根据自己的习惯自定义)
步骤四:填写容器资源限制(生产环境需要评估)

 

步骤五:配置端口用于访问容器内部
步骤六:填写启动命令选项(redis不需要配置环境变量)
步骤七:同步主机时区

步骤八:添加持久卷声明模板存放redis数据(可以多个路径进行挂载)

步骤九:挂载配置字典(挂载配置时需要选择特定键指向对应的文件)

因为在创建配置时指定的键值是redis.conf但是进行启动时指定的配置文件是redis-cluster.conf

5、创建容器查看redis集群状态

6、创建服务(Service)让外部可以访问到redis

步骤一:基本信息栏:填写服务名称 --> 选择项目 

 

步骤二:服务设置栏:选择指定工作负载 --> 选择有状态副本集 

步骤三:服务设置栏:设置端口(设置容器端口和服务端口)

步骤四:高级设置栏:选择外部访问 --> 选择访问模式为NodePort;完成创建

 

 7、外部环境连接数据库测试

在RDM工具上填写redis的连接信息

8、检查集群数据存储是否正确

9、操作生成的yaml文件

kind: StatefulSet
apiVersion: apps/v1
metadata:
  name: redis-cluster
  namespace: redis-cluster
  labels:
    app: redis-cluster
  annotations:
    kubesphere.io/creator: admin
    kubesphere.io/description: redis集群
spec:
  replicas: 6
  selector:
    matchLabels:
      app: redis-cluster
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: redis-cluster
      annotations:
        kubesphere.io/creator: admin
        kubesphere.io/imagepullsecrets: '{"redis-cluster":"aliyun-secretredis"}'
        logging.kubesphere.io/logsidecar-config: '{}'
    spec:
      volumes:
        - name: host-time
          hostPath:
            path: /etc/localtime
            type: ''
        - name: volume-c8t44w
          configMap:
            name: redis-cluster-conf
            items:
              - key: redis-cluster.conf
                path: redis-cluster.conf
            defaultMode: 420
      containers:
        - name: redis-cluster
          image: 'registry.cn-hangzhou.aliyuncs.com/yangbin-docker/redis:6.2.6'
          command:
            - redis-server
          args:
            - /etc/redis/redis-cluster.conf
            - '--cluster-announce-ip'
            - $(POD_IP)
          ports:
            - name: http-6379
              containerPort: 6379
              protocol: TCP
          env:
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.hostIP
            - name: POD_IP
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: status.podIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  apiVersion: v1
                  fieldPath: metadata.name
            - name: TZ
              value: Asia/Shanghai
          resources:
            limits:
              cpu: '1'
              memory: 1000Mi
          volumeMounts:
            - name: host-time
              mountPath: /etc/localtime
            - name: redis-data-pvc
              mountPath: /data
            - name: volume-c8t44w
              readOnly: true
              mountPath: /etc/redis
          terminationMessagePath: /dev/termination-log
          terminationMessagePolicy: File
          imagePullPolicy: IfNotPresent
      restartPolicy: Always
      terminationGracePeriodSeconds: 30
      dnsPolicy: ClusterFirst
      serviceAccountName: default
      serviceAccount: default
      securityContext: {}
      imagePullSecrets:
        - name: aliyun-secretredis
      schedulerName: default-scheduler
  volumeClaimTemplates:
    - kind: PersistentVolumeClaim
      apiVersion: v1
      metadata:
        name: redis-data-pvc
        namespace: redis-cluster
        creationTimestamp: null
      spec:
        accessModes:
          - ReadWriteOnce
        resources:
          requests:
            storage: 1Gi
        storageClassName: nfs-client
        volumeMode: Filesystem
      status:
        phase: Pending
  serviceName: redis-cluster-3d8c
  podManagementPolicy: OrderedReady
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 0
  revisionHistoryLimit: 10

三、初始化redis集群

1、初始化集群

#在master节点上执行集群初始化命令
kubectl exec -it redis-cluster-0 -n  redis-cluster   -- redis-cli -a redis_123 --cluster create --cluster-replicas 1 $(kubectl get pods -n redis-cluster  -l app=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:6379 {end}')

 

2、查看集群节点状态 

主从对应关系如下

#查看集群节点状态
KubeSphere(192.168.72.130:32728)>cluster nodes
"b0bbab8b5f2df749838a2ce91909a14165be1b16 192.169.166.150:6379@16379 master - 0 1740476861325 2 connected 5461-10922
3383c9422337b76a4e4595bdd0d7f50845ddba11 192.169.104.25:6379@16379 slave 080af61b560842ac04025e6820a68aaa6cb10b8b 0 1740476861000 3 connected
f5e7cdd9d7f4c895a1a84cfcb3f5d74196569e8e 192.169.104.26:6379@16379 slave b0bbab8b5f2df749838a2ce91909a14165be1b16 0 1740476862000 2 connected
ccbb5e70f4434b5468df3c3d9a884a428a2e79fc 192.169.104.24:6379@16379 myself,master - 0 1740476861000 1 connected 0-5460
080af61b560842ac04025e6820a68aaa6cb10b8b 192.169.166.151:6379@16379 master - 0 1740476861000 3 connected 10923-16383
da032400ebd5c0a7e4efec444b00ebece6bf8ec1 192.169.166.152:6379@16379 slave ccbb5e70f4434b5468df3c3d9a884a428a2e79fc 0 1740476862333 1 connected

3、数据写入验证

3.1、批量插入数据

#批量插入20条数据
for i in {1..20};do kubectl exec -it redis-cluster-0 -n  redis-cluster -- redis-cli -c -p 6379  -a redis_123 -c set k_${i} v_${i}; done

插入20条数据可以看到有7条数据在该节点上存储 

 

3.2、批量查看数据

#使用命令查看数据插入的情况
for i in {1..20};do kubectl exec -it redis-cluster-0 -n  redis-cluster -- redis-cli -c -p 6379  -a redis_123 -c get k_${i}; done

#查看数据插入的情况
[root@master k8s]# kubectl exec -it redis-cluster-0 -n redis-cluster -- redis-cli -c -p 6379  -a redis_123
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379>
127.0.0.1:6379> keys *
1) "k_13"
2) "k_5"
3) "k_9"
4) "k_17"
5) "k_16"
6) "k_4"
7) "k_1"
8) "k_8"
127.0.0.1:6379>
127.0.0.1:6379> get k_13
"v_13"
127.0.0.1:6379>
127.0.0.1:6379> get k_5
"v_5"
127.0.0.1:6379>
127.0.0.1:6379>
127.0.0.1:6379>

3.3、批量删除数据

#批量删除数据

for i in {1..20};do kubectl exec -it redis-cluster-0 -n redis-cluster -- redis-cli -c -p 6379 -a redis_123 -c del k_${i}; done

四、Pod发生重启时IP不同步到redis集群内部问题处理

集群节点关系对应关系如下:

master

slave

redis-cluster-0 (192.169.104.24)

redis-cluster-4 (192.169.166.152)

redis-cluster-1 (192.169.166.150)

redis-cluster-5 (192.169.104.26)

redis-cluster-2 (192.169.166.151)

redis-cluster-3 (192.169.104.25)

 1、删除redis-cluster-0节点模拟节点故障

1.1、正常的集群节点状态

1.2、删除redis-cluster-0

1.3、Pod容器的IP已经改变而redis集群中的IP没有变化

虽然redis-cluster-0容器已经重新创建,但是redis集群连接信息并没有发生变化,因为在部署时没有设置--cluster-announce-ip,$(POD_IP)参数所以pod在重新创建时没有向集群暴露自己的IP

2、--cluster-announce-ip,$(POD_IP)参数详解

在 K8S 部署 Redis 时,--cluster-announce-ip$(POD_IP)的含义如下:

2.1、--cluster-announce-ip详解

  • --cluster-announce-ip:这是 Redis 启动时的一个参数,用于指定 Redis 节点向集群中其他节点宣告自己的 IP 地址。在 Kubernetes 环境中,Pod 的 IP 地址可能会发生变化,比如在 Pod 重启、节点故障转移等情况下。通过设置--cluster-announce-ip参数,Redis 节点可以及时将自己新的 IP 地址告知集群中的其他节点,确保集群能够正确地进行数据路由和节点间的通信,维持集群的正常运行。

2.2、$(POD_IP)详解

  • $(POD_IP):这是一个环境变量引用,通常在 Kubernetes 的 Pod 配置中使用。它会在 Pod 启动时被替换为该 Pod 实际分配到的 IP 地址。在 Redis 的部署配置中,将$(POD_IP)作为--cluster-announce-ip的值,就是告诉 Redis 以当前 Pod 的 IP 地址来向集群宣告自己的地址。

2.3、POD_IP环境变量,并从status.podIP字段获取值

在 values.yaml 文件中,找到Redis容器的环境变量配置部分,添加 POD_IP 环境变量。示例如下:

redis:
  image: redis:latest
  args:
    - "--cluster-announce-ip"
    - "$(POD_IP)"
    - "--protected-mode"
    - "no"
  env:
    - name: POD_IP
      valueFrom:
        fieldRef:
          fieldPath: status.podIP

 

3、解决集群在Pod重启时IP改变不能同步到集群问题

上述说到缺少--cluster-announce-ip和$(POD_IP)参数导致Pod在重启时不能将新的IP同步到redis集群中,所以在部署时需要在启动命令中加入这两个参数,在环境变量中要定义POD_IP 环境变量,并从 status.podIP 字段获取值。

3.1、在启动命令中加入--cluster-announce-ip和$(POD_IP)参数

3.2、定义环境变量

3.2.1、在添加完启动命令之后选择编辑yaml文件

 3.2.2、在yaml文件中添加如下内容
#在args变量之后添加下边的内容
          env:
            - name: HOST_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.hostIP
            - name: POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: TZ
              value: "Asia/Shanghai"

根据在yaml中添加环境变量生成如下内容,但是在KubeSphere中找不到fieldRef选项所以在yaml中添加即可。

3.3、 删除redis-cluster-0节点模拟节点故障

Pod重新启动后看集群中的IP是否发生变化

3.3.1、删除之前IP为192.169.104.6

3.3.2、删除redis-cluster-0容器查看集群中IP的变化

容器重新启动之后的IP为192.169.104.9

集群中的IP已经发生改变

4、集群缩容

4.1、将之前的6个节点缩容到3个节点

4.2、删除掉之前在集群中写入的数据

4.3、恢复​redis-cluster-3节点查看数据是否会被同步

 

启动​redis-cluster-3节点

查看到redis3上的数据已经被同步

5、集群扩容

5.1、将集群节点扩容到6个

5.2、扩容之后查看写入的数据是否已经同步到 

扩容之后写入的数据能正常同步!! 

### 如何在 KubeSphere部署 Redis 主从复制集群 #### 准备工作 确保 KubernetesKubeSphere 已经正确安装并运行。对于 Redis 的主从复制配置,建议至少准备两个节点来分别作为主服务器和从服务器[^2]。 #### 使用 Helm 安装 Redis 集群 一种简便的方法是通过 Helm Chart 来部署带有主从架构的 Redis 实例。这可以通过官方仓库或其他可信来源获取合适的 Helm Charts 来完成。具体命令如下所示: ```bash helm repo add bitnami https://charts.bitnami.com/bitnami helm install my-release \ --set master.persistence.enabled=false,slave.persistence.enabled=false \ bitnami/redis ``` 上述命令会创建一个名为 `my-release` 的 Redis 发布版本,并关闭持久化选项以简化设置过程;实际生产环境中应根据需求调整这些参数。 #### 创建自定义资源定义 (CRD) 如果希望更深入地定制 Redis 配置,则可以考虑利用 KubeSphere 提供的服务网格功能或是编写 YAML 文件直接操作底层 API 对象。例如,下面是一个简单的 StatefulSet 资源清单片段用于启动带有一个 Master 及多个 Slave 的 Redis 组合: ```yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: redis-master-slave-set spec: serviceName: "redis" replicas: 3 # 设置副本数量为3意味着除了master外还有两个slaves selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - name: redis image: "docker.io/library/redis:alpine" command: ["sh", "-c"] args: - | if [ "$POD_NAME" == "$(hostname)" ]; then echo "Starting as MASTER..." exec redis-server /usr/local/etc/redis/redis.conf else echo "Starting as SLAVE of $MASTER_SERVICE_HOST:$REDIS_PORT_6379_TCP_PORT..." exec redis-server /usr/local/etc/redis/redis.conf --slaveof $(getent hosts redis-master | awk '{print $1}') 6379 fi env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: REDIS_PASSWORD valueFrom: secretKeyRef: name: redis-secret key: password ports: - containerPort: 6379 name: client --- apiVersion: v1 kind: Service metadata: name: redis-headless spec: clusterIP: None selector: app: redis ports: - port: 6379 targetPort: client --- apiVersion: v1 kind: Service metadata: name: redis-master spec: type: ClusterIP selector: app: redis ports: - port: 6379 targetPort: client ``` 此模板展示了如何基于 Pod 名称判断当前实例的角色(即 Master 或者 Slave),并通过环境变量注入必要的连接信息给各个成员[^4]。 #### 测试与验证 一旦成功部署Redis 主从集群,在终端中执行以下指令测试连通性和数据同步情况: ```bash kubectl run -i --tty --rm debug-redis --image=bitnami/redis:latest --restart=Never --command bash root@debug-redis:/# exit ``` 以上步骤能够帮助确认新建立起来的关系是否正常运作以及能否与其他组件良好交互。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值