Chapter 10

系统管理与运维

日志分析、磁盘管理、性能监控到系统备份——Linux 服务器运维的完整工具箱

日志系统:/var/log 目录结构

/var/log/syslog(或 messages)
系统综合日志,记录内核消息、系统启动、硬件检测等。Ubuntu 用 syslog,RHEL/CentOS 用 messages。
/var/log/auth.log(或 secure)
认证和授权日志:SSH 登录(成功/失败)、sudo 使用、用户切换、PAM 认证。安全审计的重要来源。
/var/log/kern.log
内核日志:硬件驱动、内存错误、文件系统挂载、网络接口状态变化。
/var/log/dpkg.log(或 yum.log)
包管理操作记录:安装/删除/升级软件包的历史,用于追踪系统变更。
/var/log/nginx/(或 apache2/)
Web 服务器日志:access.log 记录所有 HTTP 请求,error.log 记录错误和警告。
/var/log/journal/
systemd 的二进制日志存储目录,通过 journalctl 命令读取(不能直接 cat)。
# 实时查看系统日志
tail -f /var/log/syslog
tail -f /var/log/auth.log

# 分析 SSH 暴力破解尝试
grep "Failed password" /var/log/auth.log | \
    awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head

# 查看 nginx 错误日志
tail -100 /var/log/nginx/error.log
grep "500\|502\|503" /var/log/nginx/access.log | tail -50

# logrotate:日志轮转(防止日志文件无限增长)
cat /etc/logrotate.d/nginx    # 查看 nginx 的轮转配置
sudo logrotate -f /etc/logrotate.conf  # 手动触发轮转

磁盘空间管理

# df:查看文件系统磁盘使用情况
df -h                     # -h 人类可读(KB/MB/GB)
df -hT                    # -T 显示文件系统类型
df -h /var                # 查看特定挂载点
df -ih                    # -i 显示 inode 使用情况

# df 输出解读
# Filesystem   Size  Used  Avail  Use%  Mounted on
# /dev/sda1     50G   25G    23G   53%   /
# /dev/sdb1    200G  150G    45G   78%   /data

