即 Linux 系统自带的 crontab 服务

权限

Linux 下可以通过创建文件 /etc/cron.allow 或者 /etc/cron.deny 来控制权限

1
echo app >> /etc/cron.allow

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

# For details see man 4 crontabs

# Example of job definition:
# .---------------- minute (0 - 59)
# | .------------- hour (0 - 23)
# | | .---------- day of month (1 - 31)
# | | | .------- month (1 - 12) OR jan,feb,mar,apr ...
# | | | | .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# | | | | |
# * * * * * user-name command to be executed
  • minute:代表一小时内的第几分,范围 0-59
  • hour:代表一天中的第几小时,范围 0-23
  • day of month: 代表一个月中的第几天,范围 1-31
  • month:代表一年中第几个月,范围 1-12
  • day of week:代表星期几,范围 0-7 (0 及 7 都是星期天)
  • user-name: 要使用什么身份执行该指令,当您使用 crontab -e 时,不必加此字段
  • command to be executed:所要执行的指令

    使用

    确定任务执行
    1
    2
    3
    4
    systemctl status crond
    systemctl start crond
    systemctl stop crond
    systemctl enable crond

    命令

    1
    2
    3
    4
    5
    6
    /etc/crontab
    /etc/cron.daily
    /etc/cron.hourly
    /etc/cron.monthly
    /etc/cron.weekly
    /etc/cron.d
    1
    2
    3
    4
    5
    6
    crontab
    -l:列出当前用户的计划任务
    -e:编辑当前用户的计划任务
    -r:删除当前用户的所有计划任务,即删除 /var/spool/cron/USERNAME
    -u:管理指定用户的计划任务,仅 root 有权限
    -i:在使用 -r 选项删除所有任务时提示用户确认
    默认创建在 /var/spool/cron 下的用户名同名文件夹里

    日志

    默认日志目录:/var/log/cron

    技巧

    按秒执行任务

    通过上述语法看出,crontab 的执行精度只到分钟,需要按秒间隔执行的话需要技巧:执行的语句前面用sleep <s>来控制,如:
    1
    2
    3
    4
    5
    * * * * * sleep 10; ping -c 1 yuwei.cc
    * * * * * sleep 20; ping -c 1 yuwei.cc
    * * * * * sleep 30; ping -c 1 yuwei.cc
    * * * * * sleep 40; ping -c 1 yuwei.cc
    * * * * * sleep 50; ping -c 1 yuwei.cc
    但是如果需要一秒执行一次,就得写 60 行,因此可以将 sleep 写到脚本里,并用for循环进行控制
    1
    2
    3
    4
    5
    6
    7
    #!/bin/bash
    ## * * * * * ping -c 1 yuwei.cc
    TIMER=1
    for (( i = 0; i < 60; i=(i+TIMER) )); do
    ping -c 1 yuwei.cc
    sleep ${TIMER}
    done

    容器

    容器化是趋势,对于上了 K8s 平台的,可以直接使用 CronJob 进行操作,但是单 Docker 环境下,实现方式有:
  • 使用宿主机的 cron 实现:直接将容器当成一个服务进行调用(取消 -it 参数)
  • 创建新的容器专门执行定时任务:需要构建容器
  • 在原有容器上安装 cron,里面运行“服务 + cron” 2 个进程

2、3 都要构建专门的容器,dockerfile 如下:

1
2
3
4
5
6
7
8
9
10
11
## 使用轻量级的 Alpine 镜像
FROM alpine:latest
## 使用单个 RUN 命令来更新、安装、创建文件夹、写入 crontab 文件
RUN apk update && \
apk add --no-cache cron && \
mkdir -p /var/log && \
touch /var/log/cron.log && \
##echo "* * * * * ping -c 1 yuwei.cc >> /var/log/cron.log 2>&1" > /etc/crontabs/root
echo "* * * * * ping -c 1 yuwei.cc >> /dev/stdout 2>&1" > /etc/crontabs/root
## 设置 cron 启动日志级别为 2,持续运行 cron 服务
CMD ["crond", "-f", "-l", "2"]

然后构建镜像
1
2
3
4
docker build -t cron-alpine .
docker run -d --name cron-alpine cron-alpine
##docker exec -it cron-alpine sh && cat /var/log/cron.log
docker logs cron-alpine