Ubuntu 常用运维指令手册

运维指令手册 31.4 KB 原文

Ubuntu 常用运维指令手册

适用版本:Ubuntu 20.04 / 22.04 / 24.04 LTS(Server 与 Desktop 通用) 约定:$ 开头为普通用户执行,# 开头为 root 或 sudo 执行,<xxx> 为需替换的占位符。 排序原则:按运维实际场景组织,每节内按「查看 → 变更 → 排查」递进。


目录

  1. 系统信息与状态
  2. 用户与权限管理
  3. 文件与目录操作
  4. 文本处理与内容查找
  5. 磁盘与文件系统
  6. 软件包管理
  7. 服务与 systemd
  8. 进程与资源管理
  9. 网络配置与诊断
  10. 防火墙与安全加固
  11. 日志与排障
  12. 定时任务
  13. 压缩、备份与传输
  14. 性能监控与调优
  15. SSH 与远程运维
  16. 高频故障速查表
  17. 危险命令与避坑清单

1. 系统信息与状态

1.1 版本与内核

lsb_release -a                 # 发行版信息(需 lsb-release 包)
cat /etc/os-release            # 更可靠,无需额外安装
uname -r                       # 当前内核版本
uname -m                       # CPU 架构(x86_64 / aarch64)
hostnamectl                    # 主机名、系统版本、内核、虚拟化类型一次看全
cat /etc/hostname              # 主机名文件

1.2 硬件资源

lscpu                          # CPU 型号、核心数、NUMA、虚拟化支持
free -h                        # 内存与 swap 使用,-h 人类可读
lsblk -f                       # 块设备树 + 文件系统 + UUID
lspci | grep -i vga            # 显卡;grep -i eth 查网卡
lsusb                          # USB 设备
dmidecode -t system            # 厂商/型号/序列号(需 sudo)
nproc                          # CPU 逻辑核数(脚本中常用)

1.3 开机时长与负载

uptime                         # 当前时间、运行时长、1/5/15 分钟负载
who -b                         # 上次启动时间
last reboot | head             # 重启历史
w                              # 谁在线 + 正在执行的命令

负载判读:负载值应 ≤ CPU 核数。nproc 为 8 时负载 10 表示已过载,需结合 vmstat 看是 CPU 密集还是 IO 等待。

1.4 时间与时区

timedatectl                    # 时间、时区、NTP 同步状态
sudo timedatectl set-timezone Asia/Shanghai
sudo timedatectl set-ntp true  # 启用自动对时
date -s "2026-11-05 10:00:00"  # 手动设置(不推荐,优先用 NTP)

2. 用户与权限管理

2.1 用户增删改查

# 查看
id <user>                              # UID/GID/所属组
getent passwd <user>                   # 从 NSS 取用户信息(含 LDAP)
cat /etc/passwd | grep <user>
who                                    # 当前登录会话

# 创建(-m 建家目录,-s 指定 shell,-G 附加组)
sudo useradd -m -s /bin/bash -G sudo,dev <user>
sudo passwd <user>                     # 设置密码

# 修改
sudo usermod -aG docker <user>          # 追加组(必须带 -a,否则覆盖原有组)
sudo usermod -L <user>                 # 锁定账号
sudo usermod -U <user>                 # 解锁
sudo usermod -s /usr/sbin/nologin <user> # 禁止登录(保留服务账号)
sudo usermod -d /new/home -m <user>    # 迁移家目录

# 删除(-r 同时删家目录与邮件池)
sudo userdel -r <user>

2.2 密码策略

sudo passwd -e <user>        # 强制下次登录修改密码
sudo passwd -l <user>        # 锁定密码
sudo chage -l <user>         # 查看密码有效期
sudo chage -M 90 -W 7 <user> # 90 天过期,提前 7 天提醒

全局策略在 /etc/login.defs 与 /etc/security/pwquality.conf(libpam-pwquality 包)。

2.3 组管理

sudo groupadd <group>
sudo groupdel <group>
sudo gpasswd -a <user> <group>   # 加入组(等价 usermod -aG)
sudo gpasswd -d <user> <group>   # 移出组
getent group <group>             # 查看组成员

2.4 sudo 提权

sudo visudo                                  # 安全编辑 /etc/sudoers(带语法检查)
sudo visudo -f /etc/sudoers.d/<filename>     # 推荐:分文件管理,避免动主文件
sudo -l                                      # 查看当前用户可执行的 sudo 命令
sudo -u <user> <command>                     # 以指定用户身份执行
sudo -i                                      # 切换到 root 交互 shell
sudo -s                                      # 保留当前环境变量切 root

/etc/sudoers.d/ops 示例(免密执行特定命令,比 ALL 安全):

ops ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/journalctl -u nginx

修改后务必验证:sudo visudo -c 检查语法,语法错误会导致无法提权。

2.5 文件权限

chmod 755 <path>             # rwxr-xr-x:目录、可执行文件
chmod 644 <path>             # rw-r--r--:普通文件、配置
chmod -R 750 <dir>           # 递归
chmod u+x,g-w,o-rwx <path>   # 符号法
chown <user>:<group> <path>
chown -R www-data:www-data /var/www/html

