[转帖]k8s部署有状态应用redis-cluster集群踩坑总结

k8s,部署,状态,应用,redis,cluster,集群,总结 · 浏览次数 : 0

小编点评

**问题 1:集群初始化时等待问题** * 解决方法:禁用 `#cluster-announce-ip` 选项,集群创建时节点之间才能通讯。 **问题 2:PV与PVC绑定** * 使用 `volumeClaimTemplates` 定义多个 PVC,并与 `pv` 中的 `mountPath` 属性绑定。 * `pv` 的 `storage` 属性用于定义 PV 的大小,`pvc` 的 `resources` 属性用于定义 `pv` 的申请大小。 **问题 3:PVC如何和PV一对一绑定?** * PVC 和 `pv` 可以通过 `mountPath` 属性进行绑定。 * PVC 的 `accessModes` 属性设置为 `ReadWriteMany`,表示允许多个进程对其进行读取和写入。 * PVC 的 `resources` 属性设置 `requests.storage` 和 `requests.limits.storage`,分别指定 PVC 的存储空间大小和申请空间大小。 **问题 4:节点重启后pod ip不更新** * 解决方法:在节点重启前运行 `update-node.sh`脚本。 * 该脚本在节点启动时查找 pod IP 地址并将其写入 `nodes.conf` 文件中。 * 确保 `update-node.sh`脚本在节点重启之前运行。

正文

https://segmentfault.com/a/1190000039196137

 

redis-cluster集群的部署网上一堆,用k8s部署也不在少数,但都是抄来抄去,问题不少,实际操作分享出来的还是太少。

1、redis启动配置文件,使用CofigMap来管理比较方便,redis-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
 name: redis-config
 namespace: default
data:
 update-node.sh: |
  #!/bin/sh
  REDIS_NODES="/data/nodes.conf"
  sed -i -e "/myself/ s/[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}/${MY_POD_IP}/" ${REDIS_NODES}
  exec "$@"
 redis.conf: |+
  port 7001
  protected-mode no
  cluster-enabled yes
  cluster-config-file nodes.conf
  cluster-node-timeout 15000
  #cluster-announce-ip ${MY_POD_IP}
  #cluster-announce-port 7001
  #cluster-announce-bus-port 17001
  logfile "/data/redis.log"

说明:2个文件,node-update.sh用来redis启动时执行脚本,具体后面再介绍为何要增加一个启动脚本;redis.conf为redis启动配置文件。

2、redis持久化存储pv,pv使用nfs服务存储,集群6个节点分别创建6个pv不同存储,静态创建pv文件redis-pv.yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv0
  labels:
    pv: nfs-pv0
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.11.242
    path: /root/nfs/redis-cluster0

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv1
  labels:
    pv: nfs-pv1
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.11.242
    path: /root/nfs/redis-cluster1

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv2
  labels:
    pv: nfs-pv2
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.11.242
    path: /root/nfs/redis-cluster2

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv3
  labels:
    pv: nfs-pv3
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.11.242
    path: /root/nfs/redis-cluster3

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv4
  labels:
    pv: nfs-pv4
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.11.242
    path: /root/nfs/redis-cluster4

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nfs-pv5
  labels:
    pv: nfs-pv5
spec:
  capacity:
    storage: 1Gi
  accessModes:
    - ReadWriteMany
  nfs:
    server: 192.168.11.242
    path: /root/nfs/redis-cluster5

3、使用StatefulSet创建redis-cluster集群节点和headless service

---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  labels:
    app: redis-cluster
  name: redis-cluster
  namespace: default
