Ubuntu 常用运维指令手册
Ubuntu 常用运维指令手册
适用版本:Ubuntu 20.04 / 22.04 / 24.04 LTS(Server 与 Desktop 通用) 约定:
$开头为普通用户执行,#开头为 root 或sudo执行,<xxx>为需替换的占位符。 排序原则:按运维实际场景组织,每节内按「查看 → 变更 → 排查」递进。
目录
- 系统信息与状态
- 用户与权限管理
- 文件与目录操作
- 文本处理与内容查找
- 磁盘与文件系统
- 软件包管理
- 服务与 systemd
- 进程与资源管理
- 网络配置与诊断
- 防火墙与安全加固
- 日志与排障
- 定时任务
- 压缩、备份与传输
- 性能监控与调优
- SSH 与远程运维
- 高频故障速查表
- 危险命令与避坑清单
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 三大坑
- 环境变量不同:cron 的 PATH 极简,命令写绝对路径,或在脚本头部显式
export PATH。 - 不加载 profile:脚本里
source /etc/profile或直接写死变量。 - 输出被丢弃:一定要重定向
>> 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 自我保护习惯
- 危险操作前先备份:
cp -a /etc/nginx /etc/nginx.bak.$(date +%F) - 删除前先预览:
find ... -print确认列表,再去掉-print换成-delete rsync一律先--dry-run- 改 fstab / netplan / sshd / sudoers 前备份,改完先验证语法(
mount -a、netplan try、sshd -t、visudo -c) - 脚本第一行加
set -euo pipefail - 不用 root 直接日常操作,用 sudo 并保留审计
- 远程改网络/防火墙时,保持第二个会话,并准备云控制台 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;通用命令部分保持与本手册同步即可。