# umask:新建文件的默认权限掩码
umask                        # 查看,常见 022 → 文件 644 / 目录 755
umask 027                    # 同组可读、其他人无权限

# ACL:细粒度授权(不适合用组表达时)
sudo apt install acl
setfacl -m u:alice:rw /data/report.csv
getfacl /data/report.csv
setfacl -x u:alice /data/report.csv      # 移除单条
setfacl -b /data/report.csv              # 清空全部 ACL

# 特殊属性:防误删(连 root 也不能删)
sudo chattr +i /etc/nginx/nginx.conf
lsattr /etc/nginx/nginx.conf
sudo chattr -i /etc/nginx/nginx.conf

数字权限速记

值 权限 值 权限
7 rwx 4 r--
6 rw- 3 -wx
5 r-x 2 -w-
1 --x 0 ---

粘滞位:目录上加 chmod 1777(如 /tmp),仅文件所有者可删除自己的文件。


3. 文件与目录操作

3.1 浏览与导航

ls -alh                    # 全部(含隐藏)+ 长格式 + 人类可读大小,按时间排序加 -t
ls -lhS                    # 按大小降序
tree -L 2 -d               # 只显示 2 层目录(tree 需安装)
pwd                        # 当前路径
cd -                       # 回到上一个目录
realpath <path>            # 解析为绝对路径(含符号链接)
readlink -f <path>         # 同上
stat <file>                # inode、权限、三个时间戳(atime/mtime/ctime)

3.2 创建、复制、移动、删除

mkdir -p /data/app/{logs,conf,tmp}   # 递归 + 一次建多个
cp -a /src/. /dst/                   # 保留权限/时间/链接,含隐藏文件
cp -r --no-clobber /src /dst         # 不覆盖已存在文件(22.04+ 支持)
mv <src> <dst>
ln -s /opt/app/current /opt/app/releases/v1.2.3   # 符号链接
rm -i <file>                         # 交互确认
rm -rf <dir>                         # ⚠️ 高危,见第 17 节

cp -a /src/. /dst/ 与 cp -a /src /dst/ 的区别:前者把 /src 的内容放进 /dst,后者会在 /dst 下再建一层 /src。备份场景极易踩坑。

3.3 查找文件

# 按名/类型/大小/时间
find /var/log -name "*.log" -size +100M
find / -type f -name "*.conf" -mtime -7          # 7 天内修改
find /tmp -type f -mmin +60 -delete              # 60 分钟前的文件并删除
find /data -type d -empty                        # 空目录
find . -maxdepth 2 -type f -perm -u+x            # 有执行权限的文件
find . -type f -newer /tmp/marker                # 比参考文件更新的

# 配合执行
find /var/log -name "*.gz" -exec ls -lh {} \;
find . -type f -name "*.log" -print0 | xargs -0 gzip   # 处理含空格文件名

# 数据库式查找(快,但需先建索引)
sudo updatedb
locate nginx.conf

# 按内容查找
grep -rl "listen 8080" /etc/nginx/

3.4 归档前的常用组合

# 找出最大的 20 个文件
du -ah / 2>/dev/null | sort -rh | head -20
# 找出最大的 20 个目录(只下一层)
du -h --max-depth=1 /var 2>/dev/null | sort -rh | head -20

4. 文本处理与内容查找

4.1 查看

cat <file>
less +F <file>              # 类似 tail -f,Ctrl+C 暂停后可翻页
head -n 50 <file>
tail -n 100 <file>
tail -f <file>              # 实时跟踪
tail -F <file>              # 文件被轮转后仍能跟踪(运维首选)

4.2 过滤与统计

grep -rn "ERROR" /var/log/app/          # 递归 + 显示行号
grep -i "timeout" <file>                # 忽略大小写
grep -v "^#" <file> | grep -v "^$"      # 去注释与空行(读配置必备)
grep -c "pattern" <file>                # 计数
grep -A3 -B3 "Exception" <file>         # 前后各 3 行上下文
grep -E "error|fail|critical" <file>    # 扩展正则

awk '{print $1}' access.log | sort | uniq -c | sort -rn | head
# 统计访问量 Top10 IP(nginx 默认日志)

awk '$9 == 502 {print}' access.log | wc -l       # 统计 502 数量

sed -n '100,200p' <file>                # 打印 100-200 行
sed -i 's/old/new/g' <file>             # 原地替换(先备份:cp file file.bak)
sed -i '/^$/d' <file>                   # 删除空行

cut -d: -f1 /etc/passwd                 # 按分隔符取字段
sort -u <file>                          # 去重排序
uniq -c                                 # 需先 sort
wc -l <file>                            # 行数

4.3 实时多文件跟踪

tail -f /var/log/nginx/access.log /var/log/nginx/error.log
multitail /var/log/syslog /var/log/auth.log      # 分屏(需安装 multitail)
journalctl -u nginx -f                            # systemd 场景首选

5. 磁盘与文件系统

5.1 容量查看