# du:查看目录/文件大小
du -sh /var/log           # -s 只显示总大小 -h 人类可读
du -sh /var/log/*         # 查看子目录各自大小
du -sh /* 2>/dev/null     # 根目录各子目录大小
du -sh /home/* | sort -hr # 按大小排序
du -ah /var/log | sort -hr | head -20  # 找最大的20个文件

# 快速找出占用大空间的目录
du -sh /* 2>/dev/null | sort -hr | head -15

# 查找大文件
find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null
find /var -type f -size +50M 2>/dev/null

# ncdu:交互式磁盘使用分析(需安装)
sudo apt install ncdu
ncdu /var                 # 交互式浏览目录大小
磁盘满了怎么办
  1. df -h — 确认哪个分区满了
  2. du -sh /var/* 2>/dev/null | sort -hr — 定位大目录
  3. 常见罪魁祸首:/var/log(日志)、/tmp(临时文件)、~/.cache(用户缓存)、Docker 镜像/容器
  4. journalctl --vacuum-size=500M — 压缩 journald 日志
  5. docker system prune -af — 清理 Docker 资源

内存与 CPU 性能监控

# free:查看内存使用情况
free -h                   # 人类可读格式
free -h -s 2              # 每2秒刷新一次

# free 输出解读
#              total    used    free  shared  buff/cache  available
# Mem:           16G     4.5G    2.0G    200M       9.5G       11G
# Swap:           2G       0B      2G
#
# available = free + buff/cache(可回收),这才是实际可用内存
# buff/cache 是内核为加速 I/O 缓存的,内存不足时会自动释放

# vmstat:虚拟内存统计
vmstat 1 5                # 每秒刷新,显示5次
vmstat -s                 # 内存统计汇总
vmstat -d                 # 磁盘统计

# vmstat 关键列:
# r  : 可运行进程数(> CPU核心数 表示 CPU 过载)
# b  : 不可中断睡眠进程数(I/O 等待)
# si/so : 交换区读入/写出(非零 = 内存不足)
# bi/bo : 块设备读入/写出(I/O 速率)
# us/sy/id/wa : CPU 用户/内核/空闲/I/O等待百分比

# iostat:I/O 统计
iostat                    # 基本 CPU 和磁盘统计
iostat -x 1 3             # 扩展统计,每秒刷新3次

# iostat 关键列:
# %iowait:CPU 等待 I/O 的时间比例(高 = 磁盘瓶颈)
# await:平均 I/O 等待时间(ms)
# %util:磁盘使用率(接近 100% = 磁盘瓶颈)

# sar:历史性能数据(需要 sysstat)
sudo apt install sysstat
sar -u 1 5                # CPU 使用率(每秒5次)
sar -r 1 5                # 内存使用率
sar -d 1 5                # 磁盘 I/O
sar -n DEV 1 5            # 网络接口统计
sar -u -f /var/log/sysstat/sa01  # 读取历史数据文件

dmesg:内核消息

# dmesg 查看内核环形缓冲区(系统硬件/驱动消息)
dmesg                     # 所有内核消息
dmesg | less              # 分页查看
dmesg | tail -30          # 最新 30 条
dmesg -T                  # -T 显示人类可读时间戳
dmesg -H                  # 带颜色和时间(human-readable)
dmesg -w                  # 实时监控(类似 tail -f)
sudo dmesg -c             # 清空缓冲区(root 权限)

# 过滤特定类型消息
dmesg | grep -i error
dmesg | grep -i "usb"         # USB 设备相关
dmesg | grep -i "eth\|eno\|enp"  # 网卡相关
dmesg | grep -i "oom\|killed"    # OOM killer(内存不足杀进程)
dmesg | grep -i "fail\|error\|warn"  # 错误和警告

# 按级别过滤
dmesg --level=err           # 只看错误
dmesg --level=warn,err      # 警告和错误
dmesg --facility=kern       # 内核消息

# 常见用途
# 1. 查看新接入的 USB 设备
dmesg | tail -20

# 2. 诊断磁盘错误
dmesg | grep -i "I/O error\|ata\|sda"

# 3. 查看内存错误(ECC 服务器)
dmesg | grep -i "mce\|edac\|memory"

strace:系统调用追踪

# strace 追踪进程的系统调用——调试"为什么程序不工作"的利器

# 基本用法
strace ls /tmp              # 追踪 ls 命令的系统调用
strace -o output.txt ls     # -o 输出到文件
strace -p 1234              # -p 追踪运行中的进程
strace -p 1234 -f           # -f 同时追踪子进程

# 常用过滤选项
strace -e trace=open,read,write ls    # 只追踪特定系统调用
strace -e trace=file ls               # 只追踪文件相关调用
strace -e trace=network curl example.com  # 网络调用

# 统计调用次数和时间
strace -c ls /tmp           # -c 统计各系统调用次数/时间

# 实用场景
# 1. 找出程序读取的配置文件
strace -e trace=openat python3 app.py 2>&1 | grep "\.conf\|\.cfg\|\.ini"

# 2. 诊断权限拒绝错误
strace -e trace=open,openat ./app 2>&1 | grep "EACCES\|EPERM"

# 3. 查看程序连接了哪些 IP
strace -e trace=connect ./app 2>&1 | grep "sin_addr"

# ltrace:追踪库函数调用(与 strace 互补)
ltrace ls 2>&1 | head -20

系统备份策略

重要数据与备份原则

3-2-1 备份原则
保留 3 份数据副本,存储在 2 种不同介质上,其中 1 份保存在异地(云端或远程服务器)。这是防止数据丢失的黄金标准。
完整备份 vs 增量备份
完整备份:每次备份全部数据,恢复简单但占用空间大。增量备份:只备份自上次备份以来变化的数据,节省空间但恢复需要依次还原多个备份集。
备份验证
备份的价值在于能够成功恢复。必须定期测试恢复流程,只有经过验证的备份才是真正有效的备份。
# tar 完整备份
tar -czf /backup/home_$(date +%Y%m%d).tar.gz /home/
tar -czf /backup/etc_$(date +%Y%m%d).tar.gz /etc/
tar -czf /backup/www_$(date +%Y%m%d).tar.gz /var/www/ --exclude=/var/www/cache

# rsync 增量备份(保留删除文件的历史)
rsync -avz --delete \
    --backup --backup-dir="/backup/incremental/$(date +%Y%m%d)" \
    /home/ /backup/current/home/

# rsync + hard link 增量备份(高效)
BACKUP_DIR="/backup"
LATEST="$BACKUP_DIR/latest"
TODAY="$BACKUP_DIR/$(date +%Y%m%d)"

rsync -avz --delete \
    --link-dest="$LATEST" \
    /home/ "$TODAY/"

ln -nsf "$TODAY" "$LATEST"   # 更新 latest 链接

# 数据库备份
# MySQL/MariaDB
mysqldump -u root -p --all-databases > /backup/mysql_$(date +%Y%m%d).sql
mysqldump -u root -p mydb | gzip > /backup/mydb_$(date +%Y%m%d).sql.gz

# PostgreSQL
pg_dump mydb > /backup/pgdb_$(date +%Y%m%d).sql
pg_dumpall | gzip > /backup/pg_all_$(date +%Y%m%d).sql.gz

# 远程备份(rsync over SSH)
rsync -avz -e "ssh -p 2222 -i ~/.ssh/backup_key" \
    /data/ backup-server:/remote-backup/data/

# 定时备份(cron)
crontab -e
# 每天凌晨2点备份
# 0 2 * * * /usr/local/bin/backup.sh >> /var/log/backup.log 2>&1

定时任务:cron

# crontab 格式:
# 分 时 日 月 周  命令
# *  *  *  *  *   command
# │  │  │  │  └── 星期 (0-7, 0和7都是周日)
# │  │  │  └───── 月份 (1-12)
# │  │  └──────── 日期 (1-31)
# │  └─────────── 小时 (0-23)
# └────────────── 分钟 (0-59)

crontab -e              # 编辑当前用户的 crontab
crontab -l              # 查看当前用户的 crontab
sudo crontab -u alice -e  # 编辑 alice 的 crontab(root)

# 常用 cron 示例
# 每天凌晨2点
# 0 2 * * * /scripts/backup.sh

# 每5分钟
# */5 * * * * /scripts/check.sh

