K8S 部署redis单节点&rdb数据持久化&故障演练恢复

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

 

环境:

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

背景: 采用NFS存储卷的方式 持久化存储redis 需要保存的文件

一、部署NFS服务器

#服务器安装nfs服务,提供nfs存储功能
1、安装nfs-utils
yum install nfs-utils (centos)
或者 	apt-get install nfs-kernel-server (ubuntu)

2、启动服务
systemctl enable nfs-server
systemctl start nfs-server

3、创建共享目录完成共享配置
mkdir /home/nfs   #创建共享目录

4、编辑共享配置
vim /etc/exports                                           
#语法格式: 共享文件路径 客户机地址(权限) #这里的客户机地址可以是IP,网段,域名,也可以是任意*
/home/nfs  *(rw,async,no_root_squash)
服务自检命令 
exportfs -arv


5、重启服务
systemctl restart nfs-server


6、本机查看nfs 共享目录
#showmount -e 服务器IP地址 (如果提示命令不存在,则需要yum install showmount)

showmount -e 127.0.0.1
/home/nfs *



7、客户端模拟挂载[所有k8s的节点都需要安装客户端]
[root@master-1 ~]# yum install nfs-utils (centos)
或者  apt-get install nfs-common (ubuntu)
[root@master-1 ~]# mkdir /test
[root@master-1 ~]# mount -t nfs 172.16.201.209:/home/nfs /test

#取消挂载
[root@master-1 ~]# umount /test

二、配置PV 动态供给(NFS StorageClass),创建pvc

#部署NFS实现自动创建PV插件: 一共设计到4个yaml 文件 ,官方的文档有详细的说明

https://github.com/kubernetes-incubator/external-storage

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

root@k8s-master1:~ # mkdir /root/pvc
root@k8s-master1:~ # cd /root/pvc
  • 创建rbac.yaml 文件
