【Linux运维极简教程】09-定时任务与自动化运维
·
09 - 定时任务与自动化运维
一、cron 定时任务
cron 是 Linux 最常用的定时任务服务,可以按固定时间周期执行命令或脚本。
1.1 crontab 命令
# 编辑当前用户的定时任务
crontab -e
# 查看当前用户的定时任务
crontab -l
# 删除所有定时任务
crontab -r
# 编辑指定用户的定时任务(需要 root)
crontab -u alice -e
crontab -u alice -l
1.2 cron 表达式
* * * * * 要执行的命令
│ │ │ │ │
│ │ │ │ └── 星期 (0-7,0和7都是周日)
│ │ │ └────── 月份 (1-12)
│ │ └─────────── 日期 (1-31)
│ └────────────── 小时 (0-23)
└───────────────── 分钟 (0-59)
常用 cron 表达式
| 表达式 | 含义 |
|---|---|
*/5 * * * * |
每 5 分钟 |
0 * * * * |
每小时整点 |
0 2 * * * |
每天凌晨 2 点 |
0 2 * * 1 |
每周一凌晨 2 点 |
0 0 1 * * |
每月 1 号零点 |
0 2 * * 1-5 |
工作日凌晨 2 点 |
*/30 9-18 * * 1-5 |
工作时间每 30 分钟 |
0 0,12 * * * |
每天零点和 12 点 |
特殊关键字
@reboot # 系统启动时执行
@yearly # 每年(0 0 1 1 *)
@monthly # 每月(0 0 1 * *)
@weekly # 每周(0 0 * * 0)
@daily # 每天(0 0 * * *)
@hourly # 每小时(0 * * * *)
1.3 crontab 示例
# 每天凌晨 2 点备份数据库
0 2 * * * /opt/scripts/backup_db.sh >> /var/log/backup_db.log 2>&1
# 每 5 分钟检查服务状态,挂了自动重启
*/5 * * * * /opt/scripts/check_service.sh
# 每周日凌晨 3 点清理日志
0 3 * * 0 find /var/log -name "*.log" -mtime +30 -delete
# 开机时启动自定义脚本
@reboot /opt/scripts/init_env.sh
1.4 cron 注意事项
# 1. cron 环境变量极少,脚本中需手动设置 PATH
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# 2. cron 中的百分号 % 需要转义(或用在脚本中)
# 错误写法:
# 0 2 * * * date +%Y%m%d > /tmp/date.txt
# 正确写法:
0 2 * * * date +\%Y\%m\%d > /tmp/date.txt
# 3. 推荐将复杂逻辑放在脚本中,cron 只调用脚本
0 2 * * * /opt/scripts/daily_task.sh
# 4. 确保脚本有执行权限
chmod +x /opt/scripts/daily_task.sh
1.5 系统级定时任务
除了用户 crontab,还可以通过以下方式配置系统级定时任务:
# /etc/crontab - 系统主 crontab(多一个用户字段)
# 格式:分 时 日 月 周 用户 命令
0 2 * * * root /opt/scripts/system_backup.sh
# /etc/cron.d/ - 放置独立的定时任务文件
# 格式同 /etc/crontab
cat > /etc/cron.d/backup << 'EOF'
0 2 * * * root /opt/scripts/backup.sh
EOF
# /etc/cron.hourly/ - 每小时执行
# /etc/cron.daily/ - 每天执行
# /etc/cron.weekly/ - 每周执行
# /etc/cron.monthly/ - 每月执行
# 只需将脚本放入对应目录即可
cp backup.sh /etc/cron.daily/
chmod +x /etc/cron.daily/backup.sh
1.6 cron 日志
# 查看 cron 执行日志
# CentOS/RHEL
grep CRON /var/log/cron
# Ubuntu/Debian
grep CRON /var/log/syslog
# 查看 cron 服务状态
systemctl status crond # CentOS
systemctl status cron # Ubuntu
二、at 一次性任务
at 用于执行一次性定时任务(执行后自动删除)。
# 安装
yum install -y at # CentOS
apt install -y at # Ubuntu
# 启动服务
systemctl enable --now atd
# 今晚 23:00 执行
echo "shutdown -h now" | at 23:00
# 5 分钟后执行
echo "echo 'hello' > /tmp/test.txt" | at now + 5 minutes
# 明天早上 8 点执行
at 8:00 tomorrow
at> echo "Good morning"
at> <Ctrl+D> # 按 Ctrl+D 提交
# 查看待执行任务
atq
at -l
# 删除任务
atrm 1 # 删除任务 ID 为 1 的任务
三、Ansible 自动化运维
3.1 Ansible 简介
Ansible 是基于 SSH 的自动化运维工具,无需在目标机器安装客户端。
| 特性 | 说明 |
|---|---|
| 无 Agent | 通过 SSH 管理目标机器 |
| 幂等性 | 多次执行结果一致 |
| YAML 语法 | 易读易写 |
| 模块化 | 丰富的内置模块 |
3.2 安装与配置
# 安装(控制端)
yum install -y ansible # CentOS
apt install -y ansible # Ubuntu
pip install ansible # 通用
# 配置主机清单
cat > /etc/ansible/hosts << 'EOF'
[webservers]
192.168.1.10 ansible_ssh_user=root
192.168.1.11 ansible_ssh_user=root
[dbservers]
192.168.1.20 ansible_ssh_user=root
[all:vars]
ansible_ssh_private_key_file=~/.ssh/id_rsa
EOF
# 测试连通性
ansible all -m ping
ansible webservers -m ping
3.3 Ad-hoc 命令
# 执行命令
ansible all -a "uptime"
ansible webservers -a "df -h"
# 使用模块
# yum 模块 - 安装软件
ansible webservers -m yum -a "name=nginx state=present"
# service 模块 - 管理服务
ansible webservers -m service -a "name=nginx state=started enabled=yes"
# copy 模块 - 复制文件
ansible webservers -m copy -a "src=/etc/hosts dest=/etc/hosts"
# file 模块 - 创建目录
ansible webservers -m file -a "path=/data/app state=directory mode=0755"
# user 模块 - 创建用户
ansible all -m user -a "name=deploy shell=/bin/bash groups=wheel"
# setup 模块 - 获取主机信息
ansible webservers -m setup
ansible webservers -m setup -a "filter=ansible_memory_mb"
3.4 Playbook 示例
---
# deploy_nginx.yml - 部署 Nginx
- name: Deploy Nginx Web Server
hosts: webservers
become: yes # 使用 sudo
tasks:
- name: Install Nginx
yum:
name: nginx
state: present
- name: Copy nginx config
copy:
src: files/nginx.conf
dest: /etc/nginx/nginx.conf
backup: yes
notify: restart nginx
- name: Create web root
file:
path: /var/www/html
state: directory
owner: nginx
group: nginx
mode: '0755'
- name: Copy index page
copy:
src: files/index.html
dest: /var/www/html/index.html
- name: Start and enable Nginx
service:
name: nginx
state: started
enabled: yes
handlers:
- name: restart nginx
service:
name: nginx
state: restarted
# 执行 playbook
ansible-playbook deploy_nginx.yml
# 检查语法
ansible-playbook --syntax-check deploy_nginx.yml
# 模拟执行(不实际修改)
ansible-playbook --check deploy_nginx.yml
# 查看执行步骤
ansible-playbook --list-tasks deploy_nginx.yml
四、其他自动化工具
4.1 工具对比
| 工具 | 特点 | 适用场景 |
|---|---|---|
| Shell + cron | 简单直接,无需额外安装 | 小规模、简单任务 |
| Ansible | 无 Agent,YAML 语法,学习成本低 | 中小规模批量管理 |
| SaltStack | 高性能,实时通信 | 大规模基础设施 |
| Puppet | 声明式,成熟稳定 | 大型企业 |
| Terraform | 基础设施即代码 | 云资源管理 |
4.2 自动化运维最佳实践
- 脚本版本管理:所有运维脚本纳入 Git 管理
- 幂等性设计:脚本可以安全地重复执行
- 日志记录:每次执行都有日志,便于追溯
- 错误通知:任务失败时发送告警(邮件/钉钉/微信)
- 测试环境验证:先在测试环境验证,再推到生产
五、实战场景
场景一:监控 + 自动恢复
#!/bin/bash
# /opt/scripts/monitor_service.sh
# 检查服务状态,自动重启并告警
SERVICE="nginx"
LOG="/var/log/service_monitor.log"
ALERT_EMAIL="ops@example.com"
if ! systemctl is-active --quiet $SERVICE; then
echo "[$(date)] $SERVICE 已停止,尝试重启..." >> $LOG
systemctl restart $SERVICE
sleep 3
if systemctl is-active --quiet $SERVICE; then
echo "[$(date)] $SERVICE 重启成功" >> $LOG
echo "$SERVICE 在 $(date) 自动重启成功" | mail -s "服务恢复告警" $ALERT_EMAIL
else
echo "[$(date)] $SERVICE 重启失败!" >> $LOG
echo "$SERVICE 在 $(date) 重启失败,请紧急处理!" | mail -s "紧急故障告警" $ALERT_EMAIL
fi
fi
# 加入 cron,每 2 分钟检查
*/2 * * * * /opt/scripts/monitor_service.sh
场景二:日志轮转
#!/bin/bash
# /opt/scripts/log_rotate.sh
# 按天切割日志,保留 30 天
LOG_DIR="/var/log/myapp"
KEEP_DAYS=30
# 切割日志
cd $LOG_DIR
for log_file in *.log; do
[ -f "$log_file" ] || continue
mv "$log_file" "${log_file}.$(date +%Y%m%d)"
gzip "${log_file}.$(date +%Y%m%d)"
done
# 通知应用重新打开日志文件
# kill -USR1 $(pidof nginx)
# 清理旧日志
find $LOG_DIR -name "*.log.*.gz" -mtime +$KEEP_DAYS -delete
echo "[$(date)] 日志轮转完成" >> /var/log/log_rotate.log
# 每天凌晨执行
0 0 * * * /opt/scripts/log_rotate.sh
场景三:定时备份并同步到远程
#!/bin/bash
# /opt/scripts/backup_and_sync.sh
set -euo pipefail
SOURCE="/data/mysql"
LOCAL_BACKUP="/backup/mysql"
REMOTE_SERVER="backup@192.168.1.100:/backup/mysql/"
DATE=$(date +%Y%m%d)
KEEP=7
mkdir -p $LOCAL_BACKUP
# 1. 备份数据库
mysqldump -u root -p"$DB_PASS" --all-databases | gzip > "$LOCAL_BACKUP/db_${DATE}.sql.gz"
# 2. 同步到远程
rsync -az --progress "$LOCAL_BACKUP/db_${DATE}.sql.gz" "$REMOTE_SERVER"
# 3. 清理本地旧备份
find $LOCAL_BACKUP -name "db_*.sql.gz" -mtime +$KEEP -delete
echo "[$(date)] 备份并同步完成" >> /var/log/backup.log
# 每天凌晨 3 点执行
0 3 * * * /opt/scripts/backup_and_sync.sh >> /var/log/backup.log 2>&1
六、小结
本篇介绍了 cron 定时任务、at 一次性任务、Ansible 自动化运维以及实战自动化脚本。定时任务结合 Shell 脚本是运维自动化的第一层,Ansible 则适合大规模批量管理。核心原则是:能自动化的不要手动做。
上一篇:08 - Shell 脚本编程入门
下一篇:10 - 日志管理与故障排查
更多推荐

所有评论(0)