当前位置: 首页 > article >正文

k8s上面的Redis集群链接不上master的解决办法

  • 问题描述

之前在k8s上面部署了一台node,然后创建了6个redis的pod,构建了一个redis的集群,正常运行。

最近添加了一台slave node,然后把其中的几个redis的pod调度到了slave node上面,结果集群就起不来了,看了下log报如下错误:

127.0.0.1:6379> get test
(error) CLUSTERDOWN The cluster is down


127.0.0.1:6379> cluster info
cluster_state:fail
cluster_slots_assigned:16384
cluster_slots_ok:0
cluster_slots_pfail:16384
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:14
cluster_my_epoch:14
cluster_stats_messages_ping_sent:4
cluster_stats_messages_sent:4
cluster_stats_messages_received:0
total_cluster_links_buffer_limit_exceeded:0


$ kubectl logs redis-app-5
... ...
1:S 19 Nov 2024 01:58:13.251 * Connecting to MASTER 172.16.43.44:6379
1:S 19 Nov 2024 01:58:13.251 * MASTER <-> REPLICA sync started
1:S 19 Nov 2024 01:58:13.251 * Cluster state changed: ok
1:S 19 Nov 2024 01:58:20.754 # Cluster state changed: fail
1:S 19 Nov 2024 01:59:14.979 # Timeout connecting to the MASTER...
1:S 19 Nov 2024 01:59:14.979 * Reconnecting to MASTER 172.16.43.44:6379 after failure
1:S 19 Nov 2024 01:59:14.979 * MASTER <-> REPLICA sync started
1:S 19 Nov 2024 02:00:15.422 # Timeout connecting to the MASTER...
1:S 19 Nov 2024 02:00:15.422 * Reconnecting to MASTER 172.16.43.44:6379 after failure
1:S 19 Nov 2024 02:00:15.422 * MASTER <-> REPLICA sync started
1:S 19 Nov 2024 02:01:16.357 # Timeout connecting to the MASTER...
1:S 19 Nov 2024 02:01:16.357 * Reconnecting to MASTER 172.16.43.44:6379 after failure
1:S 19 Nov 2024 02:01:16.357 * MASTER <-> REPLICA sync started
  • 问题分析

这种情况是redis的pod已经重新启动了,相应的ip地址可能已经变掉了,但是集群部署还是按照重启之前的配置来的,所以导致启动失败。

  • 我的解决办法:

  1. 首先查看各个redis pod的信息
    $  kubectl describe pod redis-app | grep IP
                      cni.projectcalico.org/podIP: 172.16.178.201/32
                      cni.projectcalico.org/podIPs: 172.16.178.201/32
    IP:               172.16.178.201
    IPs:
      IP:           172.16.178.201
                      cni.projectcalico.org/podIP: 172.16.178.202/32
                      cni.projectcalico.org/podIPs: 172.16.178.202/32
    IP:               172.16.178.202
    IPs:
      IP:           172.16.178.202
                      cni.projectcalico.org/podIP: 172.16.43.1/32
                      cni.projectcalico.org/podIPs: 172.16.43.1/32
    IP:               172.16.43.1
    IPs:
      IP:           172.16.43.1
                      cni.projectcalico.org/podIP: 172.16.178.203/32
                      cni.projectcalico.org/podIPs: 172.16.178.203/32
    IP:               172.16.178.203
    IPs:
      IP:           172.16.178.203
                      cni.projectcalico.org/podIP: 172.16.43.63/32
                      cni.projectcalico.org/podIPs: 172.16.43.63/32
    IP:               172.16.43.63
    IPs:
      IP:           172.16.43.63
                      cni.projectcalico.org/podIP: 172.16.178.204/32
                      cni.projectcalico.org/podIPs: 172.16.178.204/32
    IP:               172.16.178.204
    IPs:
      IP:           172.16.178.204
    
    
    
    $ kubectl get pods -o wide
    NAME                                 READY   STATUS    RESTARTS         AGE     IP               NODE       NOMINATED NODE   READINESS GATES
    redis-app-0                          1/1     Running   0                2m34s   172.16.178.201   kevin-s1   <none>           <none>
    redis-app-1                          1/1     Running   0                2m32s   172.16.178.202   kevin-s1   <none>           <none>
    redis-app-2                          1/1     Running   0                2m30s   172.16.43.1      kevin-pc   <none>           <none>
    redis-app-3                          1/1     Running   0                2m26s   172.16.178.203   kevin-s1   <none>           <none>
    redis-app-4                          1/1     Running   0                2m24s   172.16.43.63     kevin-pc   <none>           <none>
    redis-app-5                          1/1     Running   0                2m19s   172.16.178.204   kevin-s1   <none>           <none>
    
    
  2. 然后通过inem0o/redis-trib根据pods的最新ip重新创建集群
    $ sudo docker run --rm -ti inem0o/redis-trib create --replicas 1 172.16.178.201:6379 172.16.178.202:6379 172.16.43.1:6379 172.16.43.63:6379 172.16.178.204:6379 172.16.178.203:6379
  3. 在创建集群的过程中可能会遇到下面这个错误