# 每周一9:00
# 0 9 * * 1 /scripts/weekly-report.sh

# 每月1日0:00
# 0 0 1 * * /scripts/monthly.sh

# 工作日每小时(9-17点)
# 0 9-17 * * 1-5 /scripts/hourly-job.sh

系统信息全览

# 系统基本信息
uname -a                  # 内核版本、主机名、架构
cat /etc/os-release       # 发行版详细信息
lsb_release -a            # Ubuntu/Debian 发行版信息
hostname                  # 主机名
uptime                    # 运行时间和平均负载
date                      # 当前时间
timedatectl               # 时区和 NTP 同步状态

# 硬件信息
lscpu                     # CPU 详细信息
lsmem                     # 内存区域信息
lsblk                     # 块设备(磁盘分区)
lspci                     # PCI 设备列表(网卡、显卡等)
lsusb                     # USB 设备列表
dmidecode -t memory        # 内存条详细信息(需 root)
smartctl -a /dev/sda       # 磁盘健康状态(需安装 smartmontools)

# 综合系统信息
neofetch                  # 美观的系统信息显示(需安装)
inxi -Fxz                 # 详细系统信息(需安装 inxi)

# 网络配置
ip addr show              # 网络接口和 IP
ip route show             # 路由表
cat /etc/resolv.conf      # DNS 配置
cat /etc/hosts            # hosts 文件

综合运维脚本示例

#!/usr/bin/env bash
# 系统健康检查脚本
set -euo pipefail

WARN_CPU=80
WARN_MEM=85
WARN_DISK=90

check_cpu() {
    local usage
    usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1 | cut -d'.' -f1)
    if [ "$usage" -gt "$WARN_CPU" ]; then
        echo "警告: CPU 使用率 ${usage}%(阈值 ${WARN_CPU}%)"
    fi
}

check_memory() {
    local usage
    usage=$(free | awk '/Mem:/{printf "%.0f", $3/$2*100}')
    if [ "$usage" -gt "$WARN_MEM" ]; then
        echo "警告: 内存使用率 ${usage}%(阈值 ${WARN_MEM}%)"
    fi
}

check_disk() {
    df -h | awk 'NR>1{
        gsub(/%/,""); 
        if ($5+0 > '"$WARN_DISK"') 
            print "警告: 磁盘 " $6 " 使用率 " $5 "%(阈值 '"$WARN_DISK"'%)"
    }'
}

check_services() {
    local services=("nginx" "mysql" "redis")
    for svc in "${services[@]}"; do
        if ! systemctl is-active "$svc" &>/dev/null; then
            echo "警告: 服务 $svc 未运行"
        fi
    done
}

echo "=== 系统健康检查 $(date) ==="
check_cpu
check_memory
check_disk
check_services
echo "=== 检查完成 ==="
本章小结

Linux 系统管理与运维的核心要点:① df -h 查磁盘分区使用率,df -i 查 inode 使用率(两者都要监控);② du -sh /* 2>/dev/null | sort -hr 快速定位磁盘占用大户;③ free 输出中 available 才是真正可用内存(free + buff/cache),不要看 free 列;④ vmstat 的 si/so 非零说明在使用 Swap(内存不足的强信号),wa 高说明磁盘 I/O 是瓶颈;⑤ dmesg | grep -i "oom\|killed" 检查 OOM killer 是否杀过进程;⑥ strace 是调试"程序为什么找不到文件"的利器——strace -e trace=openat ./app 2>&1 | grep EACCES;⑦ 备份遵循 3-2-1 原则,rsync --link-dest 实现空间高效的增量备份;⑧ crontab 中命令使用绝对路径,输出重定向到日志,方便排查定时任务问题。

Linux 运维学习路径

掌握了本教程的内容后,建议继续深入学习: