使用crontab定时任务自动清理docker资源和冗余日志

crontab (cron table) 是 Linux 和 Unix 系统中用来设置周期性被执行的指令的工具, 通过编辑 crontab 文件, 你可以安排系统在特定的时间或间隔自动执行一些命令或脚本

1. crontab 的基础使用方法

使用crontab -e命令来编辑当前用户的 crontab 文件

Crontab 语法: 每一行代表一个定时任务, 由 6 个字段组成, 用空格或制表符分隔

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
minute hour day_of_month month day_of_week command

* * * * * /path/to/your/script.sh

基础配置:

minute: 分钟 (0-59)
hour: 小时 (0-23)
day_of_month: 月份中的日期 (1-31)
month: 月份 (1-12 或 JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC)
day_of_week: 星期几 (0-6 或 SUN, MON, TUE, WED, THU, FRI, SAT, 其中 0 和 7 都表示星期日)
command: 要执行的命令或脚本的完整路径

特殊字符:

* (星号): 表示该字段的所有可能值 例如, 分钟字段为 * 表示每分钟
, (逗号): 用于指定多个值 例如, 小时字段为 1,3,5 表示在 1 点、3 点和 5 点
- (连字符): 用于指定一个范围 例如, 月份字段为 1-3 表示 1 月到 3 月
/ (斜线): 用于指定步长 例如, 分钟字段为 */15 表示每 15 分钟执行一次(相当于 0,15,30,45)

使用crontab -l查看当前用户的 crontab 任务列表

1.1 重要注意事项

  1. 使用完整的路径: 在 command 字段中, 强烈建议使用要执行的命令或脚本的完整路径, 以避免因环境变量问题导致任务执行失败

  2. 输出重定向: 定时任务的输出(包括标准输出和标准错误)通常会被发送到系统邮件。如果你不希望收到邮件, 可以将输出重定向到 /dev/null

    1
    2
    3
    4
    * * * * * /path/to/your/script.sh > /dev/null 2>&1

    `>` 表示重定向标准输出
    `2>&1` 表示将标准错误重定向到标准输出
  3. 环境变量: 定时任务执行时可能不会加载你当前用户的环境变量, 如果脚本依赖特定的环境变量, 最好在脚本中显式设置, 或者在 crontab 文件中定义

  4. 错误处理: 确保脚本具有良好的错误处理机制, 以便在任务执行失败时能够记录错误或进行其他处理

2. 添加清理 Docker 的 cron 任务

1
2
crontab -e
0 2 */3 * * /home/scripts/clean_docker_images.sh

每三天凌晨2点运行clean_docker_images.sh脚本

3. 创建 shell 脚本

对于容器应用来说, 清理悬空的的容器资源和容器日志足矣

要实现这个方案, 我需要定期运行docker system prune -af命令和删除 docker 日志并保存执行记录

创建一个shell 脚本, 并确保它具有可执行权限

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
vim /home/scripts/clean_docker_images.sh

#!/bin/bash

# 创建日志目录(如果不存在)
LOG_DIR="/home/logs"
LOG_FILE="$LOG_DIR/clean-docker-images.log"
mkdir -p $LOG_DIR

# 获取当前时间戳
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

echo "======== start run docker prune ========"
# 执行 Docker 清理命令, 并获取输出
CLEAN_OUTPUT=$(docker system prune -af 2>&1)
# 将时间戳和清理输出写入日志文件
echo "${TIMESTAMP} : 执行docker镜像清理" >> $LOG_FILE
echo "${CLEAN_OUTPUT}" >> $LOG_FILE
echo "=========== end docker prune ==========" >> $LOG_FILE

echo "======== start clean docker containers logs ========"
# 这里路径记得替换成你自己的 docker 数据路径, 默认是 /var/lib/docker
logs=$(find /data1/docker/containers/ -name *-json.log)

for log in $logs
do
echo "clean logs : $log"
cat /dev/null > $log
done
echo "======== end clean docker containers logs ========" >> $LOG_FILE

chmod +x /home/scripts/clean_docker_images.sh

3.1 额外选项-配置 Docker 的日志大小限制

如果你想从根源解决问题, Docker 允许你配置日志驱动的选项, 包括设置日志文件的最大大小和回滚数量

可以在 Docker 的守护进程配置文件/etc/docker/daemon.json中设置全局默认值

1
2
3
4
5
6
7
{
"log-driver": "json-file",
"log-opts": {
"max-size": "20m",
"max-file": "3"
}
}

修改了daemon.json文件后, 需要重启 Docker 服务以使配置生效

1
2
systemctl daemon-reload
systemctl restart docker