CentOS 7 - 10 常规运维指令手册
CentOS 7 - 10 常规运维指令手册
适用版本:CentOS 7 / CentOS 8(含 Stream 8)/ CentOS Stream 9 / CentOS Stream 10 约定:
$普通用户,#root 或sudo,<xxx>为占位符。 差异标注:正文中用> **版本差异**引用块标注跨版本不一致之处,无标注表示各版本通用。
目录
- 版本概览与差异总览
- 系统信息与状态
- 用户与权限管理
- 文件与目录操作
- 磁盘与文件系统
- 软件包管理:yum / dnf / dnf5
- 服务与 systemd
- 进程与资源管理
- 网络配置
- firewalld 防火墙
- SELinux
- 日志与排障
- 定时任务
- 压缩、备份与传输
- 性能监控与调优
- SSH 与远程运维
- 高频故障速查表
- 版本生命周期与迁移路径
- 危险命令与避坑清单
1. 版本概览与差异总览
1.1 版本对照
| 项目 | CentOS 7 | CentOS 8 | Stream 9 | Stream 10 |
|---|---|---|---|---|
| 发布/状态 | 2014,2024-06-30 EOL | 2019,2021-12-31 EOL | 2021-12 起,滚动更新 | 2024-12 起 |
| 对应 RHEL | 7 | 8 | 9 | 10 |
| 内核 | 3.10 | 4.18 | 5.14 | 6.12 |
| 包管理器 | yum(Python 2) | dnf(Python 3) | dnf | dnf5(C++) |
| 默认文件系统 | XFS | XFS | XFS | XFS |
| 默认 Python | 2.7 | 3.6(平台)+ 可选 3.11 | 3.9 | 3.12 |
| 防火墙后端 | iptables | nftables | nftables | nftables(iptables 兼容层弱化) |
| 网络配置 | network-scripts(ifcfg) | NetworkManager(ifcfg 插件,弃用) | NetworkManager(keyfile) | NetworkManager(keyfile) |
| 默认容器 | docker(第三方) | podman / buildah | podman | podman |
| systemd | 219 | 239 | 252 | 257 |
| 模块流 module | 不支持 | 支持 | 支持 | 支持(dnf5 语法) |
| dbus / 会话 | 传统 | 传统 | 默认 cgroup v2 | 默认 cgroup v2 |
1.2 运维必须知道的五个断点
- 包管理命令层:
yum在 8+ 是dnf的软链,命令基本通用;但 Stream 10 是 dnf5,部分子命令输出和参数不同(见 6.6)。 - 网络配置文件换了位置:7 的
/etc/sysconfig/network-scripts/ifcfg-*在 8 弃用、9 起完全移除。必须改用nmcli或 keyfile。 - firewalld 后端换了:规则写法不变,但底层的
iptables -L在 8+ 看不到完整规则,要用nft list ruleset。 netstat/ifconfig/lsof默认不装:7 起就已经精简,用ss/ip/lsof(需装 net-tools、lsof)。- SELinux 全程开启:CentOS 与 Ubuntu 最大的运维差异。禁用 SELinux 不是解决方案,是埋雷(见第 11 章)。
1.3 版本识别
cat /etc/centos-release # CentOS Linux release 7.9.2009 (Core) / CentOS Stream release 9
cat /etc/redhat-release # 同上(RHEL 系通用)
cat /etc/os-release # 最可靠,含 VERSION_ID="9"
rpm -E %{rhel} # 输出 7 / 8 / 9 / 10,写脚本判断版本的首选
uname -r # 内核:3.10 / 4.18 / 5.14 / 6.12
脚本中判断版本:
RHEL_VER=$(rpm -E %{rhel})
if [ "$RHEL_VER" -ge 8 ]; then echo "dnf 时代"; else echo "yum 时代"; fi
2. 系统信息与状态
2.1 版本与主机
hostnamectl # 主机名、OS、内核、虚拟化
hostnamectl set-hostname web01 # 永久改主机名(立即生效)
hostname # 当前主机名
uname -a
uname -r
getconf LONG_BIT # 64
2.2 硬件资源
lscpu # CPU 型号、核心、NUMA
free -h # 内存(-m 兆、-g 吉)
lsblk -f # 块设备 + 文件系统 + UUID
lspci | grep -i -E 'eth|vga' # 网卡 / 显卡
lsusb
dmidecode -t system | grep -E 'Manufacturer|Product' # 需 root
nproc # 逻辑核数
2.3 负载与运行状态
uptime # 负载:1/5/15 分钟
who -b # 上次启动时间
last reboot | head -5
w # 在线用户 + 正在执行的命令
vmstat 1 5 # 见 15.2
负载判读:CentOS 7 的负载包含不可中断进程(IO 等待),负载高但 CPU 空闲通常意味着磁盘卡住,查
vmstat的b列和iostat的%util。
2.4 时间同步(chrony)
timedatectl # 时区、NTP 同步状态
chronyc tracking # 当前同步精度、偏差
chronyc sources -v # 时间源列表与状态
chronyc sourcestats -v
sudo chronyc makestep # 立即强制校时(跳变,慎用于数据库主机)
sudo timedatectl set-timezone Asia/Shanghai
sudo systemctl enable --now chronyd
/etc/chrony.conf 关键项:
pool ntp.aliyun.com iburst
makestep 1.0 3
rtcsync
版本差异:CentOS 7 时代同时支持
ntpd与chronyd,默认chronyd;8+ 只保留 chrony,不要再试图装 ntpd。
3. 用户与权限管理
3.1 用户操作
id <user>
getent passwd <user>
who; w; last -n 20
# 创建
sudo useradd -m -s /bin/bash <user>
sudo useradd -r -s /sbin/nologin -M <svcuser> # 服务账号:无家目录、不可登录
sudo passwd <user>
echo '<user>:<password>' | sudo chpasswd # 批量设置(脚本用,注意安全)
# 修改
sudo usermod -aG wheel <user> # 加入 wheel 组获得 sudo 权限(CentOS 默认组)
sudo usermod -aG docker <user> # ⚠️ 必须带 -a
sudo usermod -L <user> # 锁定
sudo usermod -U <user>
sudo usermod -s /sbin/nologin <user>
sudo usermod -d /new/home -m <user>
# 删除
sudo userdel -r <user>
CentOS 与 Ubuntu 的组差异:CentOS 提权组是
wheel,Ubuntu 是sudo。把用户加进sudo组在 CentOS 上无效。
3.2 密码策略
sudo chage -l <user>
sudo chage -M 90 -W 7 <user> # 90 天有效期,提前 7 天警告
sudo chage -d 0 <user> # 强制下次登录改密
sudo passwd -e <user> # 同上
全局默认在 /etc/login.defs;复杂度策略用 authconfig(7)或 authselect(8+):
# 7
sudo authconfig --passminlen=10 --passminclass=3 --update
# 8+
sudo authselect select sssd with-pwquality --force
版本差异:
authconfig在 8 起被authselect取代。在 9/10 上装 authconfig 只是为了兼容,不应继续使用。
3.3 提权(sudo)
sudo visudo # 安全编辑 /etc/sudoers
sudo visudo -f /etc/sudoers.d/ops # 推荐:分文件
sudo -l # 查看当前权限
sudo -u <user> <cmd>
sudo -i # 切 root 环境
/etc/sudoers.d/ops:
ops ALL=(root) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/firewall-cmd --reload
%wheel ALL=(ALL) ALL
版本差异:Stream 10 引入
sudo-rs(Rust 重实现)作为 sudo 的替代路径,命令行用法保持一致,但极少数边缘语法行为可能不同;自研脚本依赖sudo -E、sudoedit等特性时建议在 Stream 10 上实测。
3.4 权限与特殊位
chmod 755 /opt/app
chmod 644 /etc/myapp/conf.ini
chown -R app:app /opt/app
umask # 默认 0022
# SUID / SGID / Sticky
chmod u+s <file> # SUID:以文件所有者身份运行
chmod g+s <dir> # SGID:目录下新文件继承目录属组
chmod +t /shared # Sticky:只能删自己的文件
# ACL
sudo dnf install acl -y
setfacl -m u:alice:rw /data/report.csv
getfacl /data/report.csv
setfacl -b /data/report.csv
# 不可变属性(防误删/防篡改)
sudo chattr +i /etc/passwd
lsattr /etc/passwd
# 检查异常 SUID(安全巡检)
sudo find / -perm -4000 -type f 2>/dev/null
4. 文件与目录操作
4.1 浏览与查找
ls -alh; ls -lhS; ls -lht
tree -L 2 -d
stat <file>
realpath <path>
findmnt
find /var/log -name "*.log" -size +100M
find / -type f -mtime -7 -name "*.conf"
find /tmp -type f -mmin +60 -delete
find /data -type d -empty
find . -type f -exec ls -lh {} \;
find . -name "*.log" -print0 | xargs -0 gzip
grep -rn "listen 8080" /etc/nginx/
locate在 CentOS 上需装mlocate,并sudo updatedb建库。生产环境常禁用(IO 抖动),优先用find或grep -r。
4.2 复制、移动、删除
cp -a /src/. /dst/ # 复制内容(含隐藏文件),保留属性
cp -a /src /dst/ # 会在 dst 下建 src 目录(易错)
mv <src> <dst>
rm -i <file>
ln -s /opt/app/releases/v1.2 /opt/app/current
mkdir -p /data/app/{logs,conf,tmp}
4.3 文本处理
less +F /var/log/messages
tail -F /var/log/secure # 轮转后仍跟踪
tail -n 200 /var/log/messages
grep -vE '^\s*#|^\s*$' /etc/ssh/sshd_config # 去注释与空行
grep -A3 -B3 "error" app.log
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head
awk '$9==502' access.log | wc -l
sed -n '100,200p' <file>
sed -i.bak 's/old/new/g' <file> # 带备份的原地替换(生产推荐)
cut -d: -f1 /etc/passwd
sort -u <file> | wc -l
CentOS 与 Ubuntu 的 sed 差异:GNU sed 行为一致,无需像 macOS 那样加
''。但sed -i不带后缀会直接改原文件,生产上坚持-i.bak。
5. 磁盘与文件系统
5.1 容量与占用
df -h
df -i # inode 用尽:小文件多的场景很常见
du -sh /var/* | sort -rh | head
du -h --max-depth=1 / | sort -rh | head -20
ncdu /var # 交互式(需 EPEL)
sudo lsof +L1 # 已删除仍被占用的文件(磁盘"假满"元凶)
5.2 分区与挂载
lsblk
sudo fdisk -l
sudo parted -l
blkid
findmnt
# 新盘(MBR)
sudo fdisk /dev/sdb # n → p → 1 → 回车 → w
sudo mkfs.xfs -L data /dev/sdb1 # CentOS 默认 XFS
# 新盘(GPT,>2T)
sudo parted /dev/sdb --script mklabel gpt
sudo parted /dev/sdb --script mkpart primary xfs 0% 100%
sudo mkfs.xfs /dev/sdb1
sudo mkdir -p /data
sudo mount /dev/sdb1 /data
永久挂载 /etc/fstab:
UUID=xxxx-xxxx /data xfs defaults,nofail 0 0
sudo cp /etc/fstab /etc/fstab.bak.$(date +%F)
sudo mount -a # 必须验证,否则重启进 emergency
XFS 的 fstab dump/pass 列应为
0 0(fsck不用于 XFS,用xfs_repair)。
5.3 扩容
# 分区扩容(云盘在线扩容后)
sudo dnf install -y cloud-utils-growpart
sudo growpart /dev/sda 1
sudo xfs_growfs / # XFS 只能扩不能缩
# ext4 用:sudo resize2fs /dev/sda1
# LVM(CentOS 默认安装即为 LVM,重点掌握)
sudo pvs; sudo vgs; sudo lvs
sudo lvextend -l +100%FREE /dev/mapper/centos-root
sudo xfs_growfs /
5.4 LVM 完整操作
# 建:PV → VG → LV
sudo pvcreate /dev/sdc
sudo vgcreate vg_data /dev/sdc
sudo lvcreate -L 200G -n lv_app vg_data
sudo mkfs.xfs /dev/vg_data/lv_app
sudo mount /dev/vg_data/lv_app /opt/app
# 扩
sudo pvcreate /dev/sdd
sudo vgextend vg_data /dev/sdd
sudo lvextend -L +100G /dev/vg_data/lv_app
sudo xfs_growfs /opt/app
# 缩(XFS 不支持缩!只能备份-重建-恢复;ext4 用 lvreduce + resize2fs)
sudo lvreduce -L -50G /dev/vg_data/lv_ext4 # ⚠️ ext4 需先 umount 并 e2fsck
# 快照(备份用)
sudo lvcreate -L 10G -s -n snap_app /dev/vg_data/lv_app
sudo lvremove /dev/vg_data/snap_app
XFS 不能缩容是 CentOS 运维最常见的误判。规划 LV 时宁可留余量,需要缩的场景应改设计或重建。
5.5 swap
swapon --show
free -h
sudo dd if=/dev/zero of=/swapfile bs=1M count=4096
sudo chmod 600 /swapfile
sudo mkswap /swapfile && sudo swapon /swapfile
echo '/swapfile swap swap defaults 0 0' | sudo tee -a /etc/fstab
sudo swapoff /swapfile
版本差异:CentOS 7 的 LVM 布局通常有独立
swapLV;8+ 默认多为 zram 或 swapfile,lsblk看到的形态不同,不要照搬 7 的文档。
5.6 磁盘健康
sudo dnf install -y smartmontools
sudo smartctl -a /dev/sda
sudo smartctl -t short /dev/sda # 短自检,结果看 -l selftest
dmesg -T | grep -iE "i/o error|medium error"
6. 软件包管理:yum / dnf / dnf5
6.1 通用命令(7 用 yum,8+ 用 dnf,语法一致)
sudo yum makecache fast # 7
sudo dnf makecache # 8+ 刷新元数据
sudo yum install -y <pkg>
sudo dnf install -y <pkg>
sudo dnf install -y <pkg>-<version> # 指定版本
sudo dnf install -y ./local.rpm # 本地 rpm(取代 localinstall)
sudo dnf remove <pkg>
sudo dnf autoremove # 清理孤立依赖
sudo dnf clean all
dnf list installed | grep <pkg>
dnf list available <pkg>
dnf info <pkg>
dnf search <keyword>
dnf provides */<command> # 反查命令属于哪个包(最高频)
dnf repoquery -l <pkg> # 包内含哪些文件(未安装也能看)
sudo dnf update # 升级全部(7 用 yum update)
sudo dnf update <pkg>
sudo dnf check-update # 只检查不升级
sudo dnf distro-sync # 同步到仓库当前版本(修复版本错乱)
6.2 仓库管理
dnf repolist
dnf repolist --all
cat /etc/yum.repos.d/*.repo
# 启用/禁用仓库
sudo dnf config-manager --set-enabled <repo> # 8+
sudo dnf config-manager --set-disabled <repo>
sudo yum-config-manager --enable <repo> # 7(需 yum-utils)
sudo dnf --disablerepo='*' --enablerepo=epel install <pkg>
# EPEL
sudo dnf install -y epel-release
本地源(离线环境):
# /etc/yum.repos.d/local.repo
[local]
name=Local Repo
baseurl=file:///mnt/cdrom
enabled=1
gpgcheck=0
sudo mount -o loop /dev/sr0 /mnt/cdrom
sudo dnf clean all && sudo dnf makecache
版本差异:7 的仓库地址在 2024-06-30 后失效,需切到
vault.centos.org(见 18.2)。仓库 ID 也从base/updates变为baseos/appstream(8+)。
6.3 模块流 module(8+ 专属)
dnf module list # 全部模块流
dnf module list nginx # 某软件的可用流
dnf module info nginx:1.22
sudo dnf module enable nginx:1.22
sudo dnf module install nginx:1.22/common
sudo dnf module reset nginx # 重置回默认
sudo dnf module switch-to nginx:1.24
模块流是 8+ 解决"同一软件多版本并存"的机制。7 完全没有,迁移脚本里遇到
dnf module要考虑兼容分支。Stream 10 的 dnf5 中模块概念进一步弱化,部分软件改用独立的 repo 提供版本。
6.4 rpm 底层操作
rpm -qa | grep <pkg> # 已装列表
rpm -qi <pkg> # 详情
rpm -ql <pkg> # 装了哪些文件
rpm -qf /usr/bin/nginx # 文件属于哪个包
rpm -qc <pkg> # 配置文件列表
rpm -qd <pkg> # 文档列表
rpm -V <pkg> # 校验文件是否被改动(安全巡检常用)
rpm -Vf /etc/passwd
rpm -ivh <pkg>.rpm # 安装
rpm -Uvh <pkg>.rpm # 升级
rpm -e <pkg> # 卸载
rpm -e --nodeps <pkg> # ⚠️ 忽略依赖强删,极易破坏系统
rpm -qp --scripts <pkg>.rpm # 看安装脚本(安装前审计)
6.5 依赖与事务修复
sudo dnf check # 检查依赖问题
sudo dnf --fix-broken install # 8+ 修复
sudo yum-complete-transaction --cleanup-only # 7 修复中断的事务
sudo rpm --rebuilddb # 重建 rpm 数据库(最后手段)
sudo dnf history # 事务历史
sudo dnf history undo <id> # 回滚某次操作(7 同样支持 yum history undo)
6.6 dnf5 变化(Stream 10)
dnf5 --version
dnf5 install <pkg>
dnf5 repo list
dnf5 history list
主要变化:
dnf5为独立二进制,dnf指向它;不再依赖 Python- 输出格式改为更结构化的表格/机器可读格式
- 部分旧参数被移除或改名(如
--skip-broken语义变化、module子命令精简) --allowerasing等冲突解决行为更严格,脚本跨版本时务必先--assumeno试跑
迁移脚本中判断:
dnf5 --version &>/dev/null && PM=dnf5 || PM=dnf。
6.7 源码与二进制安装
sudo dnf group install -y "Development Tools"
sudo dnf install -y gcc gcc-c++ make cmake kernel-devel kernel-headers
./configure --prefix=/usr/local/<app>
make -j$(nproc) && sudo make install
# 第三方二进制放 /usr/local/bin 并确认在 PATH 中
echo $PATH | tr ':' '\n' | grep /usr/local/bin
7. 服务与 systemd
7.1 基础操作
systemctl status <svc>
sudo systemctl start|stop|restart <svc>
sudo systemctl reload <svc> # 重载配置,优先于 restart
sudo systemctl enable --now <svc>
sudo systemctl disable <svc>
sudo systemctl is-active <svc>; systemctl is-enabled <svc>
sudo systemctl mask <svc> # 禁止任何方式启动
sudo systemctl unmask <svc>
systemctl cat <svc> # 查看 unit 全文与 override
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 后必执行
sudo systemctl reset-failed <svc> # 清失败计数(触发过 StartLimit 时)
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="JAVA_HOME=/usr/lib/jvm/java-17-openjdk"
EnvironmentFile=-/etc/sysconfig/myapp
ExecStart=/opt/myapp/bin/server
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
# SELinux 严格模式下需显式声明可写目录
ReadWritePaths=/var/log/myapp /var/lib/myapp
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload && sudo systemctl enable --now myapp
CentOS 的环境变量文件习惯放
/etc/sysconfig/(Debian 系是/etc/default/),沿用可减少团队认知成本。
7.4 覆盖而不改包自带 unit
sudo systemctl edit nginx # 生成 /etc/systemd/system/nginx.service.d/override.conf
sudo systemctl edit --full nginx # 整份复制(包升级后可能冲突)
7.5 SysV 兼容(仅 7 有)
# CentOS 7 仍保留 service / chkconfig 兼容层
sudo service network restart
sudo chkconfig --list
sudo chkconfig httpd on
# 8+ 已移除,只能用 systemctl
版本差异:网上大量 7 时代的教程用
service xxx restart、chkconfig,在 8+ 上直接报 command not found。本文档统一用 systemctl。
8. 进程与资源管理
8.1 查看
ps aux
ps -ef --forest
ps -eo pid,ppid,user,%cpu,%mem,etime,cmd --sort=-%cpu | head -15
pgrep -a nginx
pidof nginx
pstree -p
net-tools默认未装,netstat不可用;用ss替代。需要时sudo dnf install -y net-tools,但生产建议直接用ss。
8.2 终止与信号
kill <pid> # SIGTERM,优雅退出
kill -9 <pid> # SIGKILL,强杀
kill -HUP <pid> # 重载配置
pkill -f "python app.py"
pkill -u <user>
killall nginx
kill -l # 信号列表
8.3 前后台与持久会话
<cmd> &
jobs -l
fg %1; bg %1
nohup <cmd> > /var/log/x.log 2>&1 &
disown -h %1
# 长期任务用 tmux(7 需 EPEL 或 base 源)
sudo dnf install -y tmux
tmux new -s ops
tmux attach -t ops
# Ctrl+b d 分离
8.4 端口与句柄
sudo ss -tulnp # 监听端口与进程
sudo ss -tanp state established # 已建立连接
sudo lsof -i :8080 # 需装 lsof
sudo fuser -v 8080/tcp
8.5 资源限制
ulimit -n
ulimit -a
cat /proc/<pid>/limits
# 全局永久:/etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
sysctl fs.file-max
sysctl net.core.somaxconn
sudo sysctl -p # 应用 /etc/sysctl.conf
注意:
limits.conf对 systemd 服务无效,必须在 unit 里写LimitNOFILE=65535。这是 CentOS 7/8 上"明明改了 limits 但进程还是 1024"的根因。
9. 网络配置
这一章是 CentOS 跨版本变化最大的部分,务必按版本选择。
9.1 查看(全版本通用)
ip a
ip -4 a show dev eth0
ip r
ip route get 8.8.8.8
ip link set eth0 up
ip neigh
cat /etc/resolv.conf # 常被 NetworkManager 接管
9.2 CentOS 7:network-scripts(ifcfg)
/etc/sysconfig/network-scripts/ifcfg-eth0:
TYPE=Ethernet
BOOTPROTO=none
DEFROUTE=yes
NAME=eth0
DEVICE=eth0
IPADDR=192.168.1.10
PREFIX=24
GATEWAY=192.168.1.1
DNS1=223.5.5.5
DNS2=8.8.8.8
sudo systemctl restart network # 应用(或 ifdown/ifup eth0)
sudo ifdown eth0 && sudo ifup eth0 # 单网卡操作
ping -c3 192.168.1.1
7 上若同时启用 NetworkManager 与 network 服务,两者会互抢配置,只能保留一个:
systemctl disable --now NetworkManager。
9.3 CentOS 8:ifcfg 弃用,NetworkManager 主导
# 8 仍能读 ifcfg(兼容插件),但官方推荐 nmcli
nmcli device status
nmcli connection show
sudo nmcli connection reload
9.4 CentOS 9 / 10:keyfile(network-scripts 已移除)
nmcli device status
nmcli connection show
# 新建静态 IP 连接
sudo nmcli connection add type ethernet con-name eth0 ifname eth0 \
ipv4.method manual \
ipv4.addresses 192.168.1.10/24 \
ipv4.gateway 192.168.1.1 \
ipv4.dns "223.5.5.5 8.8.8.8"
# 修改已有连接
sudo nmcli connection modify eth0 ipv4.addresses 192.168.1.11/24
sudo nmcli connection modify eth0 ipv4.method manual
sudo nmcli connection modify eth0 ipv4.gateway 192.168.1.1
sudo nmcli connection modify eth0 ipv4.dns "223.5.5.5"
sudo nmcli connection modify eth0 connection.autoconnect yes
sudo nmcli connection up eth0
sudo nmcli connection down eth0
# 删除与回退 DHCP
sudo nmcli connection delete eth0
sudo nmcli connection modify eth0 ipv4.method auto
配置文件位置:/etc/NetworkManager/system-connections/eth0.nmconnection,权限必须 600。
等价的 keyfile 手写形式:
[connection]
id=eth0
type=ethernet
interface-name=eth0
autoconnect=true
[ipv4]
method=manual
address1=192.168.1.10/24,192.168.1.1
dns=223.5.5.5;8.8.8.8;
sudo chmod 600 /etc/NetworkManager/system-connections/eth0.nmconnection
sudo nmcli connection reload && sudo nmcli connection up eth0
交互式工具(全版本):nmtui。
远程操作警告:改 IP 前先在控制台/带外管理准备好回滚手段。
nmcli connection up会立即断连,SSH 会话随之中断。
9.5 连通性诊断(由近到远)
ping -c4 8.8.8.8 # 三层
ping -c4 www.aliyun.com # 三层 + DNS
tracepath <host> # 无需 root
mtr -rwc 20 <host> # 持续探测 + 丢包(排抖动首选,需 EPEL)
curl -I https://<host> # 应用层
curl -o /dev/null -s -w "%{http_code} %{time_total}\n" https://<host>
nc -zv <host> 3306 # 端口探测(需 nmap-ncat)
telnet <host> 80 # 需 telnet 包,很多环境没有
9.6 DNS
cat /etc/resolv.conf
dig <domain> +short
dig @8.8.8.8 <domain> A
nslookup <domain>
getent hosts <domain> # 走完整 NSS 解析链(排查 /etc/hosts 干扰)
# 持久化 DNS(9/10,NetworkManager)
sudo nmcli connection modify eth0 ipv4.dns "223.5.5.5 8.8.8.8"
sudo nmcli connection modify eth0 ipv4.ignore-auto-dns yes
sudo nmcli connection up eth0
9.7 抓包与网卡
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'
ethtool eth0
ethtool -S eth0 | grep -i err
ip -s link
9.8 网卡命名与绑定
# CentOS 7 的网卡命名规则(一致性网络设备命名)
ls /etc/sysconfig/network-scripts/ifcfg-*
grep -E 'net.ifnames|biosdevname' /etc/default/grub
# 回退为 eth0(7 常见需求)
# grub 加 net.ifnames=0 biosdevname=0,然后 grub2-mkconfig -o /boot/grub2/grub.cfg
# bond(9/10 用 nmcli)
sudo nmcli connection add type bond con-name bond0 ifname bond0 bond.options "mode=active-backup,miimon=100"
sudo nmcli connection add type ethernet slave-type bond con-name bond0-eth1 ifname eth1 master bond0
10. firewalld 防火墙
10.1 基本状态
systemctl status firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --state # running / not running
sudo firewall-cmd --get-default-zone # 通常 public
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all # 当前 zone 全部规则
sudo firewall-cmd --list-all-zones
sudo firewall-cmd --get-services # 预定义服务列表
10.2 放行与回收(核心用法)
# 服务名方式(推荐,自带端口定义)
sudo firewall-cmd --add-service=http
sudo firewall-cmd --add-service=https
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --reload # 永久规则需 reload 才生效
# 端口方式
sudo firewall-cmd --permanent --add-port=8080/tcp
sudo firewall-cmd --permanent --add-port=3306/tcp
sudo firewall-cmd --permanent --remove-port=8080/tcp
sudo firewall-cmd --reload
# 查询某个规则
sudo firewall-cmd --query-service=http
sudo firewall-cmd --query-port=8080/tcp
# 把运行时规则整体转永久(易忘记 --permanent 的救星)
sudo firewall-cmd --runtime-to-permanent
# 端口区间
sudo firewall-cmd --permanent --add-port=8000-8100/tcp
规则生效模型:加
--permanent只写配置文件,加--reload才载入内存;不加--permanent只临时生效,重启即丢。习惯是先临时测试 → 确认通 →--runtime-to-permanent。
10.3 源地址、区域与富规则
# 只允许某网段访问数据库
sudo firewall-cmd --permanent --zone=public \
--add-rich-rule='rule family="ipv4" source address="10.0.0.0/8" port port="3306" protocol="tcp" accept'
sudo firewall-cmd --reload
# 封禁某 IP
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="1.2.3.4" reject'
sudo firewall-cmd --permanent --remove-rich-rule='rule family="ipv4" source address="1.2.3.4" reject'
# 把某网卡划入不同区域
sudo firewall-cmd --permanent --zone=internal --change-interface=eth1
sudo firewall-cmd --permanent --zone=trusted --add-source=10.0.0.0/8
# 端口转发(本机 80 → 8080)
sudo firewall-cmd --permanent --add-forward-port=port=80:proto=tcp:toport=8080
# NAT 出口(需开启伪装)
sudo firewall-cmd --permanent --add-masquerade
sudo firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toaddr=192.168.1.20:toport=80
10.4 紧急操作
sudo firewall-cmd --panic-on # 切断一切流量(含 SSH!)
sudo firewall-cmd --panic-off
sudo firewall-cmd --complete-reload
sudo systemctl restart firewalld
10.5 底层查看
# CentOS 7:iptables 后端
sudo iptables -L -n -v --line-numbers
# CentOS 8+:nftables 后端,iptables -L 只能看到兼容层
sudo nft list ruleset
sudo nft list table inet firewalld
版本差异:8 起 firewalld 后端为 nftables。网上"用 iptables 命令直接加规则"的 7 时代做法在 8+ 上会被 firewalld 覆盖或失效,一律走
firewall-cmd。
10.6 三个经典坑
- 改 SSH 端口后连不上:firewalld 要放行新端口 且 SELinux 要加端口标签(见 11.6),两处缺一个都失败。
- docker 绕过 firewalld:docker 直接操作 netfilter,发布的端口不受 firewalld 管;要么改
iptables=false配合自管规则,要么用--iptables+ 自定义 DOCKER-USER 链。 --reload会短暂中断:生产上大改前先--list-all存档,避免改错后无从恢复。
sudo firewall-cmd --list-all > /root/firewall-backup-$(date +%F).txt
11. SELinux
CentOS 默认 enforcing。这不是可选组件,是强制访问控制层,绝大多数"权限没问题但就是访问不了"都是它。
11.1 状态查看与切换
getenforce # Enforcing / Permissive / Disabled
sestatus # 详细:策略版本、模式、加载的策略名
sestatus -b # 所有布尔值
# 临时切换(重启失效)
sudo setenforce 0 # → Permissive(只记录不拦截,排障用)
sudo setenforce 1 # → Enforcing
# 永久配置:/etc/selinux/config
# SELINUX=enforcing | permissive | disabled
Disable 需要重启且代价高:从 disabled 切回 enforcing 会触发全盘重新打标签(
/.autorelabel+ 重启)。生产环境排障一律用setenforce 0临时验证,不要改成 disabled。
11.2 上下文(context)
ls -Z /var/www/html # 文件上下文
ls -Zd /var/www/html # 目录本身
ps -eZ | grep httpd # 进程上下文
id -Z # 当前用户上下文
ss -Z -tulnp # 端口上下文
格式:system_u:object_r:httpd_sys_content_t:s0
11.3 修复上下文(最常用)
# 恢复为策略定义的默认值(改过文件位置后必做)
sudo restorecon -Rv /var/www/html
sudo restorecon -Rv /opt/app
# 临时修改(重启/relabel 后丢失,不推荐长期用)
sudo chcon -t httpd_sys_content_t /var/www/html/index.html
sudo chcon -R -t httpd_sys_content_t /data/web
# 永久修改(写入策略,推荐)
sudo semanage fcontext -a -t httpd_sys_content_t "/data/web(/.*)?"
sudo restorecon -Rv /data/web
# 查看策略中的路径规则
sudo semanage fcontext -l | grep httpd_sys_content
# 删除自定义规则
sudo semanage fcontext -d "/data/web(/.*)?"
semanage属于哪个包:7 是policycoreutils-python,8+ 是policycoreutils-python-utils。装错版本会 command not found。
11.4 端口标签(非标准端口必做)
sudo semanage port -l | grep http_port_t
sudo semanage port -a -t http_port_t -p tcp 8080
sudo semanage port -m -t http_port_t -p tcp 8080
sudo semanage port -d -t http_port_t -p tcp 8080
经典场景:nginx 监听 8080,firewalld 放行了、配置也对,但
curl一直 403/连接被拒 —— 缺 SELinux 端口标签。这是 CentOS 独有的高频故障。
11.5 布尔开关
sudo semanage boolean -l | grep httpd
getsebool -a | grep httpd
sudo setsebool httpd_can_network_connect on # 临时
sudo setsebool -P httpd_can_network_connect on # 永久(-P 必须加)
常用布尔值:
| 布尔值 | 用途 |
|---|---|
httpd_can_network_connect |
允许 httpd/nginx 主动外连(反代后端必备) |
httpd_can_network_connect_db |
允许连数据库 |
httpd_read_user_content |
读取用户家目录内容 |
httpd_use_nfs / httpd_use_cifs |
访问 NFS / SMB 挂载 |
ftpd_full_access |
FTP 完整访问 |
11.6 审计日志与策略生成
sudo ausearch -m avc -ts recent # 最近的 AVC 拒绝记录
sudo ausearch -m avc -ts today | aureport -f -i
sudo sealert -a /var/log/audit/audit.log # 需 setroubleshoot-server
# 由拒绝记录生成策略模块
sudo ausearch -m avc -ts recent | audit2allow -M myapp
sudo semodule -i myapp.pp
sudo semodule -l | grep myapp
sudo semodule -r myapp # 卸载
使用顺序:先
setenforce 0确认问题确由 SELinux 引起 → 看 avc 日志 → 优先用restorecon/semanage fcontext/setsebool解决 → 确实没有现成策略时,最后才用audit2allow生成自定义模块。直接关 SELinux 是错误答案。
11.7 全盘重打标签
sudo touch /.autorelabel
sudo reboot
# 或手动
sudo restorecon -Rv /
11.8 常见问题对照
| 现象 | 原因 | 处理 |
|---|---|---|
| nginx 启动失败,日志无明确错误 | 端口无标签 | semanage port -a -t http_port_t -p tcp <port> |
| 网页 403,文件权限已 755 | 上下文不是 httpd_sys_content_t |
restorecon -Rv 或 semanage fcontext |
| 反代 502,后端 curl 正常 | 布尔值未开 | setsebool -P httpd_can_network_connect on |
应用写 /opt/app/data 失败 |
目录上下文不允许写 | semanage fcontext -a -t <app>_var_lib_t 或加 ReadWritePaths |
| 挂载 NFS 后无法访问 | 缺少 use_nfs 布尔 |
setsebool -P httpd_use_nfs on |
12. 日志与排障
12.1 传统日志文件
ls -lh /var/log/
tail -F /var/log/messages # 系统总日志(最重要)
tail -F /var/log/secure # 认证、登录、sudo、SSH
tail -F /var/log/cron # 定时任务执行记录
tail -F /var/log/audit/audit.log # SELinux AVC
tail -F /var/log/boot.log # 开机过程
tail -F /var/log/dnf.log # 包管理(7 为 yum.log)
grep -i error /var/log/messages
zgrep -i error /var/log/messages-20261101.gz # 已轮转的压缩日志
CentOS 用
/var/log/messages与/var/log/secure;Debian/Ubuntu 是syslog与auth.log。抄 Ubuntu 文档会找不到文件。
12.2 journalctl
journalctl -xe # 最近的错误与提示(排障第一站)
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 # 内核
journalctl -b -1 # 上次启动(排查崩溃重启)
journalctl --disk-usage
sudo journalctl --vacuum-time=7d
sudo journalctl --vacuum-size=500M
持久化:
sudo mkdir -p /var/log/journal
sudo systemctl restart systemd-journald
# /etc/systemd/journald.conf: Storage=persistent, SystemMaxUse=2G
版本差异:7/8 的 journald 默认存
/run/log/journal(重启丢失),9+ 默认持久化到/var/log/journal。7 上排"昨天的故障"必须靠 rsyslog 的/var/log/messages。
12.3 rsyslog
systemctl status rsyslog
cat /etc/rsyslog.conf
ls /etc/rsyslog.d/
sudo rsyslogd -N1 # 配置语法检查
sudo systemctl restart rsyslog
# 单独拆一个应用的日志
# /etc/rsyslog.d/myapp.conf
# if $programname == 'myapp' then /var/log/myapp.log
# & stop
12.4 内核与启动
dmesg -T
dmesg -T | grep -iE "error|fail|oom|i/o error"
dmesg -w # 实时
journalctl -k -b
# 内核参数
sysctl -a | grep net.ipv4
cat /etc/sysctl.conf
ls /etc/sysctl.d/
sudo sysctl -p
12.5 日志轮转
cat /etc/logrotate.conf
ls /etc/logrotate.d/
sudo logrotate -d /etc/logrotate.d/myapp # 干跑
sudo logrotate -f /etc/logrotate.d/myapp
/var/log/myapp/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
copytruncate
create 0640 app app
}
13. 定时任务
13.1 cron
crontab -e
crontab -l
crontab -r # ⚠️ 清空当前用户全部任务
sudo crontab -u <user> -l
systemctl status crond # ⚠️ CentOS 服务名是 crond,不是 cron
30 3 * * * /opt/scripts/backup.sh >> /var/log/backup.log 2>&1
*/5 * * * * /opt/scripts/check.sh
0 9-18 * * 1-5 /opt/scripts/sync.sh
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
CentOS 上 cron 的四个坑
- 服务名是
crond,systemctl status cron查不到。 - PATH 极简,命令写绝对路径。
- SELinux 会拦:脚本放在自家目录且无执行上下文时,cron 静默失败。查
/var/log/cron与audit.log。 - 不加载 profile,环境变量要在脚本内显式声明。
grep CRON /var/log/cron | tail -20
sudo ausearch -m avc -ts recent | grep crond
13.2 systemd timer
/etc/systemd/system/backup.service:
[Unit]
Description=Daily backup
[Service]
Type=oneshot
ExecStart=/opt/scripts/backup.sh
/etc/systemd/system/backup.timer:
[Unit]
Description=Run backup daily
[Timer] 03:30:00
Persistent=true
RandomizedDelaySec=300
[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable --now backup.timer
systemctl list-timers --all
journalctl -u backup.service
timer 的优势:
Persistent=true补跑错过的任务、日志自动进 journal、可用systemctl status统一查看、受 systemd 的资源限制管控。生产优先于 cron。
13.3 anacron / at
cat /etc/anacrontab # 非 24 小时运行机器用
echo "/opt/scripts/restart.sh" | at 02:00
at -l; atrm <job>
14. 压缩、备份与传输
14.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 --zstd -cf x.tar.zst /app # zstd,8+ 可用
14.2 rsync
rsync -avzP /data/app/ /backup/app/
rsync -avzP -e "ssh -p 2222" user@host:/data/app/ /backup/app/
rsync -avz --delete --dry-run /src/ /dst/ # 先干跑
rsync -avz --delete /src/ /dst/ # ⚠️ 镜像同步
rsync -avz --exclude='.git' --bwlimit=5000 /data/ /backup/data/
尾斜杠语义:
/src/是"src 的内容",/src是"src 目录本身"。备份脚本写错会多一层嵌套或同步错对象。
14.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
14.4 数据库备份
CentOS 7 默认 MariaDB 5.5,8+ 为 MariaDB 10.3 / MySQL 8:
# 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
# 注意备份目录的 SELinux 上下文
sudo semanage fcontext -a -t mysqld_db_t "/backup/mysql(/.*)?"
sudo restorecon -Rv /backup/mysql
14.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"
14.6 系统级备份与快照
# LVM 快照(需预留空间)
sudo lvcreate -L 20G -s -n snap_root /dev/mapper/centos-root
# XFS 在线转储(慎用,需足够空间)
sudo xfsdump -l 0 -L full -M media -f /backup/root.xfsdump /
sudo xfsrestore -f /backup/root.xfsdump /restore
# 整机镜像(块级,需停机或快照)
sudo dd if=/dev/sda of=/backup/sda.img bs=4M status=progress
15. 性能监控与调优
15.1 快速三连
uptime; free -h; df -h; df -i
top -b -n1 | head -20
15.2 vmstat
vmstat 1 5
| 列 | 含义 | 告警 |
|---|---|---|
r |
运行队列 | 持续 > 核数 |
b |
阻塞进程 | 高说明 IO 卡 |
si/so |
swap 换入换出 | 非 0 即内存不足 |
us/sy |
用户态/内核态 | sy 高查系统调用 |
wa |
IO 等待 | > 20% 查磁盘 |
id |
空闲 | 长期 0 需扩容 |
15.3 iostat / pidstat / mpstat
iostat -xz 1 5
pidstat -u -d -p <pid> 1 5
mpstat -P ALL 1 # 各核负载(排查单核打满)
%util 接近 100% 表示磁盘饱和;await 远大于 svctm 说明排队;aqu-sz 持续 > 2 需关注。
15.4 历史趋势
CentOS 默认装 sysstat 并开启采集(与 Ubuntu 需手动开不同):
sar -u 1 5
sar -r 1 5
sar -d 1 5
sar -n DEV 1 5
sar -u -f /var/log/sa/sa05 # 回看某天(CentOS 路径,Ubuntu 是 sysstat/sa05)
ls /var/log/sa/
15.5 内存
free -h
ps -eo pid,user,rss,cmd --sort=-rss | head -10
cat /proc/meminfo
sudo slabtop
dmesg -T | grep -i "out of memory"
journalctl -k | grep -i "killed process"
关注
available,不是free。buff/cache可回收。
15.6 tuned(CentOS 特色)
sudo dnf install -y tuned
systemctl enable --now tuned
tuned-adm list
tuned-adm active
sudo tuned-adm profile throughput-performance # 数据库/高吞吐
sudo tuned-adm profile virtual-guest # 虚拟机
sudo tuned-adm profile latency-performance # 低延迟
sudo tuned-adm recommend
tuned会改内核参数、IO 调度器、CPU 调频策略,比手写 sysctl 更系统化。RHEL/CentOS 生产标配,Ubuntu 默认没有。
15.7 内核参数(/etc/sysctl.d/99-tuning.conf)
net.core.somaxconn = 32768
net.ipv4.tcp_max_syn_backlog = 16384
net.ipv4.ip_local_port_range = 10000 65000
net.ipv4.tcp_tw_reuse = 1
fs.file-max = 1000000
vm.swappiness = 10
sudo sysctl --system # 8+ 推荐
sudo sysctl -p # 7
15.8 IO 调度器
cat /sys/block/sda/queue/scheduler
echo mq-deadline | sudo tee /sys/block/sda/queue/scheduler
# 持久化:内核参数 elevator=mq-deadline,或 udev 规则
版本差异:7 内核 3.10 默认
deadline/cfq;8+ 为多队列mq-deadline/none,cfq已移除。照抄 7 的调优文档设cfq会失败。
15.9 压测与定位
stress-ng --cpu 4 --timeout 60s # EPEL
sysbench cpu --threads=4 run
sudo perf top # 函数级热点
sudo perf record -g -p <pid> -- sleep 10 && sudo perf report
16. SSH 与远程运维
16.1 密钥登录
ssh-keygen -t ed25519 -C "ops@company"
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@host
~/.ssh/config:
Host prod-web
HostName 10.0.1.10
User ops
Port 2222
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
16.2 服务端加固
# 配置目录差异
ls /etc/ssh/sshd_config.d/ # 8+ 支持 Include,7 没有该目录
# 7:直接改 /etc/ssh/sshd_config
# 8+:建议在 /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 sshd # ⚠️ CentOS 服务名是 sshd,不是 ssh
改 SSH 端口三步缺一不可:
sshd_config改Port- firewalld 放行:
firewall-cmd --permanent --add-port=2222/tcp && firewall-cmd --reload- SELinux 打标签:
semanage port -a -t ssh_port_t -p tcp 2222只做第 1 步会导致 sshd 起不来,是最常见的"把自己锁在门外"。
16.3 隧道
ssh -L 8080:localhost:80 user@host # 本地转发
ssh -R 9000:localhost:3000 user@host # 远程转发
ssh -D 1080 user@host # SOCKS5 代理
ssh -J jump@bastion user@internal # 跳板
16.4 批量执行
for h in web1 web2 web3; do
echo "== $h =="
ssh -o ConnectTimeout=5 "$h" 'systemctl is-active nginx'
done
sudo dnf install -y pdsh
pdsh -w web[1-3] 'uptime'
16.5 SSH 排障速查
sudo tail -50 /var/log/secure
sudo sshd -t
sudo ss -tulnp | grep sshd
getenforce; sudo semanage port -l | grep ssh
sudo firewall-cmd --list-all
| 现象 | 排查 |
|---|---|
| Connection refused | sshd 未启动 / 端口未监听 / SELinux 端口标签缺失 |
| Connection timed out | firewalld、云安全组、网络 |
| Permission denied (publickey) | authorized_keys 权限须 600、~/.ssh 700、家目录不可组可写 |
| 登录后立即断开 | 磁盘满、shell 不存在、/etc/nologin、PAM 限制 |
| 连接被重置 | fail2ban/denyhosts 封禁、/etc/hosts.deny |
17. 高频故障速查表
17.1 CPU 高
top -b -n1 | head -15
ps -p <pid> -o pid,user,%cpu,etime,cmd
top -H -p <pid> # 线程级
pidstat -u 1 -p <pid>
sudo perf top
17.2 磁盘满
df -h; df -i
du -h --max-depth=1 / 2>/dev/null | sort -rh | head
sudo lsof +L1 # 已删除仍被占用
journalctl --vacuum-size=200M
sudo dnf clean all
find /var/log -name "*.gz" -mtime +30 -delete
# Docker 环境
docker system df
docker system prune -a
常见元凶:/var/log 未轮转、/var/lib/docker 堆积、journal 无上限、被删除的大文件仍被进程持有、inode 耗尽(/var/spool/postfix 堆积)。
17.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
17.4 服务起不来(CentOS 四步法)
# 1. systemd 层
systemctl status <svc> -l
journalctl -u <svc> -n 100 --no-pager
# 2. SELinux 层(最常见的隐蔽原因)
sudo ausearch -m avc -ts recent
getenforce
# 3. 端口与进程层
sudo ss -tulnp | grep <port>
# 4. 手动复现
sudo -u <svcuser> <实际命令>
ls -l <工作目录> <日志目录>
17.5 权限正常但访问被拒(SELinux)
getenforce
sudo ausearch -m avc -ts recent | tail -20
sudo sealert -a /var/log/audit/audit.log
ls -Z <路径>
sudo restorecon -Rv <路径>
sudo setenforce 0 # 临时验证是否 SELinux 引起
17.6 网络通但服务连不上
ss -tulnp | grep <port> # 本机是否监听
firewall-cmd --list-all # 防火墙
sudo semanage port -l | grep <port> # SELinux 端口
curl -v http://127.0.0.1:<port> # 本机自连
ip r; ip a # 路由与地址
sudo tcpdump -i any -nn port <port> # 是否有包到达
17.7 yum/dnf 报错
| 报错 | 处理 |
|---|---|
Cannot find a valid baseurl |
网络/DNS 不通,或 7 的源已下线需换 vault |
repomd.xml ... GPG 错误 |
dnf clean all && dnf makecache;检查系统时间 |
Error: rpmdb open failed |
rm -f /var/lib/rpm/__db*; rpm --rebuilddb |
Transaction check error |
依赖冲突,dnf distro-sync 或逐一降级 |
No space left on device |
清 /var/cache/dnf、/var/cache/yum |
dnf: command not found(在 7 上) |
7 只有 yum,不要照抄 8+ 文档 |
17.8 系统启动失败
# emergency/rescue 下
mount -o remount,rw /
cat /etc/fstab # 错误条目,加 nofail
systemctl --failed
journalctl -xb -p err
# SELinux 导致无法启动:grub 加 selinux=0 一次性进入,之后修上下文
17.9 时间错乱导致证书/认证失败
timedatectl
chronyc tracking
sudo systemctl restart chronyd
sudo chronyc makestep
18. 版本生命周期与迁移路径
18.1 生命周期现状
| 版本 | EOL | 现状与建议 |
|---|---|---|
| CentOS 7 | 2024-06-30 | 已停更,仓库迁 vault。必须迁移 |
| CentOS 8 | 2021-12-31 | 已停更,转 Stream 8 亦已 EOL |
| Stream 8 | 2024-05-31 | 已 EOL |
| Stream 9 | 约 2027-05 | 当前主力,可用 |
| Stream 10 | 约 2030 | 新版本,逐步铺开 |
CentOS Linux 已于 2021 年底转向 CentOS Stream(滚动预览版,位于 RHEL 之前)。追求"稳定下游"的场景应选 Rocky Linux 或 AlmaLinux(RHEL 1:1 重建)。
18.2 CentOS 7 停更后的源切换
sudo sed -i 's|^mirrorlist=|#mirrorlist=|g' /etc/yum.repos.d/CentOS-*.repo
sudo sed -i 's|^#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' /etc/yum.repos.d/CentOS-*.repo
sudo yum clean all && sudo yum makecache
这只解决"还能装包",不解决安全更新。vault 是只读归档,不会有新补丁。
18.3 迁移路径
| 起点 | 目标 | 工具/方式 |
|---|---|---|
| CentOS 7 | Rocky/Alma 8 或 9 | elevate(AlmaLinux ELevate 项目)或重装 |
| CentOS 8 | Stream 8 / Rocky 8 | dnf swap centos-linux-repos centos-stream-repos 或 migrate2rocky |
| Stream 8 | Stream 9 | 不支持原地升级,重装 |
| Stream 9 | Stream 10 | 不支持原地升级,重装 |
| 任意 | Ubuntu | 重装(包管理与 SELinux 体系完全不同) |
# CentOS 8 → Stream 8
sudo dnf install -y centos-release-stream
sudo dnf swap centos-{linux,stream}-repos
sudo dnf distro-sync -y
# 8 → Rocky Linux(migrate2rocky)
curl -O https://raw.githubusercontent.com/rocky-linux/rocky-tools/main/migrate2rocky/migrate2rocky.sh
sudo bash migrate2rocky.sh -r
跨大版本迁移的现实建议:7→9 原地升级成功率低、回滚困难。生产环境优先"新建 + 数据迁移 + 灰度切流"。必须原地升级时,先全量快照,并在测试环境完整演练一遍。
18.4 迁移前检查清单
# 1. 记录当前状态
rpm -qa > /root/pkgs-before.txt
systemctl list-unit-files --state=enabled > /root/services-before.txt
cat /etc/fstab > /root/fstab-before.txt
ip a > /root/ip-before.txt
firewall-cmd --list-all > /root/fw-before.txt
# 2. 找出第三方源与非官方包(升级最大障碍)
ls /etc/yum.repos.d/
dnf repolist
rpm -qa --qf '%{NAME} %{VENDOR}\n' | grep -viE 'centos|red hat|rhel'
# 3. 确认关键软件在新版本的可用性(尤其依赖 Python 2 的自研脚本)
python2 -V 2>/dev/null; python3 -V
Python 2 是 7→8+ 迁移最大暗坑:7 的系统工具大量依赖 Python 2.7,8+ 全为 Python 3,9/10 完全无 Python 2。自研运维脚本必须提前改造。
19. 危险命令与避坑清单
19.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.xfs /dev/sda |
误格式化系统盘 |
rpm -e --nodeps <核心包> |
破坏依赖树,可能无法开机 |
setenforce 0 后忘记恢复 |
安全边界长期失效 |
/etc/selinux/config 改 disabled |
重启后需全盘 relabel 才能恢复 |
firewall-cmd --panic-on(远程) |
立即切断 SSH |
> /etc/passwd > /etc/shadow |
清空账户库 |
lvreduce 缩 XFS |
不支持,直接损坏文件系统 |
rsync --delete 方向写反 |
空目录覆盖源数据 |
19.2 CentOS 专属避坑
- 不要禁用 SELinux:用
setenforce 0验证,用semanage/restorecon/setsebool解决问题。 - 改 SSH 端口必须同步 firewalld + SELinux,两处缺一即失联。
- XFS 不能缩容,LV 规划留余量。
- fstab 加
nofail,避免磁盘缺失导致无法开机。 limits.conf不影响 systemd 服务,用LimitNOFILE。- 7 的教程不要照搬到 8+:
service/chkconfig/ifcfg/iptables/netstat大多已移除或失效。 - Stream 与 CentOS Linux 不是一回事:Stream 是滚动预览,补丁先于 RHEL,稳定性预期不同。
19.3 变量保护写法
# 错误
rm -rf "$VAR"/
# 正确
: "${VAR:?VAR is not set}"
rm -rf "${VAR:?}"/
19.4 变更前自保
cp -a /etc/firewalld /root/backup-firewalld-$(date +%F)
cp -a /etc/ssh/sshd_config /root/backup-sshd-$(date +%F)
cp /etc/fstab /root/backup-fstab-$(date +%F)
firewall-cmd --list-all > /root/fw-$(date +%F).txt
附录 A:常用命令速查
| 场景 | 命令 |
|---|---|
| 版本判断 | rpm -E %{rhel} / cat /etc/centos-release |
| 系统概况 | hostnamectl / lscpu / free -h |
| 磁盘使用 | df -h df -i du -sh * |
| 找大文件 | du -h --max-depth=1 / | sort -rh | head |
| 假性磁盘满 | lsof +L1 |
| 端口占用 | ss -tulnp | grep :80 |
| 进程详情 | ps -eo pid,user,%cpu,%mem,cmd --sort=-%cpu | head |
| 服务状态 | systemctl status x / journalctl -u x -f |
| 失败服务 | systemctl --failed |
| 防火墙 | firewall-cmd --list-all |
| SELinux 状态 | getenforce / sestatus |
| SELinux 拒绝 | ausearch -m avc -ts recent |
| 端口标签 | semanage port -l | grep http_port_t |
| 上下文修复 | restorecon -Rv <path> |
| 布尔开关 | setsebool -P <bool> on |
| 网络配置 | nmcli con mod + nmcli con up |
| 包管理 | dnf install / dnf provides */cmd |
| 反查命令来源包 | rpm -qf $(which cmd) |
| 定时任务 | crontab -l / systemctl list-timers |
| 增量备份 | rsync -avzP --dry-run src/ dst/ |
| 实时日志 | tail -F /var/log/messages |
| 开机耗时 | systemd-analyze blame |
| 登录审计 | last / lastb / grep Failed /var/log/secure |
附录 B:接手 CentOS 服务器检查清单
# 1. 版本与硬件
rpm -E %{rhel}; hostnamectl; lscpu; free -h; df -h; df -i
# 2. 谁在用、跑什么
who; w; systemctl list-units --type=service --state=running
# 3. 暴露面
ss -tulnp
firewall-cmd --list-all
getenforce
# 4. 健康度
systemctl --failed
journalctl -p err -b --no-pager | tail -30
dmesg -T | grep -iE "error|fail|i/o error" | tail -20
# 5. 定时任务与自启
crontab -l; ls /etc/cron.d/; systemctl list-timers --all
# 6. 安全基线
grep -E "^(PermitRootLogin|PasswordAuthentication|Port)" /etc/ssh/sshd_config
ausearch -m avc -ts today | tail -20
lastb | head -20
find / -perm -4000 -type f 2>/dev/null
# 7. 更新与仓库状态(7 尤其重要)
dnf check-update || yum check-update
dnf repolist || yum repolist
# 8. 备份是否真的在跑
ls -lht /backup | head; ls -lht /var/backups | head
文档维护建议:本手册的「版本差异」标注点是跨版本最容易出事故的地方,建议在团队内单独整理成一页《CentOS 版本差异对照卡》贴在内网文档首页,新人上手先看这页。