• T1级,生产环境事故—Shell脚本一键备份K8s的YAML文件


    大家好,我叫秋意零

    最近对公司进行日常运维工作时,出现了一个 T1 级别事故。导致公司的“酒云网”APP的无法使用。我和我领导一起搞了一个多小时,业务也停了一个多小时

    起因是:我的部门直系领导,叫我**删除一个 Deployemnt 资源(node-api-gateway)**说该资源不用了,因为用 go 语言重新写了一个 go-api-gateway 项目。

    由于咱们管理 K8s 集群使用的 Kuboard 系统,删除 Deployemnt 资源(node-api-gateway)时,如果没有勾选下面图中的选项的话,就会默认删除对应与之同名的 Service 和 Ingress

    之前将 Deployment(node-api-gateway) 使用 Go 重写了。而对应的 Ingress 名称与之前名称一致。所以删除了 Deployment(node-api-gateway)也连带删除了同名的 Ingress(node-api-gateway)应用的出口网关,导致此次事故。

    如果这时咱们有备份 K8s 资源的 YAML 文件的话,直接执行 kubectl apply -f ingeess-yaml文件 命令就不会出现,业务长时间停业务的情况。

    此次事情过后,第二天下午写了对应的 K8s 集群 YAML 文件备份脚本,如下:

    1)定时任务

    正式和测试环境一致

    [root@iZ8vbg3hxkp6i8fo6a5ymnZ ~]# crontab -l
    ...
    0 0 */1 * * /usr/bin/bash /a/k8s-yaml-all-bak/start.sh > /a/k8s-yaml-all-bak/yaml_bak.logs 2>&1 # 每1天执行一次
    
    • 1
    • 2
    • 3

    2)脚本功能

    1. 目录结构

    [root@iZ8vbg3hxkp6i8fo6a5ymnZ k8s-yaml-all-bak]# ll
    总用量 764
    -rw-r--r-- 1 root root    122 327 00:03 del-yaml.logs  # 删除备份yaml副本的日志
    -rw-r--r-- 1 root root    155 321 10:13 resources.txt  # 记录脚本需要备份资源
    -rwxr-xr-x 1 root root   2905 327 15:30 start.sh  # 脚本启动文件
    -rw-r--r-- 1 root root 391299 47 00:03 yaml_bak.logs  # 脚本备份日志
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 功能:

    YAML文件备份路径:/opt/k8s_yaml_bak

    备份YAML文件(方法名称:dump_yaml)

    删除30天前备份的YAML文件(方法名称:del_yaml)

    #/bin/bash
    
    #
    # K8S_YAML_SHELL_DIR:记录脚本和resources.txt存放位置,移动是需要修改其值
    # 一键备份K8s集群YAML文件脚本
    # resources.txt文件,编写需要备份资源
    #
    
    # 定时任务示例
    # 0 0 */1 * * /usr/bin/bash /a/k8s-yaml-all-bak/start.sh > /a/k8s-yaml-all-bak/yaml_bak.logs 2>&1
    # 后台运行示例
    # nohup /usr/bin/bash /a/k8s-yaml-all-bak/start.sh > /a/k8s-yaml-all-bak/yaml_bak.logs 2>&1 &
    
    
    # 当前时间
    DATE=`date +%Y-%m-%d--%H-%M-%S`
    
    # 备份路径
    K8S_YAML_BACKUP_DIR="/opt/k8s_yaml_bak"
    
    
    # 脚本存放目录
    K8S_YAML_SHELL_DIR="/a/k8s-yaml-all-bak"
    
    
    if [ ! -d $K8S_YAML_BACKUP_DIR ];then
       mkdir -p $K8S_YAML_BACKUP_DIR
    fi
    
    # 获取备份资源
    if [ -f ${K8S_YAML_SHELL_DIR}/resources.txt ];then
       RESOURCES=`cat ${K8S_YAML_SHELL_DIR}/resources.txt`
       # 判断资源文件是否为空
       if [[ $RESOURCES == "" ]]; then
                    echo "${DATE} ${K8S_YAML_SHELL_DIR}/resources.txt 文件为空,请输入资源名称"
                    exit 1
       fi
    else
       echo "resources.txt文件,不存在!"
       exit 1
    fi
    
    
    
    # 每次备份单独创建一个家目录+时间
    mkdir -p ${K8S_YAML_BACKUP_DIR}/k8s-${DATE}
    
    # 获取家目录
    GET_HOME_DIR=`ls -l ${K8S_YAML_BACKUP_DIR} | tail -n 1 | awk '{print $9}'`
    
    echo "备份路径:$K8S_YAML_BACKUP_DIR/$GET_HOME_DIR"
    
    # 获取k8s名称空间
    NAMESPACE=`kubectl get ns | awk '{print $1}' | tail -n +2`
    
    
    dump_yaml(){
            # 遍历NS
            for NS in $NAMESPACE ;do
              # 创建NS备份目录
              mkdir -p ${K8S_YAML_BACKUP_DIR}/${GET_HOME_DIR}/${NS}
    
              # 过滤NS(kube-public、kube-system)
              if [[ $NS != "kube-public" && $NS != "kube-system" && $NS != "csdr" && $NS != "kube-node-lease" ]]; then
                 # 遍历k8s资源
                 for RESOURCE in $RESOURCES; do
                  # 创建资源目录
                  mkdir -p ${K8S_YAML_BACKUP_DIR}/${GET_HOME_DIR}/${NS}/${RESOURCE}
    
                  # 遍历对应资源名称
                   for RESOURCE_NAME in $(kubectl get $RESOURCE -n $NS | awk '{print $1}' | tail -n +2);do
                      DATE_YAML=`date +%Y-%m-%d--%H:%M:%S`
                      echo "${DATE_YAML} 导出YAML: ${NS} ${RESOURCE} ${RESOURCE_NAME} "
                      # 导出对应名称空间下对应资源的yaml
                      kubectl get ${RESOURCE} ${RESOURCE_NAME} -n ${NS}  -o yaml > ${K8S_YAML_BACKUP_DIR}/${GET_HOME_DIR}/$NS/${RESOURCE}/${RESOURCE_NAME}.yaml
                      echo ""
                   done
                 done
              fi
            done
    }
    
    
    del_yaml(){
            for DIR_NAME in $(find $K8S_YAML_BACKUP_DIR -type d  -mtime +7);do
              DATE_YAML=`date +%Y-%m-%d--%H:%M:%S`
              echo "${DATE_YAML} 删除:$DIR_NAME" > ${K8S_YAML_SHELL_DIR}/del-yaml.logs
              rm -rf $DIR_NAME  >> ${K8S_YAML_SHELL_DIR}/del-yaml.logs
              echo ""  >> ${K8S_YAML_SHELL_DIR}/del-yaml.logs
            done
    }
    
    dump_yaml
    del_yaml
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
  • 相关阅读:
    对象头markword-锁升级
    在Winform分页控件中集成保存用户列表显示字段及宽度调整设置
    Mysql_锁_表锁和全局锁
    无人机通信协议MAVLink简介
    flutter代码中使用Android/ios原生生命周期
    Mac怎么清理磁盘空间?释放Mac磁盘空间有效方法
    7. 用Rust手把手编写一个wmproxy(代理,内网穿透等), HTTP及TCP内网穿透原理及运行篇
    C++特殊成员函数及其生成机制
    vue按键全屏和F11全屏共存
    Vue3.3指北(三)
  • 原文地址:https://blog.csdn.net/qq_48450494/article/details/138037022