Ubuntu服务器运维的核心不是记一堆命令,而是建立一套可重复、可追溯、能快速定位问题的操作习惯。多数故障并非源于复杂的内核或服务配置,而是磁盘写满、权限混乱、更新策略不当、日志无人关注这类基础问题。下面直接讲日常运维中最常用、最能避免事故的具体技巧。

先建立最小化更新策略,不要盲目执行 apt upgrade

很多人习惯定期执行 apt upgrade,但在生产服务器上这可能是危险操作。正确做法是区分安全更新和功能更新。只安装安全更新用 unattended-upgrades,配置 /etc/apt/apt.conf.d/50unattended-upgrades,只允许 Ubuntu 的安全源。功能更新要放在维护窗口手动执行,并且更新前必须做快照或备份。执行 apt upgrade 前先看有哪些包会被升级、是否会重启服务,用 apt list --upgradable 检查。对于内核更新,不要立即删除旧内核,保留至少两个可用内核版本,防止新内核与驱动或文件系统不兼容导致无法启动。

磁盘空间监控必须做到主动告警,而不是等写满再处理

Ubuntu 服务器最常见的宕机原因就是根分区写满。日志、Docker 镜像、数据库临时文件、apt 缓存都会悄悄占满磁盘。用 df -h 和 du -sh /var/* /tmp /home/* 定期检查。更可靠的是配置监控脚本,当磁盘使用率超过 80% 时发送告警。可以写一个简单的 systemd timer 或 cron 任务,每分钟检查一次。对于日志目录,务必配置 logrotate,尤其是 nginx、mysql、syslog 这类高输出服务。logrotate 的关键参数包括 daily、rotate 7、compress、maxsize 100M、copytruncate。注意有些服务不支持 copytruncate,比如 mysql 的慢日志,需要用 flush-logs 方式轮转。

用 systemd 管理服务,而不是依赖 nohup 或 screen

手工用 nohup 启动进程是运维大忌。所有需要长期运行的服务都应该写成 systemd unit 文件,放在 /etc/systemd/system/ 下。一个标准的 unit 文件要包含 Restart=on-failure、RestartSec=5、LimitNOFILE=65535、WorkingDirectory 和 EnvironmentFile。启动服务用 systemctl enable --now 服务名。查看服务状态不要只看 active,还要看 journalctl -u 服务名 -n 50 --no-pager。如果服务频繁重启,用 systemctl status 服务名 里的 Main PID 变化和 journalctl -u 服务名 --since "10 minutes ago" 定位。对于需要开机自启的脚本,写成 oneshot 类型的 systemd service 比 rc.local 更可靠,因为可以设置 After=network.target 等依赖关系。

日志管理要集中化,并设置合理的保留周期

单机日志用 journald 就够了,但生产环境最好把关键日志转发到集中日志系统。Ubuntu 默认的 rsyslog 可以配置转发,但更轻量的做法是用 journald 的 ForwardToSyslog=no 配合 promtail 或 filebeat 直接采集。日志保留时间要明确,journald 默认的 SystemMaxUse 可能只有几百 MB,需要根据磁盘大小调整 /etc/systemd/journald.conf 中的 SystemMaxUse=2G、SystemKeepFree=5G。应用日志要输出到 stdout/stderr,让 systemd 统一收集,而不是自己写文件再单独轮转。这样排查问题时用 journalctl -u 服务名 --since today 就能看到完整输出。

用户和权限管理:最小权限原则,禁用 root SSH 登录

Ubuntu 默认的 ubuntu 用户有 sudo 权限,这在生产环境不安全。应该创建独立的管理员账号,加入 sudo 组,然后禁用 ubuntu 用户或删除其 sudo 权限。SSH 配置 /etc/ssh/sshd_config 中必须设置 PermitRootLogin no、PasswordAuthentication no、PubkeyAuthentication yes。对于多用户服务器,用 visudo 配置细粒度 sudo 权限,比如只允许某个用户执行 systemctl restart nginx,而不是给全部 root 权限。定期检查 /etc/sudoers.d/ 和 /etc/passwd 中是否有异常账号。文件权限问题用 find / -xdev -type f -perm -4000 查找 SUID 文件,确认没有异常提权程序。

防火墙和网络配置要简单且可审计

Ubuntu 自带的 ufw 足够日常使用,不要一上来就配复杂的 iptables 规则。启用 ufw 前先允许 SSH 端口,否则会把自己锁在外面。典型配置:ufw default deny incoming,ufw default allow outgoing,ufw allow 22/tcp,ufw allow 80,443/tcp,然后 ufw enable。对于 Docker 服务器要特别注意,Docker 会直接操作 iptables,ufw 的规则可能被绕过。如果必须同时使用,需要在 Docker daemon 配置中设置 iptables=false,或者用 docker 的 published ports 配合 ufw-docker 脚本。网络排障时先看 ip addr 确认网卡状态,再用 ss -tlnp 查看监听端口,最后用 ip route 检查路由。

定时任务要可追踪,避免使用裸 cron 执行复杂脚本

cron 的问题在于执行环境不完整,很多脚本在 cron 里跑失败是因为 PATH 变量缺失。写 cron 任务时必须在脚本里显式设置 PATH、SHELL 和任何需要的环境变量。更推荐用 systemd timer 替代 cron,因为 timer 可以设置 Persistent=true 保证错过的任务在重启后执行,还能用 journalctl 查看执行日志。如果必须用 cron,把输出重定向到日志文件,例如 */10 * * * * /opt/script.sh >> /var/log/script.log 2>&1。对于需要锁的任务,用 flock 防止并发执行:flock -n /tmp/script.lock /opt/script.sh。

