做企业级服务器升级这件事,说复杂也复杂,说简单也简单。复杂的是那些藏在系统底层的服务依赖和版本兼容性问题,简单的是只要你按步骤来、有预案,绝大多数坑都能绕过去。我见过太多人升级时因为一个配置文件没改、一个服务没停,最后搞得凌晨三点在机房崩溃。所以今天这篇指南,不玩虚的,直接上干货,帮你把AlmaLinux 8升到9这条路走稳、走顺。
先说一个核心认知:AlmaLinux 9不是AlmaLinux 8的简单”新版本”,它是基于RHEL 9重建的完整企业级操作系统。这意味着你的内核、系统工具链、文件系统规范、甚至一些默认配置都变了。但好消息是,AlmaLinux官方提供了leapp工具来帮你完成这个迁移过程,问题只是——工具会用,不代表你懂它为什么报错。
一、升级前的”保命”动作:完整备份与系统健康检查
1.1 数据备份:三层防护策略
第一层:系统快照备份(如果你用的是云服务商)
如果你的服务器运行在阿里云、AWS、华为云或VMware等虚拟化平台,第一件事是创建系统盘快照。这个动作本身只需要5分钟,但能救你的命。
# 阿里云创建快照示例(通过CLI)
aliyun ecloud CreateSnapshot \
--RegionId cn-hangzhou \
--DiskId d-bp1xxxx \
--SnapshotName "almalinux8-to-9-backup-$(date +%Y%m%d-%H%M%S)"
# AWS创建EBS快照
aws ec2 create-snapshot \
--volume-id vol-0abc123def456 \
--description "AlmaLinux8-Backup-Before-Upgrade-$(date +%Y%m%d)"
# VMware创建虚拟机快照
# 在vSphere Client中右键虚拟机 -> Snapshot -> Take Snapshot
# 命名建议:Pre-Upgrade-Backup-$(date +%Y%m%d)
第二层:关键数据目录归档
即使你有系统快照,也要单独备份以下目录。原因很简单:快照恢复后你可能需要手动还原某些配置,提前准备好能节省大量时间。
# 创建备份脚本 backup-pre-upgrade.sh
#!/bin/bash
BACKUP_DIR="/data/backups/pre-upgrade-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$BACKUP_DIR"/{etc,home,opt,mysql,nginx,postgres,app,logs}
# 系统配置备份
echo "=== 开始备份系统配置 ==="
tar czf "$BACKUP_DIR/etc/sysconfig.tar.gz" /etc/sysconfig/ 2>/dev/null
tar czf "$BACKUP_DIR/etc/network.tar.gz" /etc/sysconfig/network-scripts/ 2>/dev/null
tar czf "$BACKUP_DIR/etc/yum.repos.tar.gz" /etc/yum.repos.d/
tar czf "$BACKUP_DIR/etc/ansible.tar.gz" /etc/ansible/ 2>/dev/null
cp -r /etc/ssh "$BACKUP_DIR/etc/ssh"
cp -r /etc/selinux "$BACKUP_DIR/etc/selinux"
# 用户数据备份
echo "=== 开始备份用户数据 ==="
rsync -av --exclude='lost+found' /home/ "$BACKUP_DIR/home/"
rsync -av --exclude='cache' /opt/ "$BACKUP_DIR/opt/"
# MySQL数据备份
echo "=== 开始备份MySQL ==="
mysqldump --all-databases --single-transaction --routines --triggers > "$BACKUP_DIR/mysql/all-databases.sql"
tar czf "$BACKUP_DIR/mysql/data.tar.gz" /var/lib/mysql/ --exclude='mysql-bin.*' --exclude='ib_logfile*' 2>/dev/null
# PostgreSQL数据备份
echo "=== 开始备份PostgreSQL ==="
su - postgres -c "pg_dumpall > /tmp/pg-full-dump.sql"
cp /tmp/pg-full-dump.sql "$BACKUP_DIR/postgres/"
tar czf "$BACKUP_DIR/postgres/data.tar.gz" /var/lib/pgsql/ 2>/dev/null
# 应用程序备份(根据你的实际路径调整)
echo "=== 开始备份应用程序 ==="
rsync -av /your/app/path/ "$BACKUP_DIR/app/" 2>/dev/null
# Nginx配置备份
echo "=== 开始备份Nginx ==="
tar czf "$BACKUP_DIR/nginx/conf.tar.gz" /etc/nginx/
rsync -av /usr/share/nginx/html/ "$BACKUP_DIR/nginx/html/" 2>/dev/null
# 关键日志备份(用于升级后问题排查)
echo "=== 开始备份日志 ==="
tar czf "$BACKUP_DIR/logs/messages.tar.gz" /var/log/messages* 2>/dev/null
tar czf "$BACKUP_DIR/logs/secure.tar.gz" /var/log/secure* 2>/dev/null
tar czf "$BACKUP_DIR/logs/yum.log.tar.gz" /var/log/yum.log 2>/dev/null
# 生成备份清单
echo "=== 生成备份清单 ==="
ls -lah "$BACKUP_DIR" > "$BACKUP_DIR/backup-manifest.txt"
echo "备份完成时间:$(date)" >> "$BACKUP_DIR/backup-manifest.txt"
echo "备份大小:$(du -sh "$BACKUP_DIR" | cut -f1)" >> "$BACKUP_DIR/backup-manifest.txt"
echo "=== 备份完成 ==="
echo "备份目录:$BACKUP_DIR"
echo "备份大小:$(du -sh "$BACKUP_DIR" | cut -f1)"
echo "清单文件:$BACKUP_DIR/backup-manifest.txt"
执行这个脚本前,记得修改第57行和62行的路径,确保覆盖你实际的应用目录。
第三层:系统状态记录
在升级前,把系统当前的状态信息全部记录到文件中。升级后如果出现问题,这些记录是你排查问题的”时间机器”。
# 创建系统状态记录脚本 record-system-state.sh
#!/bin/bash
STATE_DIR="/data/backups/system-state-$(date +%Y%m%d-%H%M%S)"
mkdir -p "$STATE_DIR"
echo "=== 系统基本信息 ===" > "$STATE_DIR/01-system-info.txt"
uname -a >> "$STATE_DIR/01-system-info.txt"
echo "" >> "$STATE_DIR/01-system-info.txt"
cat /etc/os-release >> "$STATE_DIR/01-system-info.txt"
echo "" >> "$STATE_DIR/01-system-info.txt"
free -h >> "$STATE_DIR/01-system-info.txt"
echo "" >> "$STATE_DIR/01-system-info.txt"
df -h >> "$STATE_DIR/01-system-info.txt"
echo "=== 运行中的服务 ===" > "$STATE_DIR/02-running-services.txt"
systemctl list-units --type=service --state=running >> "$STATE_DIR/02-running-services.txt" 2>&1
echo "=== 监听端口 ===" > "$STATE_DIR/03-listening-ports.txt"
ss -tlnp >> "$STATE_DIR/03-listening-ports.txt" 2>&1
netstat -tlnp >> "$STATE_DIR/03-listening-ports.txt" 2>/dev/null
echo "=== 已安装的关键软件包 ===" > "$STATE_DIR/04-key-packages.txt"
rpm -qa | grep -E "(nginx|httpd|mysql|postgres|redis|docker|python|java|nodejs|php)" | sort >> "$STATE_DIR/04-key-packages.txt"
echo "=== YUM仓库配置 ===" > "$STATE_DIR/05-yum-repos.txt"
ls -la /etc/yum.repos.d/ >> "$STATE_DIR/05-yum-repos.txt"
cat /etc/yum.repos.d/*.repo >> "$STATE_DIR/05-yum-repos.txt" 2>/dev/null
echo "=== 环境变量 ===" > "$STATE_DIR/06-environment-vars.txt"
env >> "$STATE_DIR/06-environment-vars.txt"
echo "=== Crontab任务 ===" > "$STATE_DIR/07-crontab.txt"
crontab -l >> "$STATE_DIR/07-crontab.txt" 2>/dev/null
ls -la /etc/cron.d/ >> "$STATE_DIR/07-crontab.txt"
cat /etc/cron.d/* >> "$STATE_DIR/07-crontab.txt" 2>/dev/null
echo "=== SELinux状态 ===" > "$STATE_DIR/08-selinux-status.txt"
getenforce >> "$STATE_DIR/08-selinux-status.txt"
sestatus >> "$STATE_DIR/08-selinux-status.txt"
auditctl -s >> "$STATE_DIR/08-selinux-status.txt"
echo "=== 文件系统挂载 ===" > "$STATE_DIR/09-fstab.txt"
cat /etc/fstab >> "$STATE_DIR/09-fstab.txt"
blkid >> "$STATE_DIR/09-fstab.txt"
echo "=== SSH配置 ===" > "$STATE_DIR/10-ssh-config.txt"
cat /etc/ssh/sshd_config >> "$STATE_DIR/10-ssh-config.txt"
ls -la /etc/ssh/ssh_host_* >> "$STATE_DIR/10-ssh-config.txt"
echo "=== 备份完成,记录目录:$STATE_DIR ==="
echo "文件大小统计:"
du -sh "$STATE_DIR"
执行后,你会得到一个包含10个文件的目录,每个文件记录系统的一个维度的状态。这个习惯请务必保持,它会在升级失败时救你的命。
1.2 系统健康检查:升级前的”体检”
检查磁盘空间
AlmaLinux 9的升级过程需要额外的磁盘空间来下载和存储rpm包。官方建议至少保留2GB的/var目录空间,但为了保险,我建议至少5GB。
# 检查关键分区空间
echo "=== 磁盘空间检查 ==="
df -h / /var /tmp /home
echo ""
echo "=== /var目录详细空间使用 ==="
du -sh /var/*/ 2>/dev/null | sort -hr | head -20
echo ""
echo "=== 检查/var/log是否过大 ==="
du -sh /var/log/ 2>/dev/null
echo ""
echo "=== 清理日志建议(如果超过1GB) ==="
if [ $(du -s /var/log/ 2>/dev/null | cut -f1) -gt 1000000 ]; then
echo "警告:/var/log空间较大,建议清理"
echo "建议执行:journalctl --vacuum-size=100M"
echo "建议执行:find /var/log -name "*.log" -size +100M -exec truncate -s 0 {} \;"
fi
检查系统包状态
升级前确保当前系统没有损坏的包,否则leapp可能会失败或产生不可预测的结果。
# 检查rpm数据库完整性
echo "=== 检查RPM数据库 ==="
rpm -Va 2>&1 | grep -v "^No files" | head -50
echo ""
echo "=== 检查损坏的包 ==="
rpm -Va --nofiles --nodigest 2>&1 | head -20
echo ""
echo "=== 检查未完成的事务 ==="
rpm -qa --qf '%{NAME} %{FILENAMES}\n' 2>&1 | head -20
echo ""
echo "=== 检查需要修复的包 ==="
dnf check 2>&1
echo ""
echo "=== 检查可更新的包 ==="
dnf upgrade --refresh --best --assumeno 2>&1 | head -30
如果发现损坏的包,先修复再升级:
# 修复rpm数据库
echo "=== 修复RPM数据库 ==="
rpm --rebuilddb
dnf clean all
dnf update --refresh
检查第三方仓库和EPEL
AlmaLinux 9的仓库结构与AlmaLinux 8不完全兼容。特别是EPEL(Extra Packages for Enterprise Linux)需要从EPEL 8升级到EPEL 9。
# 检查当前仓库状态
echo "=== 当前启用的仓库 ==="
dnf repolist enabled
echo ""
echo "=== 检查第三方仓库 ==="
ls -la /etc/yum.repos.d/ | grep -v "almalinux\|epel"
echo ""
echo "=== 检查仓库的gpg签名 ==="
for repo in $(dnf repolist --all --qf "%{repoid}"); do
echo "检查仓库: $repo"
dnf repoinfo "$repo" 2>&1 | grep -E "(Repository ID|Name|Status)" | head -3
done
检查内核模块和驱动
如果你运行的是物理机或特定硬件环境,需要检查内核模块是否兼容。
# 检查当前内核模块
echo "=== 当前内核模块 ==="
uname -r
echo ""
echo "=== 列出关键模块 ==="
lsmod | grep -E "(nvidia|vmware|virtualbox|zfs|bcache|dm_|loop|md)"
echo ""
echo "=== 检查DKMS模块(如NVIDIA驱动) ==="
dkms status 2>/dev/null || echo "DKMS未安装"
echo ""
echo "=== 检查第三方内核模块 ==="
find /lib/modules/$(uname -r) -name "*.ko" | grep -v "kernel" | head -20
1.3 服务停机窗口规划
企业级服务器升级不是随时可以做的。你需要:
- 确定业务低峰期:通常是凌晨0-6点,但具体看你的业务类型
- 通知相关人员:开发、运维、测试团队
- 准备回滚方案:如果升级失败,如何在30分钟内恢复服务
- 文档记录:升级前后的状态、操作日志、问题记录
# 创建升级计划文档模板
cat > /data/backups/upgrade-plan.md << 'EOF'
# AlmaLinux 8 -> 9 升级计划
## 基本信息
- 服务器名称:
- 服务器IP:
- 当前版本:AlmaLinux 8.x
- 目标版本:AlmaLinux 9.x
- 计划升级时间:
- 预计耗时:
- 负责人:
## 业务影响
- 影响的服务:
- 影响的用户:
- 回滚时间窗口:
## 备份清单
- [ ] 系统快照已创建
- [ ] 关键数据已备份
- [ ] 系统状态已记录
- [ ] 配置文件已归档
## 升级步骤
1. 预检:
2. 安装leapp:
3. 执行升级:
4. 重启系统:
5. 验证:
6. 清理:
## 回滚方案
如果升级失败,执行:
1. 从快照恢复系统
2. 恢复配置文件
3. 恢复数据库
4. 验证服务
## 升级后检查清单
- [ ] 系统正常启动
- [ ] 关键服务运行正常
- [ ] 数据库连接正常
- [ ] 应用程序功能正常
- [ ] 监控告警正常
- [ ] 日志无异常
EOF
二、安装和配置leapp升级工具
2.1 leapp工具的安装
leapp是AlmaLinux官方提供的升级工具,它会自动分析你的系统、检测兼容性问题、生成升级报告。在AlmaLinux 8中安装:
# 安装leapp和相关工具
echo "=== 安装leapp升级工具 ==="
dnf install -y leapp leapp-upgrade leapp-repository
echo ""
echo "=== 验证安装 ==="
leapp --version
echo ""
leapp answer --help
echo ""
echo "=== 检查leapp-repository版本 ==="
rpm -qi leapp-repository
2.2 配置leapp仓库
# 检查当前仓库配置
echo "=== 检查leapp仓库配置 ==="
cat /etc/yum.repos.d/almalinux-leapp.repo 2>/dev/null || echo "仓库配置文件不存在"
echo ""
echo "=== 启用leapp仓库 ==="
dnf config-manager --set-enabled almalinux-leapp
echo ""
echo "=== 刷新仓库元数据 ==="
dnf clean all
dnf makecache
2.3 执行预检分析
这是最重要的一步。leapp会扫描你的系统,找出可能导致升级失败的问题。
# 执行预检分析
echo "=== 开始leapp预检分析 ==="
echo "这可能需要10-30分钟,请耐心等待..."
echo ""
leapp preupgrade 2>&1 | tee /data/backups/leapp-preupgrade-report.log
echo ""
echo "=== 预检分析完成 ==="
echo "报告文件:/data/backups/leapp-preupgrade-report.log"
echo "答案文件:/etc/leapp/repos.d/system_upgrade/el8to9/answers.json"
预检分析会生成两个关键文件:
- 报告文件:包含所有检测到的问题和警告
- 答案文件:你需要根据实际情况修改这个文件,告诉leapp如何处理某些问题
2.4 分析预检报告
预检报告会列出几类问题:
Critical(严重):必须解决的问题,否则升级会失败 Warning(警告):建议解决的问题,不解决可能导致升级后功能异常 Information(信息):仅供参考,不影响升级
”`bash
提取关键问题
echo “=== 提取Critical问题 ===” grep -A 10 “severity: Critical” /data/backups/leapp-preupgrade-report.log | head -50 echo “” echo “=== 提取Warning问题 ===” grep -A 10 “severity: Warning” /data/backups/leapp-preupgrade-report
