Skip to content

06|日常运维操作规范

运维事故里,很少有"命令敲错了"——多数是"命令没错,但删错了对象、范围太大、没有退路"。同样一个 rm,删 /tmp/old.log 没事,删 /data/mysql 就是灾难。差别不在命令,在执行的范围、对象和有没有回滚。

本篇讲操作时怎么防这些事:危险命令怎么确认、批量操作怎么防误删、变更怎么留退路、操作怎么留痕。这些不是流程的形式主义,是减少事故的实际手段。

一、操作分级

按影响面和可逆程度分级,不同级别对应不同流程:

类型例子处理方式
只读tailsystemctl status、配置查阅按需执行
低风险改日志级别、调监控阈值、加非关键 cron记录变更和回滚方式
中风险重启单个实例、发布非核心服务低峰窗口、确认影响、备好回滚
高风险数据库 DDL、批量删除、防火墙策略、核心服务重启工单+审批+双人复核+回滚演练
应急服务中断恢复优先,尽量留痕,事后补复盘

一个操作带"批量"和"删除"两个属性,风险等级自动提升一档。

二、操作前确认

连上机器后第一件事不是动手,是确认对象:

bash
hostname      # 正确机器?
hostname -I   # IP 也对?
whoami        # 账号对?
pwd            # 目录对?

四条命令,两秒钟,能挡住连错机器、用错账号、进错目录这类低级但常见的问题。

变更前的检查清单

检查项确认什么
机器身份主机名、IP、环境、集群角色
当前状态服务正常?有未处理告警?正在被其他变更占用?
操作账号是不是该用的用户?会不会不小心用了 root?
影响范围单机?某个可用区?全集群?
上下游依赖谁在调用?依赖哪个数据库/队列/缓存?
回滚方式配置备份在哪?版本回退命令?数据恢复方法和时长?
观察指标改完后看哪个监控、哪段日志?

看当前基线

bash
systemctl status nginx --no-pager          # 服务状态
journalctl -u nginx -n 50 --no-pager       # 最近日志
ss -lntp                                   # 监听端口

--no-pager 防止输出卡在 less 里。

三、操作窗口

选窗口要看的不只是业务低峰:

  • 有人能响应——出了事不是孤军奋战
  • 上下游有人——网络、DB、应用能在同一时间响应
  • 监控正常——改完能观察到指标变化
  • 避开并发变更——出了问题分不清原因

数据库结构变更、网络策略收敛、批量重启不适合卡在下班前做。 白天"人都在、业务相对低峰"的窗口比半夜更安全——半夜人困反应慢、能帮忙的人少。

四、回滚方案

"支持回滚"不等于能回滚——要能写出回滚命令。

配置类变更

bash
# 变:前备份
cp -a /etc/nginx/nginx.conf /etc/nginx/nginx.conf.$(date +%F-%H%M%S).bak

# 改:完后检查
nginx -t && systemctl reload nginx

# 回滚
cp /etc/nginx/nginx.conf.2026-05-21-230000.bak /etc/nginx/nginx.conf
nginx -t                               # 旧配置不一定是错的,环境可能已变
systemctl reload nginx

旧配置备份不一定还对——环境可能已经变了。回滚也要走"检查→加载"流程。

版本类回滚(软链接)

text
/opt/myapp/releases/
├── 20260521-2100/
├── 20260521-2230/
└── current -> /opt/myapp/releases/20260521-2230
bash
ln -sfn /opt/myapp/releases/20260521-2100 /opt/myapp/current
systemctl restart myapp

-n 不可少——否则会在原目录内部创建链接,不是替换 current。

数据库变更

DDL、数据修复、批量删除——"从备份恢复"四个字不够。需要评估:恢复要多久?会不会覆盖新数据?业务能不能等?

五、双人确认

另一个人看着屏幕,与真正的双人确认是两回事。 双人确认是让另一个人独立审视关键事实。

哪些操作需要双人确认

操作复核要点
批量删除目录、匹配条件、备份存在
数据库变更库名、表名、WHERE、字段、备份
防火墙调整源地址、目标端口、回滚入口、会不会锁自己
生产重启剩余实例数、流量已摘除、健康检查正常
权限开通用户、资产范围、账号级别、有效期

确认时说明意图

准备删除 /data/app/tmp 下 7 天前的临时文件。
不涉及 /data/app/upload。
已确认备份不依赖 tmp 目录的内容。
先 find -print 看范围,确认后再执行删除。

完整意图描述比裸贴命令更容易让对方发现问题。

六、危险命令防护

rm

bash
# 先看范围
find /data/app/tmp -type f -mtime +7 -print