$ sudo docker run --rm -ti inem0o/redis-trib create --replicas 1 172.16.178.201:6379 172.16.178.202:6379 172.16.43.1:6379 172.16.43.63:6379 172.16.178.204:6379 172.16.178.203:6379
>>> Creating cluster
[ERR] Node 172.16.178.201:6379 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.

 这种情况是因为redis的pod没有被重置,需要登录出问题的pod然后用redis-cii重置集群

$ kubectl exec -it redis-app-0 -- redis-cli -h 172.16.178.201 -p 6379
172.16.178.201:6379> CLUSTER RESET
OK

出问题的pod全部重置完之后再执行上面的命令,集群重新构建成功

$ sudo docker run --rm -ti inem0o/redis-trib create --replicas 1 172.16.178.201:6379 172.16.178.202:6379 172.16.43.1:6379 172.16.43.63:6379 172.16.178.204:6379 172.16.178.203:6379
>>> Creating cluster
>>> Performing hash slots allocation on 6 nodes...
Using 3 masters:
172.16.178.201:6379
172.16.178.202:6379
172.16.43.1:6379
Adding replica 172.16.43.63:6379 to 172.16.178.201:6379
Adding replica 172.16.178.204:6379 to 172.16.178.202:6379
Adding replica 172.16.178.203:6379 to 172.16.43.1:6379
M: 57d9f345d23e7bf7dd2f331e14d9d7143aa9617f 172.16.178.201:6379
   slots:0-5460 (5461 slots) master
M: f5d617c0ed655dd6afa32c5d4ec6260713668639 172.16.178.202:6379
   slots:5461-10922 (5462 slots) master
M: 808de7e00f10fe17a5582cd76a533159a25006d8 172.16.43.1:6379
   slots:10923-16383 (5461 slots) master
S: 44ac042b99b9b73051b05d1be3d98cf475f67f0a 172.16.43.63:6379
   replicates 57d9f345d23e7bf7dd2f331e14d9d7143aa9617f
S: 8db8f89b7b28d0ce098de275340e3c4679fd342d 172.16.178.204:6379
   replicates f5d617c0ed655dd6afa32c5d4ec6260713668639
S: 2f5860e62f03ea17d398bbe447a6f1d428ae8698 172.16.178.203:6379
   replicates 808de7e00f10fe17a5582cd76a533159a25006d8
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join.
>>> Performing Cluster Check (using node 172.16.178.201:6379)
M: 57d9f345d23e7bf7dd2f331e14d9d7143aa9617f 172.16.178.201:6379
   slots:0-5460 (5461 slots) master
   1 additional replica(s)
S: 44ac042b99b9b73051b05d1be3d98cf475f67f0a 172.16.43.63:6379@16379
   slots: (0 slots) slave
   replicates 57d9f345d23e7bf7dd2f331e14d9d7143aa9617f
M: f5d617c0ed655dd6afa32c5d4ec6260713668639 172.16.178.202:6379@16379
   slots:5461-10922 (5462 slots) master
   1 additional replica(s)
S: 8db8f89b7b28d0ce098de275340e3c4679fd342d 172.16.178.204:6379@16379
   slots: (0 slots) slave
   replicates f5d617c0ed655dd6afa32c5d4ec6260713668639
S: 2f5860e62f03ea17d398bbe447a6f1d428ae8698 172.16.178.203:6379@16379
   slots: (0 slots) slave
   replicates 808de7e00f10fe17a5582cd76a533159a25006d8
M: 808de7e00f10fe17a5582cd76a533159a25006d8 172.16.43.1:6379@16379
   slots:10923-16383 (5461 slots) master
   1 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

查看集群状态:

$ kubectl exec -it redis-app-3 -- redis-cli
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:14
cluster_my_epoch:3
cluster_stats_messages_ping_sent:39
cluster_stats_messages_pong_sent:40
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:80
cluster_stats_messages_ping_received:40
cluster_stats_messages_pong_received:36
cluster_stats_messages_received:76
total_cluster_links_buffer_limit_exceeded:0

至此问题解决。

=========================================================================

2024.11.20更新

=========================================================================

因为重启node之后,node上面的pod也会被重启,而redis pod 的IP地址是启动时候随机分配的,所以重启node可能会导致集群再次down掉,另一种解决办法就是在构建集群的时候,使用各个redis pod的DNS名称构造,DNS名称的格式是:

<statefulset-name>-<ordinal>.<service-name>.<namespace>.svc.cluster.local

其中的<statefulset-name><service-name>和<namespace>可以从redis-stateful.yaml里面获取到

-<ordinal>就是instance的编号

例如下面这个redis-stateful.yaml

$ cat redis-stateful.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: redis-app
spec:
  serviceName: redis-service
  replicas: 6
  selector:
    matchLabels:
      app: redis
      appCluster: redis-cluster
  template:
    metadata:
      labels:
        app: redis
        appCluster: redis-cluster
    spec:
      containers:
      - name: redis
        image: redis
        imagePullPolicy: IfNotPresent
        command: ["/bin/bash", "-ce", "tail -f /dev/null"]
        command: ["redis-server"]
        args:
          - "/etc/redis/redis.conf"
          - "--protected-mode"
          - "no"
        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: "redis"
      resources:
        requests:
          storage: 1Gi

其中

<statefulset-name>是redis-app

<service-name>是redis-service

<namespace>默认为default (你可以配置自己的namespace)

因为起了6个节点,所以<ordinal>是0~5

有了以上信息,那么构造集群的命令就是

$ kubectl exec -it redis-app-0 -n default -- redis-cli --cluster create 
redis-app-1.redis-service.default.svc.cluster.local:6379 
redis-app-2.redis-service.default.svc.cluster.local:6379 
redis-app-3.redis-service.default.svc.cluster.local:6379 
redis-app-4.redis-service.default.svc.cluster.local:6379 
redis-app-5.redis-service.default.svc.cluster.local:6379 
redis-app-0.redis-service.default.svc.cluster.local:6379 --cluster-replicas 1

至此redis集群构造成功,重启node之后,集群的节点还是可以通过DNS name连接成功。

127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:15
cluster_my_epoch:15
cluster_stats_messages_ping_sent:1204
cluster_stats_messages_pong_sent:1195
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:2400
cluster_stats_messages_ping_received:1195
cluster_stats_messages_pong_received:1200
cluster_stats_messages_received:2395
total_cluster_links_buffer_limit_exceeded:0


http://www.kler.cn/a/406841.html

相关文章:

  • 快速图像识别:落叶植物叶片分类
  • 智能工厂的设计软件 为了监管控一体化的全能Supervisor 的监督学习 之 序7 进化论及科学的信息技术创新:分布式账本/区块链/智能合约
  • flex布局 昵图网【案例】
  • 深度学习3
  • 使用docker快速部署Nginx、Redis、MySQL、Tomcat以及制作镜像
  • javaScript交互案例
  • Powershell 命令行窗口 设置行宽、折行、行省略
  • IText创建加盖公章的pdf文件并生成压缩文件
  • 高级java每日一道面试题-2024年11月22日-JVM篇-说说堆和栈的区别?
  • 纯HTMLCSS实现3D旋转地球
  • 嵌入式C语言面试题 - 2024/11/18
  • 【HM-React】01. React基础-上
  • element-plus教程:Layout 布局
  • 从容器到Podman:一个全方位的剖析
  • 电子应用设计方案-20:智能电冰箱系统方案设计
  • 人工智能与自动驾驶:从梦想到现实
  • 事务、视图、索引
  • Kafka-Consumer理论知识
  • “iOS profile文件与私钥证书文件不匹配”总结打ipa包出现的问题
  • R package安装的几种方式
  • gstream插件编译笔记【1.16.3】
  • 仿axios,封装微信小程序的请求
  • Vue移动端网页(H5)预览pdf文件(pdfh5和vue-pdf)(很详细)
  • RHCD-----shell
  • 【Isaac Sim】相关问题汇总
  • CANDENCE: 绘制好的封装元件 刷新(Refresh) 和 替换 (Replace)焊盘