root@k8s-master1:pvc # cat rbac.yaml 
kind: ServiceAccount
apiVersion: v1
metadata:
  name: nfs-client-provisioner
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "create", "delete"]
  - apiGroups: [""]
    resources: ["persistentvolumeclaims"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["storageclasses"]
    verbs: ["get", "list", "watch"]
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: default
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io
  • 创建deployment.yaml 文件

#官方默认的镜像地址,国内可能无法下载,可以使用 image:
fxkjnj/nfs-client-provisioner:latest

#定义NFS 服务器的地址,共享目录名称

root@k8s-master1:pvc # cat deployment.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
---
kind: Deployment
apiVersion: apps/v1 
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: fxkjnj/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 172.16.201.209 
            - name: NFS_PATH
              value: /home/nfs
      volumes:
        - name: nfs-client-root
          nfs:
            server: 172.16.201.209
            path: /home/nfs
  • 创建class.yaml

# archiveOnDelete: “true” 表示当PVC 删除后,后端数据不直接删除,而是归档

root@k8s-master1:pvc # cat class.yaml 
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: managed-nfs-storage
provisioner: fuseim.pri/ifs # or choose another name, must match deployment's env PROVISIONER_NAME'
parameters:
  archiveOnDelete: "true"
  • 创建pvc.yaml

#指定storageClassName 存储卷的名字

# requests:

storage: 100Gi 指定需要多大的存储

#注意,这里pvc ,我们创建在redis 命名空间下了,如果没有redis 还需要先创建才行, kubectl create namespace redis

root@k8s-master1:pvc # cat pvc.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nfs-redis
  namespace: redis
spec:
  storageClassName: "managed-nfs-storage"
  accessModes:
    - ReadWriteMany     
  resources:
    requests:
      storage: 100Gi
#部署
root@k8s-master1:pvc # kubectl apply -f .


#查看存储卷
root@k8s-master1:pvc # kubectl get sc
NAME                  PROVISIONER      RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
managed-nfs-storage   fuseim.pri/ifs   Delete          Immediate           false                  25h


#查看pvc
root@k8s-master1:pvc # kubectl get pvc -n redis
NAME        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS          AGE
nfs-redis   Bound    pvc-8eacbe25-3875-4f78-91ca-ba83b6967a8a   100Gi      RWX            managed-nfs-storage   21h

三、编写redis yaml 文件

root@k8s-master1:~ # mkdir /root/redis
root@k8s-master1:~ # cd /root/redis
  • 编写 redis.conf 配置文件,以configmap 的方式挂载到容器中

# require 配置redis 密码

#save 5 1 ,表示 每5秒有一个key 变动 就写入到 dump.rdb 文件中

# appendonly no ,表示下次可以使用dump.rdb 来恢复 redis 快照的数据

# 注意namespace 为redis

root@k8s-master1: redis# cat redis-configmap-rdb.yml 
kind: ConfigMap
apiVersion: v1
metadata:
  name: redis-config
  namespace: redis
  labels:
    app: redis
data:
    redis.conf: |-
    protected-mode no
    port 6379
    tcp-backlog 511
    timeout 0
    tcp-keepalive 300
    daemonize no
    supervised no
    pidfile /data/redis_6379.pid
    loglevel notice
    logfile ""
    databases 16
    always-show-logo yes
    save 5 1
    save 300 10
    save 60 10000
    stop-writes-on-bgsave-error yes
    rdbcompression yes
    rdbchecksum yes
    dbfilename dump.rdb
    dir /data
    replica-serve-stale-data yes
    replica-read-only yes
    repl-diskless-sync no
    repl-diskless-sync-delay 5
    repl-disable-tcp-nodelay no
    replica-priority 100
    requirepass 123
    lazyfree-lazy-eviction no
    lazyfree-lazy-expire no
    lazyfree-lazy-server-del no
    replica-lazy-flush no
    appendonly no
    appendfilename "appendonly.aof"
    appendfsync everysec
    no-appendfsync-on-rewrite no
    auto-aof-rewrite-percentage 100
    auto-aof-rewrite-min-size 64mb
    aof-load-truncated yes
    aof-use-rdb-preamble yes
    lua-time-limit 5000
    slowlog-log-slower-than 10000
    slowlog-max-len 128
    latency-monitor-threshold 0
    notify-keyspace-events ""
    hash-max-ziplist-entries 512
    hash-max-ziplist-value 64
    list-max-ziplist-size -2
    list-compress-depth 0
    set-max-intset-entries 512
    zset-max-ziplist-entries 128
    zset-max-ziplist-value 64
    hll-sparse-max-bytes 3000
    stream-node-max-bytes 4096
    stream-node-max-entries 100
    activerehashing yes
    client-output-buffer-limit normal 0 0 0
    client-output-buffer-limit replica 256mb 64mb 60
    client-output-buffer-limit pubsub 32mb 8mb 60
    hz 10
    dynamic-hz yes
    aof-rewrite-incremental-fsync yes
    rdb-save-incremental-fsync yes
  • 编写 redis-deployment.yml

#注意namespace 为redis

root@k8s-master1: redis# cat redis-deployment.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  namespace: redis
  labels:
    app: redis
spec:
  replicas: 3
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      # 进行初始化操作,修改系统配置,解决 Redis 启动时提示的警告信息
      initContainers:
        - name: system-init
          image: busybox:1.32
          imagePullPolicy: IfNotPresent
          command:
            - "sh"
            - "-c"
            - "echo 2048 > /proc/sys/net/core/somaxconn && echo never > /sys/kernel/mm/transparent_hugepage/enabled"
          securityContext:
            privileged: true
            runAsUser: 0
          volumeMounts:
          - name: sys
            mountPath: /sys
      containers:
        - name: redis
          image: redis:5.0.8
          command:
            - "sh"
            - "-c"
            - "redis-server /usr/local/etc/redis/redis.conf"
          ports:
            - containerPort: 6379
          resources:
            limits:
              cpu: 1000m
              memory: 1024Mi
            requests:
              cpu: 1000m
              memory: 1024Mi
          livenessProbe:
            tcpSocket:
              port: 6379
            initialDelaySeconds: 300
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          readinessProbe:
            tcpSocket:
              port: 6379
            initialDelaySeconds: 5
            timeoutSeconds: 1
            periodSeconds: 10
            successThreshold: 1
            failureThreshold: 3
          volumeMounts:
            - name: data
              mountPath: /data
            - name: config
              mountPath: /usr/local/etc/redis/redis.conf
              subPath: redis.conf
      volumes:
        - name: data
          persistentVolumeClaim:
            claimName: nfs-redis
        - name: config
          configMap:
            name: redis-config
        - name: sys
          hostPath:
            path: /sys
  • 编写 redis-service.yml

#注意namespace 为redis

#部署
root@k8s-master1:~/kubernetes/redis# kubectl get pod -n redis
NAME                     READY   STATUS    RESTARTS   AGE
redis-65f75db6bc-5skgr   1/1     Running   0          21h
redis-65f75db6bc-75m8m   1/1     Running   0          21h
redis-65f75db6bc-cp6cx   1/1     Running   0          21h

root@k8s-master1:~/kubernetes/redis# kubectl get svc -n redis
NAME          TYPE       CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
redis-front   NodePort   10.0.0.169   <none>        6379:36379/TCP   22h

四、测试,访问

使用redis 客户端工具,写入几个KEY 测试

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

  • 删除pod,在自动新建pod后,查询键值是否存在
root@k8s-master1:~# kubectl get pods -n redis
NAME                     READY   STATUS    RESTARTS   AGE
redis-65f75db6bc-5skgr   1/1     Running   0          5d20h
redis-65f75db6bc-75m8m   1/1     Running   0          5d20h
redis-65f75db6bc-cp6cx   1/1     Running   0          5d20h

root@k8s-master1:~# kubectl delete -n redis pod redis-65f75db6bc-5skgr 
pod "redis-65f75db6bc-5skgr" deleted


#删除pod后,根据副本数,又重新拉取新的pod生成
root@k8s-master1:~# kubectl get pods -n redis
NAME                     READY   STATUS    RESTARTS   AGE
redis-65f75db6bc-tnnxp   1/1     Running   0          54s
redis-65f75db6bc-75m8m   1/1     Running   0          5d20h
redis-65f75db6bc-cp6cx   1/1     Running   0          5d20h

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

查看nfs共享目录下是否存在 dump.rdb

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

五、故障演练恢复

(1)、数据备份

  • 源redis配置有持久化,直接拷贝持久化目录下的dump.rdb

直接到持久化的目录下,拷贝走dump.rdb 文件

  • 源redis不支持持久化,则进入容器生成dump.rdb并拷出

进入容器:kubectl exec -it redis-xxx /bin/bash -n redis

进入redis命令台:redis-cli

密码认证:auth 123

保存数据,生成dump.rdb文件:save

退出redis命令台:quit

退出容器:exit

从容器中取出数据到本地:kubectl cp -n redis Pod_Name:/data/dump.rdb ./

传输至远程主机:scp dump.rdb root@目标服务器:/目录

(2)、数据恢复

  • 停止redis,直接删除创建的deployment
  • 拷贝dump.rdb至目标redis的持久化目录下(注:将覆盖目标redis的数据)
  • 重启pod:kubectl apply -f redis-deployment.yml
#拷贝持久化目录下的dump.rbd文件 到root 下
cp dump.rdb /root

#停止redis,也就是删除deployment
root@k8s-master1:~/kubernetes/redis# kubectl delete -f redis-deployment.yml 
deployment.apps "redis" deleted

root@k8s-master1:~/kubernetes/redis# kubectl get pods -n redis
No resources found in redis namespace.

#拷贝dump.rdb至目标redis的持久化目录下
cp /root/dump.rdb   /home/nfs/redis-nfs-redis-pvc-8eacbe25-3875-4f78-91ca-ba83b6967a8a

#重启pod
root@k8s-master1:~/kubernetes/redis# kubectl apply -f redis-deployment.yml 
deployment.apps/redis created

root@k8s-master1:~/kubernetes/redis# kubectl get pods -n redis
NAME                     READY   STATUS     RESTARTS   AGE
redis-65f75db6bc-5jx4m   0/1     Init:0/1   0          3s
redis-65f75db6bc-68jf5   0/1     Init:0/1   0          3s
redis-65f75db6bc-b9gvk   0/1     Init:0/1   0          3s

root@k8s-master1:~/kubernetes/redis# kubectl get pods -n redis
NAME                     READY   STATUS    RESTARTS   AGE
redis-65f75db6bc-5jx4m   1/1     Running   0          20s
redis-65f75db6bc-68jf5   1/1     Running   0          20s
redis-65f75db6bc-b9gvk   1/1     Running   0          20s

(3)、验证数据,可发现源redis的数据已全部复现

K8S 部署redis单节点&rdb数据持久化&故障演练恢复

2021/10/26 南京 晴

文章来源:https://www.cnaaa.net,转载请注明出处:https://www.cnaaa.net/archives/7097

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年2月7日 下午5:43
下一篇 2023年2月8日 下午6:09

相关推荐

  • Docker常用命令

    列出所有容器ID 查看所有运行或者不运行容器 停止所有的container(容器),这样才能够删除其中的images: 如果想要删除所有container(容器)的话再加一个指令: 查看当前有些什么images 删除images(镜像),通过image的id来指定删除谁 想要删除untagged images,也就是那些id为的image的话可以用 要删除全…

    2022年11月19日
    9300
  • kubernetes集群搭建Zabbix监控平台的详细过程

    一、框架图 二、环境 名称 版本 操作系统 IP 备注 K8S 集群 1.24.1 centos7.9 172.16.201.30,172.16.201.31,172.16.201.32 k8s-master01,k8s-node1, k8s-node2 zabbix 6.2.6 centos7.9 zabbix-server,zabbix-proxy,za…

    2023年1月20日
    8800
  • Ubuntu系统如何配置镜像源

    我们在使用Linux系统时,一般来说都是需要配置一个源地址才能直接使用下载的命令来安装软件的,若你购买的是云服务器,正常来讲是服务器厂商配置好了源的,但是也不缺乏有少量的机器源会出现问题,导致安装软件不成功,如下图所示,那么我们就需要手动去配置了 第一步:替换原有的源 第二步:安装证书 如果安装失败,重新安装即可

    2022年6月14日
    34300
  • Linux下查找并删除挖矿程序实例

    症状表现 从外网连接服务器时,间接性断开特别频繁。在断开的时候,从内网也连接不上 排查方法 从链路等硬件方面去排查 通过zabbix监控的服务器的端口,发现这个服务器一直在间断性占用1000M带宽,实际客户购买的带宽15M,这就是客户间断性频繁断网的原因。 在排除了线路等相关问题后,将问题锁定在客户系统内。 在软件中排查 在Linux系统中,我们可以使用to…

    2022年6月14日
    30900
  • kubernetes弹性伸缩之 Pod基于HPA_实现自动扩容/缩容

    kubernetes弹性伸缩之 Pod基于HPA_实现自动扩容/缩容 Pod自动扩容/缩容:HPA介绍 Horizontal Pod Autoscaler(HPA,Pod水平自动伸缩):根据资源利用率或者自定义指 标自动调整Deployment的Pod副本数量,提供应用并发。HPA不适于无法缩放的对象,例 如DaemonSet。 Pod自动扩容/缩容:HPA…

    2023年2月3日
    4600

在线咨询: QQ交谈

邮件:712342017@qq.com

工作时间:周一至周五,8:30-17:30,节假日休息

关注微信