# 确认后删除
find /data/app/tmp -type f -mtime +7 -delete

变量拼接路径的 rm 必须检查:

bash
target_dir="${1:-}"

if [ -z "$target_dir" ] || [ "$target_dir" = "/" ]; then
    echo "invalid target dir: $target_dir" >&2
    exit 1
fi

rm -rf -- "$target_dir"/*

-- 防止文件名以 - 开头被当成选项。

rsync --delete

预演不是可选步骤:

bash
rsync -avh --delete --dry-run /srv/app/dist/ web@host:/var/www/app/

路径写错时,rsync 会很认真地把目标端删干净。

chmod / chown

bash
# 先看现状
find /opt/myapp -maxdepth 2 -printf '%m %u:%g %p\n' | head

# 再执行
chown -R app:app /opt/myapp
chmod -R u=rwX,go=rX /opt/myapp

X(大写)只给目录和已有执行位的文件加执行权限,不会给纯数据文件加执行位。chmod -R 755 不同。

在系统目录做递归权限修改的破坏性极大——应定位到具体文件,而不是全局放开。

kill

bash
systemctl stop service    # 标准
kill -TERM <pid>          # 请求进程正常退出:关闭连接、清理文件、写日志
kill -KILL <pid>          # 强制终止:不给清理机会

数据库进程被 kill -9 后,可能需要 crash recovery,比正常关闭慢得多。

七、批量操作

全量批量命令把风险放大了 N 倍。安全的做法:单台验证→分批推进:

bash
# 第 1 步:单台验证
head -1 hosts.txt | while read -r host; do
    ssh "$host" 'hostname; systemctl restart myapp; systemctl is-active myapp'
done

# 第 2 步:串行分批
while read -r host; do
    echo "=== $host ==="
    ssh "$host" 'systemctl restart myapp && systemctl is-active --quiet myapp'
    sleep 10        # 给监控和均衡器时间
done < hosts.txt

# 第 3 步:控制并发(xargs -P)
cat hosts.txt | xargs -I{} -P 5 sh -c '
    ssh "$1" "systemctl restart myapp && systemctl is-active --quiet myapp"
' sh {}

串行分批虽慢,但每一步可控。生产批量操作不追求速度,追求影响范围最小。

-P 的并发数要按容量决定:8 个实例,每个 CPU 已 60%,一次重启 5 个会让剩下 3 个扛全部流量,错误率会上升。

八、操作记录与留痕

最低要求记录

项目内容
操作人堡垒机用户
时间开始和结束
目标主机、服务、数据库、集群
关键命令执行了什么,用的哪个版本
结果成功/失败,回滚是否成功
证据日志片段、监控截图

终端记录

bash
# 用 script 记录会话
script -a /var/log/ops/$(date +%F-%H%M%S)-change.log

# 退出:exit
bash
# 脚本输出到日志
./deploy.sh 2>&1 | tee deploy-$(date +%F-%H%M%S).log

九、变更后观察

检查项怎么确认
服务正常systemctl status service --no-pager
无新错误journalctl -u service -n 100 --no-pager
端口监听ss -lntp
健康检查curl -fsS http://127.0.0.1:8080/healthz
业务指标QPS、错误率、延迟对比变更前
系统指标CPU、内存、磁盘、网络异常波动

多实例变更:只看单机健康不够。 实例本机 /healthz 已 200,但负载均衡没流量——可能没重新加入。所有实例健康,整体 5xx 上涨——服务发现、入口转发、下游依赖。

十、应急操作

故障中节奏快、压力大,但几条底线要守住:

原则做法
恢复优先降级、摘流量、扩容、回滚——先恢复,再研究根因
少做不可逆操作删数据、清日志、重建集群——可能让故障变事故
保留现场关键日志、错误信息、时间点——事后复盘必需
单点指挥避免多人同时改同一系统
事后补齐应急时来不及写,恢复后立即补上

保留现场

bash
mkdir -p /tmp/incident-$(date +%F-%H%M%S)
cd /tmp/incident-*

hostname > host.txt
date > date.txt
ip addr > ip-addr.txt
ip route > ip-route.txt
ss -antp > ss-antp.txt
journalctl -n 500 --no-pager > journal-last-500.txt

十一、操作记录模板

text
变更名称:
操作人:
操作时间:
目标环境:
目标主机:

变更内容:
影响范围:
回滚方案:

操作前状态:
执行命令:
操作后验证:
异常与处理:

模板的作用不是把流程变复杂,而是让自己第二天打开还能看懂: 当时为什么做、做了什么、结果怎样、出问题怎么退。