在Ubuntu中构建chroot环境运行CentOS
我在 HPE DL360 BIOS升级 时发现,在企业级Linux市场,果然 RedHat Linux 占据了主导地位: HP官方网站只提供Windows安装包和RPM安装包。但这也带来了一点困扰:
虽然可以通过 alien软件包转换工具 将RPM包转换成DEB包,但是我发现一个非常尴尬的事情: HP官网提供了大量的软件包,但是没有明确软件包如何对应于硬件,而服务器硬件组合实在太繁多,很难确定我现有的 HPE ProLiant DL360 Gen9服务器 硬件配置是否需要安装更新包
同一个软件包可以能包含了针对多种硬件的firmware更新,但列出的型号很难确定和
dmidecode
或lspci
对应
不过,HP为方便系统升级,提供了完整的 SSP 安装光盘,可以通过集成更新脚本自动匹配硬件进行升级更新,这对运维工作带来极大方便。可惜,由于是集成RPM包,所以也不太可能将数百给RPM包转换成DEB包进行一一测试安装。
比较笨的方法是使用基于RHEL/CentOS的U盘运行系统,然后运行SSP安装光盘进行服务器硬件的firmware/BIOS更新。但是,我希望使用更为优雅的方式:
既然在安装 Arch Linux 时能够通过 chroot
切换系统运行根目录,能够迅速从一种Linux操作系统切换到另一种,那么也可以在这种方式,把我现在在 HPE ProLiant DL360 Gen9服务器 上安装的 Ubuntu Linux 系统切换成 CentOS ,也就能够运行更新软件了。这种方式除了内核不是CentOS发行版内核,其他软件包运行环境并没有区别。
备注
说到 chroot
,你肯定就想起了 Docker : 是的,Docker的底层关键技术就是 chroot
,也就是能够在一个底层操作系统上切换到不同Linux系统运行的关键。不过,Docker容器环境对容器做了诸多安全限制,并不适合我们这种需要对底层物理服务器更新firmware/bios的场景。
使用 rinse
初始化 booststap
Debian提供了 rinse
脚本来创建很多基于RPM系统的最小化安装:
sudo apt install rinse
初始化系统:
sudo su - rinse --arch amd64 --distribution centos-7 \ --directory /srv/chroot/centos-7 \ --mirror http://mirrors.163.com/centos/7.9.2009/os/x86_64/Packages
此时会在 /srv/chroot/centos-7
目录下下载需要的rpm
我这里遇到报错:
Extracting: filesystem-3.2-25.el7.x86_64.rpm
failed to extract filesystem-3.2-25.el7.x86_64.rpm: 16384 at /usr/sbin/rinse line 1254.
检查 /usr/sbin/rinse
可以看到这步是执行:
rpm2cpio filesystem-3.2-25.el7.x86_64.rpm | (cd /var/lib/docker/chroot/centos-7 ; cpio --extract --extract-over-symlinks --make-directories --no-absolute-filenames --preserve-modification-time)
模拟执行了一次发现报错是:
cpio: unrecognized option '--extract-over-symlinks'
Try 'cpio --help' or 'cpio --usage' for more information.
看来 cpio
参数不兼容,所以修订 /usr/sbin/rinse
去掉 --extract-over-symlinks
参数:
# Run the unpacking command.
#
my $cmd =
# "rpm2cpio $file | (cd $CONFIG{'directory'} ; cpio --extract --extract-over-symlinks --make-directories --no-absolute-filenames --preserve-modification-time) 2>/dev/null >/dev/null";
"rpm2cpio $file | (cd $CONFIG{'directory'} ; cpio --extract --make-directories --no-absolute-filenames --preserve-modification-time) 2>/dev/null >/dev/null";
再次运行则完成初始化,此时在 /srv/chroot/centos-7
目录下就是完成的操作系统:
total 16K
lrwxrwxrwx 1 root root 7 Jun 24 10:42 bin -> usr/bin
dr-xr-xr-x 1 root root 0 Apr 11 2018 boot
drwxr-xr-x 1 root root 42 Jun 24 10:42 dev
drwxr-xr-x 1 root root 1.9K Jun 24 10:42 etc
drwxr-xr-x 1 root root 0 Apr 11 2018 home
lrwxrwxrwx 1 root root 7 Jun 24 10:42 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Jun 24 10:42 lib64 -> usr/lib64
drwxr-xr-x 1 root root 0 Apr 11 2018 media
drwxr-xr-x 1 root root 0 Apr 11 2018 mnt
drwxr-xr-x 1 root root 0 Apr 11 2018 opt
dr-xr-xr-x 1 root root 0 Apr 11 2018 proc
dr-xr-x--- 1 root root 0 Apr 11 2018 root
drwxr-xr-x 1 root root 72 Jun 24 10:42 run
lrwxrwxrwx 1 root root 8 Jun 24 10:42 sbin -> usr/sbin
drwxr-xr-x 1 root root 0 Apr 11 2018 srv
dr-xr-xr-x 1 root root 0 Apr 11 2018 sys
drwxrwxrwt 1 root root 0 Jun 24 10:42 tmp
drwxr-xr-x 1 root root 106 Jun 24 10:42 usr
drwxr-xr-x 1 root root 160 Jun 24 10:42 var
创建最小化 /dev
项目
CentOS 7已经不再提供 MAKEDEV
脚本,所以需要在 chroot
内部执行以下命令创建需要的设备:
mknod /dev/null c 1 3
chmod 666 /dev/null
mknod /dev/ptmx c 5 2
chmod 666 /dev/ptmx
mkdir /dev/pts
在物理主机和chroot之间共享用户
可以方便地在主机系统和chroot中重用相同用户。对于单一用户,非常方便在 chroot
目录下创建系统用户:
chroot /srv/chroot/centos-7 adduser --no-create-home \
--uid $USER_ID $USER_NAME
举例,我的个人系统只有 /home/huatai
,则执行:
chroot /srv/chroot/centos-7 adduser --no-create-home \
--uid 502 huatai
后面我们会用 bind mount 方式将物理主机目录映射到chroot中
(参考)挂载chroot文件系统
简单来说,至少要挂载 /proc
伪文件系统,很多工具还需要创建伪终端才能工作。通常执行以下命令:
mount -t proc proc /srv/chroot/centos-7/proc
mount -t devpts devpts /srv/chroot/centos-7/dev/pts
mount -o bind /home /srv/chroot/centos-7/home
不过,我的实践发现有些目录已经创建或者缺失,我实际执行命令如下:
mount -t proc proc /srv/chroot/centos-7/proc
mknod /srv/chroot/centos-7/dev/ptmx c 5 2
chmod 666 /srv/chroot/centos-7/dev/ptmx
mkdir /srv/chroot/centos-7/dev/pts
mount -t devpts devpts /srv/chroot/centos-7/dev/pts
mount -o bind /home /srv/chroot/centos-7/home
改进的实际挂载chroot文件系统
我感觉上述步骤太繁琐,所以参考gentoo linux的安装手册完成上述步骤:
chroot_dir=/srv/chroot/centos-7
mount -t proc proc ${chroot_dir}/proc
mount --rbind /sys ${chroot_dir}/sys
mount --make-rslave ${chroot_dir}/sys
mount --rbind /dev ${chroot_dir}/dev
mount --make-rslave ${chroot_dir}/dev
mount -o bind /home ${chroot_dir}/home
备注
后来发现 HPE DL360 BIOS升级 还需要用户账号登陆,所以再添加以下bind,将操作系统的账号密码也映射到chroot环境:
mount -o bind /etc/passwd ${chroot_dir}/etc/passwd
mount -o bind /etc/shadow ${chroot_dir}/etc/shadow
mount -o bind /etc/group ${chroot_dir}/etc/group
当添加了上述 passwd
等文件后, HPE DL360 BIOS升级 过程中通过WEB浏览器访问 Smart Update Manager 管理界面就能够正常使用系统 root
账号登陆
进入chroot:
chroot ${chroot_dir} /bin/bash
source /etc/profile
export PS1="(chroot) $PS1"
此时已经chroot进入了CentOS系统,可以使用 df -h
查看系统:
(chroot) bash-4.2# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
(chroot) bash-4.2# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda2 32G 26G 4.5G 85% /home
tmpfs 95G 0 95G 0% /sys/fs/cgroup
udev 95G 0 95G 0% /dev
tmpfs 95G 12K 95G 1% /dev/shm
验证(通过升级系统)
在chroot的CentOS系统中执行一次升级就可以验证:
yum update
可以验证这是一个完整的可工作的CentOS 7系统。
现在就可以在这个基础上完成 HPE DL360 BIOS升级 ,即通过HP官方提供的 SPP 光盘,一条脚本命令进行升级