df -h                          # 各挂载点使用率(含 tmpfs,可加 -x tmpfs 过滤)
df -i                          # inode 使用率("磁盘没满却写不进去"的元凶)
du -sh /var/*                  # 各子目录大小
du -h --max-depth=1 . | sort -rh
ncdu /var                      # 交互式磁盘分析(推荐安装)

5.2 分区与挂载

lsblk                          # 块设备树
sudo fdisk -l                  # 分区表
sudo parted -l                 # GPT 分区信息
blkid                          # UUID 与文件系统类型(写 fstab 用这个)
findmnt                        # 当前挂载树,比 mount 输出清晰
cat /proc/mounts

# 新盘初始化(MBR 用 fdisk,>2T 用 parted + GPT)
sudo parted /dev/sdb --script mklabel gpt
sudo parted /dev/sdb --script mkpart primary ext4 0% 100%
sudo mkfs.ext4 -L data /dev/sdb1
sudo mkdir -p /data
sudo mount /dev/sdb1 /data

5.3 永久挂载 /etc/fstab

UUID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx  /data  ext4  defaults,nofail  0  2
sudo mount -a              # 应用 fstab,务必先测试再重启
sudo systemctl daemon-reload

nofail 很重要:磁盘缺失时不阻塞开机,避免服务器卡在 emergency mode。 改 fstab 前先备份:sudo cp /etc/fstab /etc/fstab.bak。写错会导致无法正常启动。

5.4 扩容

# ext4 在线扩容(先扩分区或云盘,再扩文件系统)
sudo growpart /dev/sda 1        # 扩展分区到磁盘末尾(cloud-utils-growpart)
sudo resize2fs /dev/sda1

# xfs 只能扩不能缩
sudo xfs_growfs /data

# LVM
sudo pvcreate /dev/sdc
sudo vgcreate vg_data /dev/sdc
sudo lvcreate -L 100G -n lv_app vg_data
sudo lvextend -L +50G /dev/vg_data/lv_app
sudo resize2fs /dev/vg_data/lv_app     # 或 xfs_growfs
sudo pvs && sudo vgs && sudo lvs       # 查看状态

5.5 swap

swapon --show
free -h
sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab   # 持久化
sudo swapoff /swapfile                                        # 关闭

5.6 磁盘健康

sudo smartctl -a /dev/sda          # 需 smartmontools
sudo badblocks -sv /dev/sdb        # ⚠️ 只读扫描加 -n,否则会破坏数据
dmesg -T | grep -i "i/o error"     # 内核层 IO 错误

6. 软件包管理

6.1 apt 基础

sudo apt update                     # 刷新索引(只更新列表,不升级)
sudo apt upgrade                    # 升级已装包(不删包)
sudo apt full-upgrade               # 允许为解决依赖而增删包
sudo apt install <pkg>              # 安装
sudo apt install -y <pkg1> <pkg2>
sudo apt remove <pkg>               # 卸载,保留配置
sudo apt purge <pkg>                # 卸载并删配置
sudo apt autoremove --purge         # 清理无用依赖
sudo apt clean                      # 清理 /var/cache/apt/archives

sudo apt search <keyword>
apt list --installed | grep <pkg>
apt-cache policy <pkg>              # 已装/可装版本、来源仓库
apt-cache show <pkg>                # 包详情

sudo apt --reinstall install <pkg>  # 修复被误删的文件
sudo apt-mark hold <pkg>            # 锁定版本,防止被升级
sudo apt-mark unhold <pkg>
apt-mark showhold

6.2 依赖与状态修复

sudo apt-get -f install             # 修复依赖断裂
sudo dpkg --configure -a            # 修复安装中断("dpkg was interrupted")
sudo apt --fix-broken install
sudo rm /var/lib/dpkg/lock-frontend # ⚠️ 仅在确认无 apt 进程运行时
sudo rm /var/lib/apt/lists/lock

6.3 dpkg 本地包

sudo dpkg -i ./app_1.0_amd64.deb
sudo dpkg -l | grep <pkg>           # 列出已装
dpkg -L <pkg>                       # 该包安装的所有文件路径
dpkg -S /usr/bin/nginx              # 反查文件属于哪个包
dpkg -s <pkg>                       # 包状态详情
sudo dpkg -r <pkg>

6.4 软件源

# 22.04/20.04:/etc/apt/sources.list 与 /etc/apt/sources.list.d/*.list
# 24.04:/etc/apt/sources.list.d/ubuntu.sources(deb822 新格式)

sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo sed -i 's|http://archive.ubuntu.com|https://mirrors.aliyun.com|g' /etc/apt/sources.list
sudo apt update

sudo add-apt-repository ppa:<user>/<repo>     # 添加 PPA
sudo add-apt-repository --remove ppa:<user>/<repo>

# 导入第三方 GPG key(现代写法)
curl -fsSL https://example.com/key.gpg | sudo gpg --dearmor -o /usr/share/keyrings/example.gpg

6.5 snap

snap list
sudo snap install <pkg> --classic     # 需要宽权限的包(如 code、kubectl)
sudo snap refresh                     # 更新全部
sudo snap refresh <pkg> --channel=stable
sudo snap remove <pkg> --purge
sudo snap services                    # 查看 snap 服务

7. 服务与 systemd

7.1 unit 管理

systemctl status nginx                  # 状态 + 最近日志
sudo systemctl start|stop|restart nginx
sudo systemctl reload nginx             # 重载配置(不断连接,优先用这个)
sudo systemctl enable nginx             # 开机自启
sudo systemctl disable nginx
sudo systemctl enable --now nginx       # 启用并立即启动
sudo systemctl is-active nginx
sudo systemctl is-enabled nginx
sudo systemctl mask nginx               # 彻底禁止启动(比 disable 更强)
sudo systemctl unmask nginx

7.2 全局排查

systemctl list-units --type=service --state=running
systemctl list-units --failed           # 启动失败的服务,排障第一步
systemctl list-unit-files --state=enabled
systemctl list-timers --all             # 定时器总览
systemd-analyze blame                   # 开机耗时排序
systemd-analyze critical-chain          # 关键启动链路
sudo systemctl daemon-reload            # 改完 unit 文件必须执行

7.3 自定义服务

/etc/systemd/system/myapp.service:

[Unit]
Description=My Application
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=app
Group=app
WorkingDirectory=/opt/myapp
Environment="APP_ENV=prod"
EnvironmentFile=-/etc/myapp/env
ExecStart=/opt/myapp/bin/server --port 8080
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now myapp
sudo systemctl status myapp

Restart 策略选择

值 含义 适用
no 不重启 一次性任务
on-failure 非 0 退出或被信号杀死 大多数服务(推荐)
always 总是重启 守护型常驻进程
on-abnormal 超时/信号/看门狗 避免配置错误时无限重启

7.4 覆盖而非改包自带 unit

sudo systemctl edit nginx            # 生成 /etc/systemd/system/nginx.service.d/override.conf
sudo systemctl edit --full nginx     # 复制完整 unit 再改(升级时可能被覆盖)

8. 进程与资源管理

8.1 查看

ps aux                              # 全部进程快照
ps -ef --forest                     # 进程树
ps -eo pid,ppid,user,%cpu,%mem,etime,cmd --sort=-%cpu | head -15
pgrep -a nginx                      # 按名查 PID 并显示命令行
pidof nginx
pstree -p                           # 进程树带 PID

8.2 终止

kill <pid>              # SIGTERM(15),优雅退出
kill -9 <pid>           # SIGKILL,强杀(跳过清理,慎用)
kill -HUP <pid>         # 重载配置(很多守护进程支持)
pkill -f "python app.py"   # 按完整命令行匹配
pkill -u <user>            # 杀某用户全部进程
killall nginx

8.3 优先级与后台

nice -n 10 <cmd>              # 以低优先级启动(-20 最高,19 最低)
renice -n 5 -p <pid>
sudo ionice -c3 -p <pid>      # IO 优先级(idle 类)

<cmd> &                       # 后台运行
jobs -l                       # 查看当前 shell 作业
fg %1 / bg %1                 # 前后台切换
nohup <cmd> > /var/log/x.log 2>&1 &   # 退出终端不中断
disown -h %1                  # 已启动任务脱离 shell

长期运行的服务不要用 nohup,用 systemd 或 tmux。nohup 进程崩溃后无人拉起,也没有日志轮转。

tmux new -s ops               # 新建会话
tmux attach -t ops            # 重连(SSH 断线后救场)
tmux ls
# Ctrl+b d 分离,Ctrl+b c 新窗口,Ctrl+b " 水平分割

8.4 端口占用

sudo ss -tulnp | grep :8080     # 推荐的现代写法
sudo lsof -i :8080
sudo fuser -k 8080/tcp          # ⚠️ 直接杀掉占用者

9. 网络配置与诊断

9.1 地址与路由

ip a                            # 所有网卡地址(替代 ifconfig)
ip -4 a show dev eth0
ip r                            # 路由表
ip route get 8.8.8.8            # 查某目标走哪条路由
ip link set eth0 up|down
sudo ip addr add 192.168.1.10/24 dev eth0      # 临时加地址,重启失效
sudo ip route add 10.0.0.0/8 via 192.168.1.1
sudo ip neigh                   # ARP 表

9.2 静态 IP(netplan,Ubuntu 17.10+ 唯一方式)

/etc/netplan/50-cloud-init.yaml:

network:
  version: 2
  ethernets:
    eth0:
      dhcp4: false
      addresses: [192.168.1.10/24]
      routes:
        - to: default
          via: 192.168.1.1
      nameservers:
        addresses: [223.5.5.5, 8.8.8.8]
sudo netplan try        # 试运行,120 秒内不确认会自动回滚(远程操作必用)
sudo netplan apply

YAML 对缩进极其敏感,只能用空格。改错会导致断网,远程服务器务必先用 netplan try。

9.3 连通性诊断(由近到远)

ping -c 4 8.8.8.8               # 三层连通
ping -c 4 www.baidu.com         # 三层 + DNS
tracepath <host>                # 路径追踪(无需 root)
traceroute -n <host>
mtr -rwc 20 <host>              # 持续探测 + 丢包统计(排网络抖动首选)
curl -I https://example.com     # HTTP 头
curl -v -o /dev/null -w "%{http_code} %{time_total}\n" https://example.com
curl --resolve example.com:443:1.2.3.4 https://example.com   # 绕过 DNS 直连验证
nc -zv <host> 3306              # 端口探测(需 netcat-openbsd)
telnet <host> 80

9.4 DNS

resolvectl status              # systemd-resolved 的 DNS 配置
resolvectl query example.com
dig example.com +short
dig @8.8.8.8 example.com A
nslookup example.com
cat /etc/resolv.conf           # 注意:常被 systemd-resolved 接管

修改 DNS 应改 /etc/systemd/resolved.conf 或 netplan 配置,直接改 /etc/resolv.conf 会被覆盖。

9.5 抓包与网卡状态

sudo tcpdump -i any -nn port 80 -c 50
sudo tcpdump -i eth0 -nn host 1.2.3.4 and tcp port 443 -w /tmp/cap.pcap
sudo tcpdump -i any -nn 'tcp[tcpflags] & tcp-syn != 0'    # 只看 SYN

ethtool eth0                   # 速率、双工、链路状态
ethtool -S eth0 | grep -i error
ip -s link                     # 网卡收发统计与错误计数
nmcli device status            # NetworkManager 管理的连接

9.6 带宽观测

iftop -i eth0                  # 实时连接级流量
nethogs                        # 按进程看流量
sudo apt install iftop nethogs mtr netcat-openbsd -y

10. 防火墙与安全加固

10.1 ufw(Ubuntu 默认,推荐)

sudo ufw status verbose          # 查看状态与规则
sudo ufw status numbered         # 带编号,便于删除
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp            # ⚠️ 启用前必须先放行 SSH
sudo ufw allow from 192.168.1.0/24 to any port 3306 proto tcp
sudo ufw limit 22/tcp            # 限速,缓解暴力破解
sudo ufw delete <num>
sudo ufw delete allow 80/tcp
sudo ufw enable
sudo ufw disable
sudo ufw reset                    # 清空全部规则

顺序铁律:先 allow 22,再 enable。反过来会导致远程服务器失联(云厂商控制台 VNC 才能救)。

10.2 iptables / nftables

sudo iptables -L -n -v --line-numbers
sudo iptables -I INPUT -s 1.2.3.4 -j DROP        # 临时封 IP
sudo iptables -D INPUT -s 1.2.3.4 -j DROP

# 持久化(iptables-persistent)
sudo apt install iptables-persistent
sudo netfilter-persistent save

# 22.04+ 底层已是 nftables
sudo nft list ruleset

10.3 fail2ban(防暴力破解)

sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 1.2.3.4

/etc/fail2ban/jail.local 关键项:

[DEFAULT]
bantime  = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 192.168.1.0/24

[sshd]
enabled = true
port    = ssh
logpath = %(sshd_log)s

10.4 安全巡检清单

# 登录失败记录
sudo lastb | head -20
sudo grep "Failed password" /var/log/auth.log | tail -20

# 当前登录与历史
who; last -n 20

# 计划任务是否被植入
crontab -l; sudo ls -l /etc/cron.*/ /etc/cron.d/
sudo systemctl list-timers --all

# 监听端口审计(暴露面)
sudo ss -tulnp

# SUID 文件排查
sudo find / -perm -4000 -type f 2>/dev/null

# 文件完整性(需先装 aide 或 debsums)
sudo debsums -c

# 自动安全更新
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades

10.5 AppArmor

sudo aa-status
sudo aa-enforce /etc/apparmor.d/usr.sbin.nginx
sudo aa-complain /etc/apparmor.d/usr.sbin.nginx

11. 日志与排障

11.1 journalctl(systemd 日志)

journalctl -xe                          # 最近的错误与解释(排障第一站)
journalctl -u nginx                     # 指定服务
journalctl -u nginx -f                  # 实时跟踪
journalctl -u nginx --since "1 hour ago"
journalctl --since "2026-11-05 08:00" --until "2026-11-05 09:00"
journalctl -p err -b                    # 本次启动的错误级别以上
journalctl -k                           # 内核日志(等价 dmesg)
journalctl --disk-usage
sudo journalctl --vacuum-time=7d        # 只保留 7 天
sudo journalctl --vacuum-size=500M      # 限制总量
journalctl -b -1                        # 上一次启动的日志(排查崩溃重启)
journalctl -o json-pretty -n 1          # 结构化输出

持久化日志(默认存 /run,重启丢失):sudo mkdir -p /var/log/journal && sudo systemctl restart systemd-journald。

/etc/systemd/journald.conf 常用项:Storage=persistent、SystemMaxUse=1G、MaxRetentionSec=30day。

11.2 传统日志文件

ls -lh /var/log/
tail -F /var/log/syslog                 # 系统总日志
tail -F /var/log/auth.log               # 认证/登录
tail -F /var/log/kern.log               # 内核
tail -F /var/log/dpkg.log               # 包安装记录
zgrep "error" /var/log/syslog.2.gz      # 查已轮转的压缩日志

11.3 dmesg

sudo dmesg -T                  # 带可读时间戳
sudo dmesg -T | grep -iE "error|fail|oom"
sudo dmesg -w                  # 实时跟踪
sudo dmesg -C                  # 清空(调试时便于只看新日志)

11.4 日志轮转

/etc/logrotate.d/myapp:

/var/log/myapp/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    copytruncate
    create 0640 app app
}
sudo logrotate -d /etc/logrotate.d/myapp    # 干跑,只输出不执行
sudo logrotate -f /etc/logrotate.d/myapp    # 强制执行

copytruncate 适用于不支持重开日志文件的程序(如部分 Java/Python 应用),配合 logrotate 可避免必须重启服务。


12. 定时任务

12.1 cron

crontab -e                 # 编辑当前用户任务
crontab -l                 # 列出
crontab -r                 # ⚠️ 删除全部任务
sudo crontab -u <user> -l  # 查看指定用户