spec:
  replicas: 6
  selector:
    matchLabels:
      app: redis-cluster
  serviceName: redis-cluster
  template:
    metadata:
      labels:
        app: redis-cluster
    spec:
      containers:
        - command: 
            ["/bin/bash", "/usr/local/etc/redis/update-node.sh", "redis-server", "/usr/local/etc/redis/redis.conf"]
          #args:
          #  - /usr/local/etc/redis/redis.conf
          #  - --cluster-announce-ip
          #  - "$(MY_POD_IP)"
          env:
            - name: MY_POD_IP
              valueFrom:
                fieldRef:
                  fieldPath: status.podIP
            - name: TZ
              value: Asia/Shanghai
          image: 'redis:6.0.10'
          imagePullPolicy: IfNotPresent
          name: redis
          ports:
            - containerPort: 7001
              hostPort: 7001
              name: redis-port
              protocol: TCP
          volumeMounts:
            - mountPath: /data
              name: redis-cluster-data
              subPath: data
              readOnly: false
            - mountPath: /usr/local/etc/redis
              name: redis-config
              readOnly: false
      dnsPolicy: ClusterFirst
      volumes:
        - name: redis-config
          configMap:
           name: redis-config
  volumeClaimTemplates:  #PVC模板
  - metadata:
      name: redis-cluster-data
      namespace: default
    spec:
      accessModes: [ "ReadWriteMany" ]
      resources:
        requests:
          storage: 1Gi

---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: redis-cluster
  name: redis-cluster
  namespace: default
spec:
  ports:
    - name: redis-port
      port: 7001
      protocol: TCP
      targetPort: 7001
  selector:
    app: redis-cluster
  type: ClusterIP
  clusterIP: None

说明2个点:第一,update-node.sh脚本需要加上bash环境变量,否则脚本启动执行时提示没有权限,这也是网上很多文章并没有提到的;
第二,env环境变量中加了2个,${MY_POD_IP}是节点重启时更新pod的ip地址,TZ就是时区更改;

4、初始化集群
redis-cluster从4.0开始支持命令行直接初始化,不再需要安装ruby了。

kubectl exec -it redis-cluster-0 -- redis-cli -p 7001 --cluster create --cluster-replicas 1 $(kubectl get pods -l k8s.kuboard.cn/name=redis-cluster -o jsonpath='{range.items[*]}{.status.podIP}:7001 ')

5、验证集群

kubectl exec -it redis-cluster-0 -- redis-cli cluster info

redis-cluster集群部署完毕。

踩坑总结

问题1,集群初始化时,一直等待 Waiting for the cluster to join
解决:最开始部署时,从使用docker-comopose部署的方法套用过来,由于redis.conf配置文件中参数cluster-announce-ip配置了宿主机的ip,当初始化时集群节点之间需要通讯,但是再k8s中宿主机ip已经不适用,导致无法通讯一致卡住在那个位置。
禁用#cluster-announce-ip

问题2,集群创建时,[ERR] Node 10.244.7.224:7001 is not empty. Either the node already knows other nodes (check with CLUSTER NODES) or contains some key in database 0.
解决:由于前面初始化集群时卡住,导致部分节点的nodes.conf文件中更新了新节点数据,需要删除数据。可以删除文件,也可以通过如下命令
redis-cli -p 7001 -c 登录每个redis节点重置:

flushdb
cluster reset

问题3,pvc如何和pv一对一绑定?
说明:分静态和动态绑定
首先静态,之前一直没想明白,写好了pv的yaml文件,service里面定义好pvc之后,如何让pv和pvc进行绑定?只要我们定义的pv存储空间大小和pvc申请大小一致就会匹配绑定bound,当然也可以通过lebel标签来关联pvc到特定的pv。
另外,redis集群多个节点,持久化存储目录肯定不能一样,如果yaml中直接指定PVC的名字,只能指定一个名字,这样是办不到关联到多个不同的PV,于是需要volumeClaimTemplates(PVC模板)。

  volumeClaimTemplates:
  - metadata:
      name: redis-cluster-data
      namespace: default
    spec:
      accessModes: [ "ReadWriteMany" ]
      resources:
        requests:
          storage: 1Gi

动态,因为NFS不支持动态存储,所以我们需要借用这个存储插件StorageClass,关联pvc,动态创建pv。分3个步骤,1,定义storage;2,部署授权,因为storage自动创建pv需要经过kube-apiserver,所以要进行授权;3,部署自动创建pv的服务nfs-client-provisioner;4,部署redis服务。
参考链接地址:
https://blog.csdn.net/qq_2561...
以上动态创建pv确实是个好办法,后续有时间再实践操作下。
当然,如果嫌麻烦推荐使用kuboard,手动点点体验也很不错,完全不用自己这么麻烦了哈。

问题4,测试一个节点重启,发现节点重启后,nodes.conf中自己的pod ip 不会更新,倒是其他节点之间通讯会更新pod ip。
解决:上面也提到过,添加一个启动脚本update-node.sh ,每次启动查找podIP后替换nodes.conf文件中myself节点的ip地址就可以解决。注意,网上很多都是通过容器启动时在参数args里面添加pod ip来更新,但我实践过并不行,他们说5.0可以,但是我换5.0也试过并不行。如果有可以的请留言,也有可能是我配置写的不对吧。

最后,以上内容虽然不多,但绝对自己手敲的,希望能分享给大家,这也是年前的最后一篇文章,欢迎留言。

与[转帖]k8s部署有状态应用redis-cluster集群踩坑总结相似的内容:

[转帖]k8s部署有状态应用redis-cluster集群踩坑总结

https://segmentfault.com/a/1190000039196137 redis-cluster集群的部署网上一堆,用k8s部署也不在少数,但都是抄来抄去,问题不少,实际操作分享出来的还是太少。 1、redis启动配置文件,使用CofigMap来管理比较方便,redis-confi

[转帖]k8s-mtu设置不当引发的线上故障

https://www.cnblogs.com/zisefeizhu/p/16611626.html 背景 在部署新的paas平台线上环境时,突发consul和es中间件无法创建。 排查过程 以consul 通过查询k8s集群中pod状态发现原来3pod的consul集群,其中2个pod一直重启。

[转帖]k8s部署-22-yaml文件怎么写,规则是什么,在k8s中分别有什么含义

https://www.jianshu.com/p/ba5e3d9ecc1e 在前面的文章中,我们使用了较多的yaml文件,例如测试kubespary方式搭建的集群可用性,亦或者前文中我们搭建ingress-nginx的时候也是用了yaml文件,那么k8s中的yaml文件到底该如何来写,针对k8s中

[转帖]记一次flannel网络调整

https://www.jianshu.com/p/a772e4b951f2 背景 最近给一个子公司部署一套k8s集群,集群搭建完之后有几个新需求需要新增几个node节点,在新增节点时发现添加失败,经过查询发现是网络规划问题导致。 flannel启动失败,报错信息如下:Error registeri

[转帖]Kafka-Kraft 模式架构部署

news文章来源: Kafka-Kraft 模式架构部署 Kafka网址:https://kafka.apache.org/ PS:因环境原因此文档内端口都有修改! 1.去官网下载二进制包 PS:3.4.0是目前最新的版本!需要jdk1.8及以上版本启动。 [root@k8s-node1 ~]# w

[转帖]K8S部署Redis Cluster集群(三主三从模式) - 部署笔记

https://www.cnblogs.com/cheyunhua/p/15619317.html 一、Redis 介绍 Redis代表REmote DIctionary Server是一种开源的内存中数据存储,通常用作数据库,缓存或消息代理。它可以存储和操作高级数据类型,例如列表,地图,集合和排序

[转帖]k8s nginx-ingress上的配置优化

https://cloud.tencent.com/developer/article/1932188?areaSource=&traceId= 自建K8s上,如果部署了Nginx-Ingress,通常一些默认的参数有些可能需要优化下以便提升它的性能(阿里云之类的云厂商提供的Ingress是优化过的

[转帖]【k8s】1、基础概念和架构及组件

文章目录 一、kubernetes概述1、什么是kubernetes?2、应用程序部署方式的演变3、为什么要用kubernetes? 二、kubernetes 特性三、Kubernetes集群架构与核心组件1、master组件1.1 kube-apiserver(中央枢纽)1.2 kube-cont

[转帖]Kubernetes部署Minio集群存储的选择,使用DirectPV CSI作为分布式存储的最佳实践

Kubernetes部署Minio集群存储的选择,使用DirectPV CSI作为分布式存储的最佳实践 个人理解浅谈 1. 关于在kubernetes上部署分布式存储服务,K8s存储的选择 非云环境部署K8s Pod时存储的选择 在非云环境部署Kubernets时,一般采用的都是本地的直连式存储和文

[转帖]ansible 安装 K8S

作者:山河已无恙链接:https://www.zhihu.com/question/315497851/answer/2898814729来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。 写在前面分享一个 k8s 高可用集群部署的 Ansible 剧本以及涉及到的一些工