备份策略要包含验证环节,不能只备份不恢复

备份的核心不是备份本身,而是恢复能力。对于数据库,用 mysqldump 或 pg_dump 做逻辑备份,配合 binlog 做增量恢复。文件备份用 rsync 或 restic 做快照。关键是要定期做恢复演练,比如每月从备份中恢复一个数据库到测试环境,确认备份文件完整可用。备份文件要放在不同物理位置,至少一份异地存储。对于配置文件,用 git 管理 /etc 目录的关键配置,每次修改后提交,这样配置变更可追溯、可回滚。

性能监控要关注负载、内存和 IO 等待,而不是只看 CPU

Ubuntu 服务器卡顿的原因往往是 IO 等待或内存不足导致 swap 使用过高。用 top 或 htop 看 load average,如果 load 高但 CPU 使用率不高,基本是 IO 瓶颈。用 iostat -x 1 查看 %util 和 await,如果 await 超过 20ms 说明磁盘性能有问题。内存方面,free -h 看 available 列,不要只看 free,因为 Linux 会缓存文件。swap 使用过高说明内存不够,需要加内存或优化应用。用 vmstat 1 观察 si/so 列,如果持续有 swap in/out,说明内存压力大。对于数据库服务器,用 pt-query-digest 分析慢查询,而不是盲目加索引。

安全加固:自动更新、失败登录处理和文件完整性监控

除了前面提到的 SSH 加固,还要配置 fail2ban 防止暴力破解。安装后启用 sshd、nginx-limit-req 等 jail,设置 bantime 为 3600 秒。定期用 lynis audit system 做安全审计,它会检查文件权限、内核参数、已安装软件漏洞等。对于关键目录如 /etc、/usr/bin,可以用 aide 做文件完整性监控,任何异常改动都会告警。内核参数方面,在 /etc/sysctl.conf 中设置 net.ipv4.conf.all.rp_filter=1、net.ipv4.tcp_syncookies=1、kernel.randomize_va_space=2 等基本加固项。

故障排查的固定顺序:先看日志,再查资源,最后动配置

遇到服务异常,第一步永远是 journalctl -u 服务名 --since "5 minutes ago",而不是直接重启服务。重启会丢失现场,让问题更难定位。第二步看系统资源:df -h、free -h、top、ss -tlnp。第三步检查依赖服务是否正常,比如数据库连接、DNS 解析、外部 API 可达性。确认问题范围后再修改配置,每次只改一个变量,改完立即验证。对于疑难问题,用 strace -p PID 跟踪进程系统调用,或者用 tcpdump -i any port 端口 抓包分析网络层问题。

Ubuntu 服务器运维的成熟度不在于会多少高级技巧,而在于基础操作是否规范、监控是否到位、变更是否可回滚。把这些日常动作固定下来,形成 checklist,比任何花哨的自动化工具都更可靠。