格式:分 时 日 月 周 命令

# 每天 03:30 备份
30 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1

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

# 工作日 9 点到 18 点每小时
0 9-18 * * 1-5 /opt/scripts/sync.sh

# 每月 1 日 0 点
0 0 1 * * /opt/scripts/monthly.sh

/etc/cron.d/myjob(带用户字段):

SHELL=/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
30 3 * * * root /opt/scripts/backup.sh

cron 三大坑

  1. 环境变量不同:cron 的 PATH 极简,命令写绝对路径,或在脚本头部显式 export PATH。
  2. 不加载 profile:脚本里 source /etc/profile 或直接写死变量。
  3. 输出被丢弃:一定要重定向 >> log 2>&1,否则报错无处可查。
sudo systemctl status cron        # cron 服务自身状态
grep CRON /var/log/syslog | tail  # 确认任务是否被触发

12.2 systemd timer(更可靠,推荐生产使用)

/etc/systemd/system/backup.service + backup.timer:

# backup.service
[Unit]
Description=Daily backup

[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
# backup.timer
[Unit]
Description=Run backup daily at 03:30

[Timer] 03:30:00
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers --all
journalctl -u backup.service

Persistent=true 会在关机错过时间点后补跑,这是 cron 做不到的。

12.3 at(一次性)

echo "/opt/scripts/restart.sh" | at 02:00
at -l
atrm <job>

13. 压缩、备份与传输

13.1 tar

tar -czf backup-$(date +%F).tar.gz /data/app        # 压缩
tar -xzf backup.tar.gz -C /restore                  # 解压到指定目录
tar -tzf backup.tar.gz | head                       # 查看内容不解压
tar -czf x.tar.gz --exclude='*.log' --exclude='node_modules' /app
tar -cjf x.tar.bz2 <dir>                            # bzip2,更小更慢
tar --zstd -cf x.tar.zst <dir>                      # zstd,现代首选

13.2 rsync(增量备份核心工具)

# 本地同步(-a 归档 -v 详细 -z 压缩 -P 进度+断点续传)
rsync -avzP /data/app/ /backup/app/

# 远程拉取
rsync -avzP -e "ssh -p 2222" user@host:/data/app/ /backup/app/

# 镜像同步(--delete 删除目标端多余文件,⚠️ 危险)
rsync -avz --delete /src/ /dst/

# 只同步变更,排除大目录,带限速
rsync -avz --exclude='.git' --exclude='cache/' --bwlimit=5000 /data/ /backup/data/

# 干跑预览(执行前必做)
rsync -avz --delete --dry-run /src/ /dst/

路径尾部斜杠是语义开关:/src/ 表示"src 的内容",/src 表示"src 这个目录本身"。备份写错会多一层嵌套。

13.3 scp / sftp

scp file.tar.gz user@host:/tmp/
scp -r user@host:/var/log/app ./logs/
scp -P 2222 file user@host:/tmp/       # 注意是大写 P
sftp user@host                          # 交互式传输

13.4 数据库备份

# MySQL / MariaDB
mysqldump -u root -p --single-transaction --routines --triggers db > db-$(date +%F).sql
mysqldump -u root -p --all-databases | gzip > all-$(date +%F).sql.gz
mysql -u root -p db < db.sql

# PostgreSQL
pg_dump -U postgres -Fc db > db.dump
pg_restore -U postgres -d db db.dump
pg_dumpall -U postgres | gzip > all.sql.gz

13.5 备份脚本模板

#!/usr/bin/env bash
set -euo pipefail

BACKUP_DIR=/backup
SRC=/data/app
STAMP=$(date +%F_%H%M)
KEEP_DAYS=14

mkdir -p "$BACKUP_DIR"
tar -czf "$BACKUP_DIR/app-$STAMP.tar.gz" -C "$(dirname "$SRC")" "$(basename "$SRC")"
find "$BACKUP_DIR" -name 'app-*.tar.gz' -mtime +$KEEP_DAYS -delete

echo "[$(date '+%F %T')] backup ok: app-$STAMP.tar.gz"

set -euo pipefail 是运维脚本标配:出错即停、未定义变量报错、管道中任一环失败即失败。


14. 性能监控与调优

14.1 快速三连

uptime            # 负载趋势
free -h           # 内存是否吃紧
df -h             # 磁盘是否将满
top -b -n1 | head -20   # CPU 占用 Top

14.2 vmstat(CPU/内存/IO 全景)

vmstat 1 5
列 含义 关注点
r 运行队列长度 持续 > 核数说明 CPU 不足
b 阻塞进程数 高说明 IO 等待严重
si/so swap 换入换出 非 0 说明内存不足
us/sy 用户态/内核态 CPU sy 高说明系统调用或中断多
wa IO 等待占比 持续 > 20% 查磁盘
id 空闲 长期接近 0 需扩容

14.3 iostat / iotop

iostat -xz 1 5        # -x 扩展指标 -z 隐藏空闲设备
iotop -oP             # 按进程看 IO,-o 只显示有 IO 的

iostat -x 关键指标:%util 接近 100% 表示磁盘饱和;await 远高于 svctm 说明排队严重;aqu-sz 队列长度持续 > 2 需关注。

14.4 内存

free -h
cat /proc/meminfo | head -20
ps -eo pid,user,rss,cmd --sort=-rss | head -10     # RSS 排序
smem -tk                                            # 更准的共享内存统计
sudo slabtop                                        # 内核 slab 占用

free 的 available 才是真正可用的量,buff/cache 可被回收,不要看到 free 很小就以为内存不足。

14.5 历史趋势(sar)

sudo apt install sysstat
sudo sed -i 's/ENABLED="false"/ENABLED="true"/' /etc/default/sysstat
sudo systemctl restart sysstat

sar -u 1 5        # CPU
sar -r 1 5        # 内存
sar -d 1 5        # 磁盘
sar -n DEV 1 5    # 网络
sar -u -f /var/log/sysstat/sa05   # 回看某天

sar 是事后复盘"昨天 3 点为什么卡"的唯一可靠数据源,生产机器建议常开。

14.6 压测与文件句柄

ulimit -n                          # 当前进程文件句柄上限
ulimit -n 65535                    # 临时提高(仅当前 shell)
cat /proc/<pid>/limits             # 某进程实际限制

# 全局永久:/etc/security/limits.conf
*  soft  nofile  65535
*  hard  nofile  65535
# systemd 服务还需在 unit 里设 LimitNOFILE=65535

sysctl net.core.somaxconn          # 监听队列上限
sysctl fs.file-max                 # 系统级句柄上限
sudo sysctl -p                     # 应用 /etc/sysctl.conf

15. SSH 与远程运维

15.1 密钥登录

ssh-keygen -t ed25519 -C "ops@company"     # 现代推荐算法
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
ssh -i ~/.ssh/id_ed25519 user@host

~/.ssh/config 管理多主机:

Host prod-web
    HostName 10.0.1.10
    User ops
    Port 2222
    IdentityFile ~/.ssh/id_ed25519
    ServerAliveInterval 60
    ServerAliveCountMax 3
ssh prod-web               # 直接用别名
ssh -v prod-web            # 排查握手失败

15.2 服务端加固

/etc/ssh/sshd_config.d/99-hardening.conf:

Port 2222
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers ops deploy
sudo sshd -t                      # 先检查配置语法
sudo systemctl reload ssh

修改端口/禁用密码前,保持一个已登录会话不要退出,另开窗口验证能登录后再关。这是避免把自己锁在门外的唯一办法。

15.3 隧道与转发

# 本地转发:访问本机 8080 → 远端 80
ssh -L 8080:localhost:80 user@host

# 远程转发:把远端 9000 映射到本机 3000
ssh -R 9000:localhost:3000 user@host

# 动态代理(SOCKS5)
ssh -D 1080 user@host

# 跳板机
ssh -J jump@bastion user@internal

15.4 批量执行

for h in web1 web2 web3; do
  echo "== $h =="
  ssh -o ConnectTimeout=5 "$h" 'systemctl is-active nginx'
done

# 多机并行(需 pdsh 或 parallel-ssh)
parallel-ssh -h hosts.txt -i 'uptime'

16. 高频故障速查表

16.1 CPU 使用率过高

top -b -n1 | head -15                       # 找 PID
ps -p <pid> -o pid,user,%cpu,etime,cmd      # 看是什么进程
top -H -p <pid>                             # 看线程
sudo perf top                               # 函数级热点(需 linux-tools)
pidstat -u 1 -p <pid>                       # 单进程持续采样

16.2 磁盘满了

df -h; df -i                                # 先分清是空间还是 inode
du -h --max-depth=1 / 2>/dev/null | sort -rh | head
sudo lsof +L1                               # 已删除但被进程占用的文件(最常见隐形占用)
# 解决:重启对应服务释放句柄,或 : > /proc/<pid>/fd/<n> 截断
journalctl --vacuum-size=200M
sudo apt clean
find /var/log -name "*.gz" -mtime +30 -delete

典型元凶:/var/log 未轮转、/var/lib/docker 镜像堆积、被删除的大文件仍被进程持有、inode 被海量小文件耗尽。

16.3 内存不足 / OOM

free -h
dmesg -T | grep -i "out of memory"
journalctl -k | grep -i "killed process"
ps -eo pid,user,rss,cmd --sort=-rss | head
cat /proc/<pid>/oom_score

16.4 端口被占用

sudo ss -tulnp | grep :<port>
sudo lsof -i :<port>
sudo fuser -v <port>/tcp

16.5 服务起不来

systemctl status <svc> -l          # 先看退出码与最后几行
journalctl -u <svc> -n 100 --no-pager
systemctl cat <svc>                # 确认 unit 内容与依赖
systemctl show <svc> -p ExecStart  # 实际执行的命令
sudo -u <svcuser> <实际命令>        # 用服务账号手动跑,复现报错
ss -tulnp | grep <port>            # 端口是否被占
ls -l <工作目录> <日志目录>          # 权限是否正确

常见原因:配置文件语法错、工作目录不存在、端口占用、权限不足、依赖服务未就绪(缺 After=)。

16.6 SSH 连不上

现象 排查方向
Connection refused sshd 未启动 / 端口未监听 → systemctl status ssh、ss -tulnp | grep 22
Connection timed out 防火墙 / 安全组 / 网络不通 → 云控制台检查安全组,本机 ufw status
Permission denied (publickey) 公钥未写入 ~/.ssh/authorized_keys、权限应为 700/600、家目录不可组可写
登录后立刻断开 磁盘满 / shell 不存在 / /etc/nologin 存在 / PAM 限制
Too many authentication failures 本地密钥过多 → ssh -o IdentitiesOnly=yes -i <key>
ls -ld ~ ~/.ssh && ls -l ~/.ssh/authorized_keys
sudo tail -50 /var/log/auth.log
sudo sshd -t

16.7 网络通但域名解析失败

cat /etc/resolv.conf
resolvectl status
ping 223.5.5.5            # 通 → DNS 问题;不通 → 网络/路由问题
dig @223.5.5.5 example.com

16.8 系统启动失败

# 进入 rescue/emergency 后
mount -o remount,rw /            # 根分区常为只读
cat /etc/fstab                   # 检查是否有错误条目,加 nofail
systemctl --failed
journalctl -xb -p err

16.9 时间不同步导致证书/认证异常

timedatectl
sudo systemctl restart systemd-timesyncd
chronyc sources -v               # 若用 chrony

17. 危险命令与避坑清单

17.1 高危命令(执行前三思)

命令 风险
rm -rf / 或 rm -rf /* 系统毁灭,无恢复可能
rm -rf $VAR/(VAR 为空) 变量未定义时等价 rm -rf /;脚本中用 ${VAR:?} 保护
chmod -R 777 / 全系统权限崩坏,SSH 会拒绝密钥登录
chown -R user:user / 同上,系统服务大面积故障
dd if=/dev/zero of=/dev/sda 直接覆写磁盘
mkfs.* /dev/sda 分区未确认时格式化数据盘
> /etc/passwd 清空用户库
iptables -F (远程) 清空规则可能连自己一起断
:(){ :|:& };: fork 炸弹
rsync --delete 方向写反 用空目录覆盖源数据

17.2 自我保护习惯

  1. 危险操作前先备份:cp -a /etc/nginx /etc/nginx.bak.$(date +%F)
  2. 删除前先预览:find ... -print 确认列表,再去掉 -print 换成 -delete
  3. rsync 一律先 --dry-run
  4. 改 fstab / netplan / sshd / sudoers 前备份,改完先验证语法(mount -a、netplan try、sshd -t、visudo -c)
  5. 脚本第一行加 set -euo pipefail
  6. 不用 root 直接日常操作,用 sudo 并保留审计
  7. 远程改网络/防火墙时,保持第二个会话,并准备云控制台 VNC 兜底

17.3 变量保护写法

# 错误:VAR 为空时变成 rm -rf /
rm -rf "$VAR"/

# 正确:VAR 为空则报错退出
: "${VAR:?VAR is not set}"
rm -rf "${VAR:?}"/

附录 A:常用运维命令速查

场景 命令
系统版本 hostnamectl / cat /etc/os-release
CPU/内存概况 lscpu / free -h
磁盘使用 df -h du -sh * ncdu /
inode 检查 df -i
找大文件 du -ah / | sort -rh | head -20
端口占用 ss -tulnp | grep :80
进程详情 ps -eo pid,user,%cpu,%mem,cmd --sort=-%cpu | head
服务状态 systemctl status x / journalctl -u x -f
失败服务 systemctl --failed
防火墙 ufw status numbered
网络诊断 ip a / ip r / mtr host / tcpdump
抓包 tcpdump -i any -nn port 80
定时任务 crontab -l / systemctl list-timers
增量备份 rsync -avzP --dry-run src/ dst/
压缩 tar -czf x.tar.gz dir/
实时日志 tail -F /var/log/syslog
开机耗时 systemd-analyze blame
登录审计 last / lastb / grep Failed /var/log/auth.log

附录 B:初次接手服务器检查清单

# 1. 基本信息摸底
hostnamectl; uptime; free -h; df -h; df -i

# 2. 谁在用、跑什么
who; w; systemctl list-units --type=service --state=running

# 3. 暴露面
sudo ss -tulnp
sudo ufw status verbose

# 4. 健康度
systemctl --failed
journalctl -p err -b --no-pager | tail -30
sudo dmesg -T | grep -iE "error|fail" | tail -20

# 5. 定时任务与自启
crontab -l; sudo ls /etc/cron.d/; systemctl list-timers --all

# 6. 安全基线
sudo grep -E "^(PermitRootLogin|PasswordAuthentication|Port)" /etc/ssh/sshd_config
sudo apt list --upgradable

# 7. 备份是否真的在跑
ls -lht /backup | head; sudo ls -lht /var/backups | head

文档维护建议:把本手册中与你们环境强相关的部分(网卡名、端口规范、备份路径、服务命名)替换成实际值,沉淀为团队内部 SOP;通用命令部分保持与本手册同步即可。