Ubuntu服务器长期靠手动敲命令维护,迟早会出问题。补丁漏打、配置漂移、多台机器重复操作、半夜被报警叫起来处理磁盘写满,这些场景的根源都是没有把运维动作自动化。自动化管理的核心不是装一堆花哨工具,而是把重复的、可标准化的操作固化成脚本和配置,让服务器自己按预期运行。下面直接讲具体怎么落地。
用Ansible统一配置多台服务器如果你管理超过三台Ubuntu服务器,第一件事就是部署Ansible。它通过SSH工作,不需要在目标机器上装agent,符合Ubuntu默认环境。先在控制机上安装:
sudo apt update && sudo apt install -y ansible
然后编辑inventory文件,把服务器分组:
[web] 192.168.1.10 192.168.1.11 [db] 192.168.1.20 ansible_user=deploy ansible_ssh_private_key_file=/home/deploy/.ssh/id_ed25519
接下来写playbook。比如统一所有web服务器安装Nginx并推送配置文件,同时确保时区、locale、内核参数一致:
- hosts: web
become: yes
vars:
nginx_worker_connections: 4096
tasks:
- name: 安装Nginx
apt:
name: nginx
state: latest
update_cache: yes
- name: 推送Nginx主配置
template:
src: templates/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
notify: reload nginx
- name: 设置时区为Asia/Shanghai
timezone:
name: Asia/Shanghai
- name: 调整文件描述符限制
pam_limits:
domain: "*"
limit_type: soft
limit_item: nofile
value: "65535"
handlers:
- name: reload nginx
systemd:
name: nginx
state: reloaded
Ansible的幂等性保证你可以反复执行同一个playbook而不会产生副作用。配置漂移的问题用git管理playbook目录,每次修改都走版本记录,然后定期跑一遍playbook把实际状态拉回期望状态。这比手动登录每台机器改配置可靠得多。
无人值守的自动安全更新Ubuntu默认的unattended-upgrades只对部分安全源生效,而且经常因为配置不完整而漏掉关键补丁。建议显式配置:
sudo apt install -y unattended-upgrades apt-listchanges sudo dpkg-reconfigure -plow unattended-upgrades
然后编辑/etc/apt/apt.conf.d/50unattended-upgrades,把Ubuntu所有更新源都打开:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}";
"${distro_id}:${distro_codename}-security";
"${distro_id}ESMApps:${distro_codename}-apps-security";
"${distro_id}ESM:${distro_codename}-infra-security";
"${distro_id}:${distro_codename}-updates";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Remove-Unused-Dependencies "true";
Unattended-Upgrade::Automatic-Reboot "false";
Unattended-Upgrade::Automatic-Reboot-Time "03:00";
生产环境不建议自动重启,但内核补丁不重启不生效。可以配合needrestart检查哪些服务需要重启,然后安排维护窗口统一处理。自动更新日志在/var/log/unattended-upgrades/,建议用logrotate控制大小,并配置监控告警抓取“ERROR”关键字。
systemd timer替代cron做定时任务cron的问题在于没有依赖管理、没有失败重试、日志分散。Ubuntu 20.04以后systemd timer已经足够成熟,建议把重要定时任务迁过去。比如每天凌晨备份数据库,先写一个service单元:
[Unit] Description=MySQL daily backup After=mysql.service [Service] Type=oneshot User=backup ExecStart=/usr/local/bin/mysql_backup.sh StandardOutput=append:/var/log/mysql_backup.log StandardError=append:/var/log/mysql_backup_error.log
再写timer单元:
[Unit] Description=Run MySQL backup daily at 2:30 [Timer] OnCalendar=*-*-* 02:30:00 Persistent=true Unit=mysql-backup.service [Install] WantedBy=timers.target
启用并启动timer:
sudo systemctl daemon-reload sudo systemctl enable mysql-backup.timer sudo systemctl start mysql-backup.timer sudo systemctl list-timers --all
Persistent=true保证如果服务器在任务计划时间关机了,开机后会补跑。systemd timer还能设置随机延迟、单调计时器、失败后重启策略,比cron灵活得多。
集中日志管理与磁盘防爆Ubuntu服务器磁盘写满最常见的原因就是日志没管好。journald默认限制比较宽松,先收紧:
sudo mkdir -p /etc/systemd/journald.conf.d sudo tee /etc/systemd/journald.conf.d/size.conf <<'EOF' [Journal] SystemMaxUse=500M SystemMaxFileSize=100M MaxRetentionSec=2week Compress=yes EOF sudo systemctl restart systemd-journald
应用日志用logrotate控制。很多软件自带的logrotate配置不够细,建议在/etc/logrotate.d/下统一覆盖。比如Nginx:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
postrotate
if [ -f /var/run/nginx.pid ]; then
kill -USR1 `cat /var/run/nginx.pid`
fi
endscript
}
如果服务器数量多,单机日志管理只是兜底,真正要做的是把日志集中到Loki或ELK。Ubuntu上推荐用rsyslog转发到中央日志服务器,配置简单:
# /etc/rsyslog.d/50-forward.conf *.* @192.168.1.100:514
中央端用rsyslog或Grafana Loki接收,配合Promtail采集。日志集中后,磁盘写满的风险从业务服务器转移到了日志服务器,日志服务器再单独做容量规划和告警。
监控告警与自愈脚本自动化管理不只是配置和部署,还包括自动发现异常并处理。基础监控用Prometheus node_exporter,Ubuntu上安装:
sudo apt install -y prometheus-node-exporter sudo systemctl enable --now prometheus-node-exporter
告警规则至少覆盖CPU持续高负载、内存剩余不足、磁盘使用率超过85%、systemd服务失败、重启次数异常。Alertmanager收到告警后,可以触发webhook调用自愈脚本。
自愈脚本要非常克制,只处理明确无副作用的场景。比如磁盘使用率超过90%时自动清理可安全删除的缓存:
#!/bin/bash
# /usr/local/bin/auto_cleanup.sh
THRESHOLD=90
PARTITION="/"
USAGE=$(df -h "$PARTITION" | awk 'NR==2 {gsub("%","",$5); print $5}')
if [ "$USAGE" -ge "$THRESHOLD" ]; then
# 清理apt缓存
apt-get clean
# 清理旧内核
apt-get autoremove --purge -y
# 清理journald
journalctl --vacuum-size=200M
# 清理临时文件
find /tmp -type f -atime +7 -delete
logger -t auto_cleanup "磁盘使用率${USAGE}%,已执行自动清理"
fi
把这个脚本接到systemd timer每30分钟跑一次,同时配合告警通知。注意自愈脚本必须记录日志,并且要有告警兜底,不能静默失败。
配置管理:把服务器当代码管自动化配置的最高形式是基础设施即代码。除了Ansible,建议把服务器初始化也标准化。Ubuntu的cloud-init可以在首次启动时自动完成基础配置。创建/etc/cloud/cloud.cfg.d/99_custom.cfg:
#cloud-config
hostname: web-prod-01
manage_etc_hosts: true
users:
- name: deploy
sudo: ALL=(ALL) NOPASSWD:ALL
ssh_authorized_keys:
- ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAA...
packages:
- htop
- vim
- curl
- git
- unattended-upgrades
package_update: true
package_upgrade: true
runcmd:
- systemctl enable --now unattended-upgrades
- sed -i 's/#Port 22/Port 2200/' /etc/ssh/sshd_config
- systemctl restart sshd
这样新机器从镜像启动后自动完成用户创建、软件安装、安全基线配置。配合Ubuntu的autoinstall可以做全自动安装,把整个装机过程变成一条命令。
备份自动化与恢复验证没有验证过的备份等于没有备份。自动化备份要包含恢复测试。数据库备份脚本示例:
#!/bin/bash # /usr/local/bin/mysql_backup.sh BACKUP_DIR="/backup/mysql" DATE=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=14 mkdir -p "$BACKUP_DIR" mysqldump --single-transaction --quick --all-databases \ | gzip > "$BACKUP_DIR/full_$DATE.sql.gz" # 删除过期备份 find "$BACKUP_DIR" -name "full_*.sql.gz" -mtime +$RETENTION_DAYS -delete # 记录备份大小 du -sh "$BACKUP_DIR/full_$DATE.sql.gz" | logger -t mysql_backup
恢复验证可以每周自动把最新备份恢复到一台测试实例,跑一条简单的数据完整性检查SQL,然后把结果发到监控系统。这个流程用GitLab CI或Jenkins做调度,比手动验证可靠。
SSH安全基线自动化SSH是Ubuntu服务器最常被攻击的入口。自动化加固配置:
sudo tee /etc/ssh/sshd_config.d/99-hardening.conf <<'EOF' Port 2200 PermitRootLogin prohibit-password PasswordAuthentication no PubkeyAuthentication yes MaxAuthTries 3 ClientAliveInterval 300 ClientAliveCountMax 2 AllowUsers deploy EOF sudo systemctl restart sshd
配合fail2ban自动封禁暴力破解:
sudo apt install -y fail2ban sudo tee /etc/fail2ban/jail.local <<'EOF' [sshd] enabled = true port = 2200 maxretry = 3 bantime = 3600 findtime = 600 EOF sudo systemctl enable --now fail2ban
这些配置都应该放进Ansible playbook,确保每台新机器自动应用。
自动化运维的落地顺序不要试图一次性把所有东西都自动化。建议按这个顺序推进:先把所有服务器纳入Ansible管理,统一基础配置;然后配置自动安全更新和日志轮转,解决最紧急的补丁和磁盘问题;接着部署监控告警,让你知道什么时候出了问题;再逐步把备份、定时任务、自愈脚本迁移到自动化体系里。每一步都要有日志和告警,自动化不是把问题藏起来,而是让问题更快暴露、更快处理。Ubuntu服务器运维自动化管理的本质,是把你的运维经验固化成代码,让服务器按照你设定的规则自己运行,而不是每次出问题都靠人肉登录去救火。
