美文网首页
Docker镜像服务器磁盘空间清理

Docker镜像服务器磁盘空间清理

作者: 蜀山_竹君子 | 来源:发表于2020-11-26 18:00 被阅读0次

    我们开发环境Jenkins构建项目时报服务器磁盘空间不足,导致项目自动化构建部署失败,


    构建错误日志

    Docker镜像服务器磁盘空间清理我们做了多次了,之前在清理Docker镜像服务器时走了不少弯路,查了不少Docker镜像服务器空间清理,都大同小异,都是一些如何清理历史镜像文件的文章,而实际按照清理镜像文件进行一顿操作,释放的内存了了,最近一次磁盘空间报警事件,镜像文件清理也就才清理了40M,完全达不到清理磁盘空间的效果。
    事实上我们的镜像执行sh脚本本身包含清理垃圾镜像文件的步骤:

    #!/usr/bin/env bash
    app_name='xxxx'
    docker stop ${app_name}
    echo '----stop container----'
    docker rm ${app_name}
    echo '----rm container----'
    docker rmi `docker images | grep none | awk '{print $3}'`
    echo '----rm none images----'
    docker run -e TZ="Asia/Shanghai" -p 7200:7200 -p 8734:8734  --name ${app_name} \
    --link registry2:registry2 \
    -v /etc/localtime:/etc/localtime \
    -v /usr/local/server-log/xxxx:/logs \
    -d ${app_name}:latest
    echo '----start container----'
    ~
    

    因此,重要事情说三遍:当Docker镜像服务器磁盘空间不足时,首先要考虑的时服务器的日志文件、大文件等等,最后才考虑Docker镜像本身占用的磁盘内存

    磁盘清理思路分享

    du与df命令结合

    df命令

    df命令用于查看磁盘分区的使用情况,了解磁盘总量及用量,默认单位为KB。
    当磁盘空间报警时,我们可以使用df命令查看磁盘分区使用情况:



    注意,使用df -h命令会看到Docker镜像的/var/lib/docker 目录占很多空间,其实这是假象,许多同事初次看到这个接口首先应该就是去考虑如何清理/var/lib/docker,我也不例外。
    不要受/var/lib/docker 目录影响,继续分析空间占用情况。

    du命令

    前面通过df命名我们大致了解了我们磁盘分区内存使用情况,使用du命令可以当前目录下文件、目录在磁盘中占用的空间的大小。
    来到服务器顶层目录,执行命令:

    du -sh *
    

    找到内存使用异常的文件夹,进入其目录依次执行du -sh *,最终找到占用内存的大文件或日志,进行清理。
    分享下我在情况过程找到的大文件


    清理镜像

    通过前面df 和du配合分析清理空间后,基本就能释放服务器磁盘空间,就简单提下Docker镜像清理咯,毕竟网上一大堆。
    镜像清理。

    docker image prune -f 
    

    批量清除无用的镜像

    docker images | awk 'NR!=1{print $1":"$2}' | xargs docker rmi
    

    清理日志

    • 清理文件
    删除当前目录下的文件
    
    1.rm -f *
    
    #最经典的方法,删除当前目录下的所有类型的文件
    
    2.find . -type f -delete或find . -type f -exec rm -f {} \;
    
    #用find命令查找普通文件并删除or用find命令的处理动作将其删除
    
    3.find . -type f | xargs rm -f
    
    • 清理指定nacos logs
    ## 清理 7 天前的日志文件
    sh clear-logs.sh -p /usr/local/nacos/conf/logs -d 7
    
    • 定时清除
    $ crontab -e
    0 1 * * * sh /home/nacos/clear-logs.sh -p /home/nacos/nacos/logs -d 7
    
    • 脚本
      clear-logs.sh
    #!/bin/bash
    #================================================================
    # HEADER
    #================================================================
    #    Filename         clear-logs.sh
    #    Revision         0.0.1
    #    Date             2020/06/05
    #    Author           jiangliheng
    #    Email            jiang_liheng@163.com
    #    Website          https://jiangliheng.github.io/
    #    Description      删除 N 天前的日志文件
    #    Copyright        Copyright (c) jiangliheng
    #    License          GNU General Public License
    #
    #================================================================
    #
    #  Version 0.0.1 2020/06/05
    #     删除 N 天前的日志文件,仅删除匹配  "*.log*"  的日志文件
    #
    #================================================================
    #%名称(NAME)
    #%       ${SCRIPT_NAME} - 删除 N 天前的日志文件
    #%
    #%概要(SYNOPSIS)
    #%       sh ${SCRIPT_NAME} [options] <value> ...
    #%
    #%描述(DESCRIPTION)
    #%       删除 N 天前的日志文件,仅删除匹配  "*.log*"  的日志文件
    #%
    #%选项(OPTIONS)
    #%       -p <value>                 删除日志的路径,必输参数
    #%       -d <value>                 删除 N 天前的日志文件,即保留 N 天日志,默认:7
    #%       --help                     帮助信息
    #%       -v, --version              版本信息
    #%
    #%示例(EXAMPLES)
    #%
    #%       1. 清理 7 天前的日志文件
    #%       sh ${SCRIPT_NAME} -p /home/nacos/logs
    #%       sh ${SCRIPT_NAME} -p /home/nacos/logs -d 7
    #%
    #%       2. 清理 30 天前的日志文件
    #%       sh ${SCRIPT_NAME} -p /home/nacos/logs -d 30
    #%
    #================================================================
    # END_OF_HEADER
    #================================================================
     
    # header 总行数
    SCRIPT_HEADSIZE=$(head -200 "${0}" |grep -n "^# END_OF_HEADER" | cut -f1 -d:)
    # 脚本名称
    SCRIPT_NAME="$(basename "${0}")"
    # 版本
    VERSION="0.0.1"
     
    # 默认保留 7 天
    DAYS=7
    # 脚本执行日志目录
    CLEAR_LOGS_LOG_PATH=/tmp/$(whoami)-clear-logs
    # 日志文件
    LOGFILE=${CLEAR_LOGS_LOG_PATH}/${SCRIPT_NAME}-$(date +%Y%m).log
     
    # usage
    function usage() {
      head -"${SCRIPT_HEADSIZE:-99}" "${0}" \
      | grep -e "^#%" \
      | sed -e "s/^#%//g" -e "s/\${SCRIPT_NAME}/${SCRIPT_NAME}/g" -e "s/\${VERSION}/${VERSION}/g"
    }
     
    # 初始化创建脚本日志目录
    function init() {
      # 目录不存在,则创建
      if [ ! -d "${CLEAR_LOGS_LOG_PATH}" ]
      then
        mkdir -p "${CLEAR_LOGS_LOG_PATH}"
      fi
     
      # 日志文件不存在,则创建
      if [ ! -f "${LOGFILE}" ]
      then
        touch "${LOGFILE}"
      fi
    }
     
    # 记录 INFO log
    function infoLog() {
      echo "$(date "+%Y-%m-%d %H:%M:%S") [ INFO] ${1}" >> "${LOGFILE}"
    }
     
    # 记录 ERROR log
    function errorLog() {
      echo -e "$(date "+%Y-%m-%d %H:%M:%S") \033[31m[ERROR]\033[0m ${1}" >> "${LOGFILE}"
    }
     
    # 清理 log
    function clearLogs() {
      infoLog "====>> Start cleaning up log files: [${LOGS_PATH}]"
      cd "${LOGS_PATH}" || exit
     
      # 查询要清理的文件(*.log*)
      clear_log_files=$(find "${LOGS_PATH}" -type f -mtime +${DAYS} -name "*.log*")
     
      # 没有找到匹配文件,记录日志退出
      if [ -z "${clear_log_files}" ]
      then
        errorLog "In the [${LOGS_PATH}] directory, the log [${DAYS}] days ago was not found!"
        infoLog "====>> End cleaning up log files: [${LOGS_PATH}]"
        exit 1
      fi
     
      # 临时记录要清理的文件(*.log*)
      echo "${clear_log_files}" > log_files.tmp
     
      # 循环清理日志文件
      while IFS= read -r item
      do
        rm -f ${item}
        infoLog "-- Clean up log file: [${item}]"
      done < log_files.tmp
     
      # 删除临时文件
      rm log_files.tmp
     
      infoLog "====>> End cleaning up log files: [${LOGS_PATH}]"
    }
     
    # 主方法
    function main() {
      init
     
      # 参数必输校验
      if [ -z "${LOGS_PATH}" ]
      then
        printf "Parameter [-p] is required!\n"
        exit 1
      fi
     
      # 目录合法性校验
      if [ ! -d "${LOGS_PATH}" ]
      then
       printf "[%s] is not a directory!\n" "${LOGS_PATH}"
       exit 1
      fi
     
      # 数字合法性校验,且必须大于 0,即至少保留1天
      if ! [ "${DAYS}" -gt 0 ] 2>/dev/null
      then
        printf "Parameter [-d] must be a number greater than 0!\n"
        exit 1
      fi
     
      clearLogs
    }
     
    # 判断参数个数
    if [ $# -eq 0 ];
    then
      usage
      exit 1
    fi
     
    # getopt 命令行参数
    if ! ARGS=$(getopt -o vd:p: --long help,version -n "${SCRIPT_NAME}" -- "$@")
    then
      # 无效选项,则退出
      exit 1
    fi
     
    # 命令行参数格式化
    eval set -- "${ARGS}"
     
    while [ -n "$1" ]
    do
      case "$1" in
        -p)
          LOGS_PATH=$2
          shift 2
          ;;
     
        -d)
          DAYS=$2
          shift 2
          ;;
     
        -v|--version)
          printf "%s version %s\n" "${SCRIPT_NAME}" "${VERSION}"
          exit 1
          ;;
     
        --help)
          usage
          exit 1
          ;;
     
        --)
          shift
          break
          ;;
     
        *)
          printf "%s is not an option!" "$1"
          exit 1
          ;;
     
      esac
    done
     
    main
    
    

    相关文章

      网友评论

          本文标题:Docker镜像服务器磁盘空间清理

          本文链接:https://www.haomeiwen.com/subject/tnoxwktx.html