背景
早期,客户的On-premises网关设备(基于CentOS 7)采用增量升级方案进行固件更新。 这种方案存在两个主要问题:
- 一旦升级过程中出现问题,客户只能重新安装系统,严重影响用户体验。
- 部分客户未开启自动升级功能,为了支持所有客户的升级需求,升级包必须保存从初始版本到最新版本的所有增量文件。随着版本迭代,升级包变得越来越大,难以维护。
为了解决这些问题,需要为客户网关设备设计一种新的升级方案。
A/B系统升级简介
A/B分区升级机制允许设备在不同分区上安装和运行系统的不同版本,从而实现无缝更新。这种方法常用于移动设备、物联网设备以及其他需要高可用性和减少停机时间的场景中。例如,Android系统、Chrome OS及许多嵌入式和IoT设备都采用了A/B系统升级方法。其主要优点包括:
- 无缝更新:可以在系统运行期间进行更新,唯一的宕机发生在设备重启到更新后分区时。
- 故障恢复:如果升级失败,设备仍可工作在旧分区,并允许客户继续尝试升级。
方案
升级方案中包含以下关键环节:
- 设计分区
- 构建升级包
- 同步系统配置
- 配置GRUB启动项
设计分区
客户的设备只有一个虚拟硬盘,因此需要重新设计分区方案,划出两个系统分区,具体如下:
1 | +--------------------------------------------------+ |
- 使用BIOS+GPT分区格式,以兼容现有客户。分区方案包括:BIOS Boot分区(sda1)、Boot分区(sda2)和LVM分区(sda3)。LVM分区便于后期扩容。
- 在LVM分区上创建名为VA的逻辑卷组,并进一步创建四个逻辑卷:VA-root和VA-back作为两个系统分区,VA-data存储公共数据,VA-image存储镜像文件。
构建升级包
构建原理如下:
- 通过ISO安装虚拟机, 导出虚拟机OVA文件, 解压OVA文件得到VMDK磁盘文件
- 使用guestmount挂载VMDK文件,对整个根文件系统进行打包,注意打包时需保留UID(numeric-owner)和文件扩展属性(xattr),解包时同样需要声明UID和xattr。
同步系统配置
在升级过程中需要同步当前系统的配置到目标系统,以确保无缝升级。这些配置包括:
- 网络配置, 比如网卡, 路由, hostname, NTP Server, DNS
- LVM配置(/etc/lvm)
- 用户口令(/etc/shadow), SSH密钥, 以确保升级后客户仍能通过密码或SSH登录。
- 同步证书(/etc/pki/tls/certs)
- 正确设置备用分区的/etc/fstab,确保两个系统分区的正确挂载路径。
配置GRUB启动项
双系统升级需要配置GRUB以正确引导两个系统分区。这里存在一个难点:目标系统的GRUB版本可能比当前系统更高,使用当前系统的GRUB引导两个系统分区可能存在兼容性问题。针对这种情况,我采取了以下做法:
- 使用目标系统的/boot引导两个系统的内核。
- 通过chroot方式配置并重装GRUB。
- 如果GRUB配置失败,回滚到升级前的状态。
为什么不直接把目标系统的/boot放在LVM系统分区?
- 兼容性问题, 传统BIOS和某些UEFI固件不支持直接从LVM卷启动
- 复杂性增加, 故障恢复困难
为什么不划两个/boot分区?
- 手动修改风险:客户需要手动调整磁盘分区,这不仅增加了操作难度,还可能导致数据丢失或分区表损坏。
- 实现复杂性:理论上划分两个/boot分区是可行的,但实现起来较为复杂。实际上,GRUB的一个/boot分区就可以引导多个版本的内核,支持向前兼容。
优化
当目标系统GRUB版本与当前系统不一致时,直接覆盖/boot分区可能导致旧系统的引导文件丢失,进而导致启动故障。
实际测试中,没有遇到客户出现此类问题。如果要避免覆盖问题,可以使用EFI系统分区,为每个系统创建独立目录存放引导文件:
1 | /boot/efi/EFI/systemA/ |
问题记录
1. 客户升级后admin用户无法登录
定位:后台查看发现admin用户的文件UID不正确,升级前后两个系统的用户配置不一致。同样的admin用户在两个系统上的UID不同。由于升级包是通过tar备份的,而tar解压文件的默认行为是根据当前系统用户名进行映射,而不是UID,因此升级后文件的UID不正确。
解决方法:在tar解压时添加–numeric-owner参数,保留文件的UID,解决了问题。
2. 升级到Rocky Linux 9.4后, 客户设备启动故障, 报错: 虚拟机CPU不支持x86_64_v2
定位:查看/proc/cpuinfo,发现客户虚拟机不支持x86_64_v2指令集,但物理服务器支持该指令集。
解决方法:指导客户开启CPU虚拟化扩展,并在升级前验证虚拟机CPU是否支持所需指令集。如果不支持,则直接上报失败。
3: 配置了双网卡的客户, 在升级到Rocky Linux 9.4后有概率出现网络不通, 网卡的IP,Gateway配置看上去是正确的
定位: 首先ping网关, 发现网关不可达, 通过ethtool查看网卡信息, 发现升级后eth0和eth1顺序反了, 导致网络不通
原因: 现代Linux系统通常使用基于硬件信息(如PCI总线ID)的可预测网卡命名规则,保证OS升级后网卡顺序也是正确的。 但是我们的网关设备采用的还是传统的eth命名规则,这种规则不能保证网卡顺序的正确性。
解决方法: 升级后用ethtool判断网卡顺序是否正确, 如果不正确, 用modprobe按正确顺序加载网卡驱动; (如果两个网卡驱动相同, 还需要修改udev规则)