在前面, 我们已经使用 debootstrap 构建基于Ubuntu的内存OS, 但是业界常用的更多的是CentOS,所以一直在尝试使用CentOS来构建内存OS.
CentOS 7 root filesystem on tmpfs这篇文章中的方案可行, 我们不使用的原因是流程构建太长, 外部依赖太多,冗余的内容太多,也不够精简.
所以我们希望尝试的方案是类似 Ubuntudebootstrap 的工具. yum 本身是可以将对应包安装到指定目录,直到看到下面这篇日本同行写的文章,让这个过程更加清晰了.

宿主环境中,我们需要有 yum rpm 等工具命令的支持,在各个发行版中均可以安装这两个包, 当然宿主机器本身就是CentOS那就不需要在独立安装了.

  • ubuntu
apt -y install yum
  • gentoo
USE="python lua" emerge yum rpm

定位 centos-release 包在远程仓库中的位置, 我们这里使用 CentOS 7, 架构选择 x86_64, 镜像源地址我们选择清华大学的公开镜像站, 如果更好的选择也可以选择其他镜像站, 比如网易的 <mirrors.163.com>.

https://mirrors.tuna.tsinghua.edu.cn/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm

接下来准备下工作根目录, 我这里选择 $HOME/work/chroot 作为我们的工作环境

mkdir -p $HOME/work/chroot/var/lib/rpm

初始化rpm的工作环境以及目标系统安装 centos-release

rpm --root $HOME/work/chroot/ --initdb
rpm -ivh --nodeps --root $HOME/work/chroot/ https://mirrors.tuna.tsinghua.edu.cn/centos/7/os/x86_64/Packages/centos-release-7-6.1810.2.el7.centos.x86_64.rpm

目标系统安装yum工具

yum --nogpgcheck --installroot $HOME/work/chroot -y install yum

日本同行在介绍的过程中, 在这里忽略了一个细节, 需要将宿主环境的 /dev 绑定到目标系统的 /dev 目录下

mount -o bind /dev $HOME/work/chroot/dev

如果不执行上述绑定,将导致chroot后无法执行yum命令, 错误提示信息如下:

error: Failed to initialize NSS library
There was a problem importing one of the Python modules
required to run yum. The error leading to this problem was:

   cannot import name ts

Please install a package which provides this module, or
verify that the module is installed correctly.

It's possible that the above module doesn't match the
current version of Python, which is:
2.7.5 (default, Jun 20 2019, 20:27:34)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]

If you cannot solve this problem yourself, please go to
the yum faq at:
  http://yum.baseurl.org/wiki/Faq

紧接着安装内核:

yum --nogpgcheck --installroot $HOME/work/chroot -y install kernel

安装必要的工具集:

yum --nogpgcheck --installroot $HOME/work/chroot -y install @core

在真正chroot到目标目录之前,我们还需要配置下目标系统的 DNS 信息, 直接将宿主环境的 /etc/resolv.conf 文件拷贝到 $HOME/work/chroot/etc/

cp /etc/resolv.conf $HOME/work/chroot/etc/

到这里,我们就可以直接切换到目标系统中工作啦

chroot $HOME/work/chroot

紧接着执行一次 yum 验证下环境执行是否成功?

(virtualenv) root@server:/# yum                  
Loaded plugins: fastestmirror           
You need to give some command                                              
Usage: yum [options] COMMAND                                                
                                   
List of Commands:                                         
                          
check          Check for problems in the rpmdb                      
check-update   Check for available package updates
clean          Remove cached data
deplist        List a package's dependencies                            
distribution-synchronization Synchronize installed packages to the latest available versions
downgrade      downgrade a package         
erase          Remove a package or packages from your system
fs             Acts on the filesystem data of the host, mainly for removing docs/lanuages for minimal hosts.
fssnapshot     Creates filesystem snapshots, or lists/deletes current snapshots.
groups         Display, or use, the groups information
help           Display a helpful usage message
history        Display, or use, the transaction history       
info           Display details about a package or group of packages
install        Install a package or packages on your system
list           List a package or groups of packages                          
load-transaction load a saved transaction from filename
makecache      Generate the metadata cache                                
provides       Find what package provides the given value    
reinstall      reinstall a package                                  
repo-pkgs      Treat a repo. as a group of packages, so we can install/remove all of them
repolist       Display the configured software repositories
search         Search package details for the given string                   
shell          Run an interactive yum shell
swap           Simple way to swap packages, instead of using shell     
update         Update a package or packages on your system
update-minimal Works like upgrade, but goes to the 'newest' package match which fixes a problem that affects your system
updateinfo     Acts on repository update information
upgrade        Update packages taking obsoletes into account
version        Display a version for the machine and/or available repos.

我们在任何其他操作前需要将系统整体更新到最新, 执行 yum -y update.

yum -y update

激活系统环境信息

source /etc/profile

基础系统初始化完成之后,清理一下不必要的数据文件

yum clean all

到此, 我们目标系统的根盘内容就构建完成了,删掉之前配置的 /etc/resolv.conf 文件, 剩下的内容就和之前构建基于 Ubuntu 的内存镜像的操作流程一样, 退出 chroot 环境.

根盘文件系统好了之后, 需要将其压缩打包:

cd ~/work/chroot
time tar -cf - . | xz -v --threads=24 > ~/work/initramfs/rootfs.tar.xz

接下来我们需要下载 busybox 来作为执行环境, 减少 init 脚本的编写成本

wget -O ~/work/initramfs/bin/busybox https://busybox.net/downloads/binaries/1.21.1/busybox-x86_64

编写 init 文件内容(这里可以可以参考各个发行版本的 iso 中的 init 工具的编写方式, 大同小异)

vim ~/work/initramfs/init

~/work/initramfs/init文件的内容如下:

#!/bin/busybox sh

# Dump to sh if something fails
error() {
    echo "Jumping into the shell..."
    setsid cttyhack sh
}

# Populate /bin with binaries from busybox
/bin/busybox --install /bin

mkdir -p /proc
mount -t proc proc /proc

mkdir -p /sys
mount -t sysfs sysfs /sys

mkdir -p /sys/dev
mkdir -p /var/run
mkdir -p /dev

mkdir -p /dev/pts
mount -t devpts devpts /dev/pts

# Populate /dev
echo /bin/mdev > /proc/sys/kernel/hotplug
mdev -s

echo "mount rootfs... "
mkdir -p /newroot
mount -t tmpfs -o size=80% tmpfs /newroot || error

xz -d -c -f rootfs.tar.xz | tar -x -f - -C /newroot || error

mount --move /sys /newroot/sys
mount --move /proc /newroot/proc
mount --move /dev /newroot/dev

exec switch_root /newroot /sbin/init || error

到此整个 initramfs 的内容,我们就构建完成了.最终需要输出为cpio文档格式.

cd ~/work/initramfs
find . -print0 | cpio --null -ov --format=newc | gzip -9 > ~/work/build/initramfs.gz

最终生成的 initramfs 文件为 ~/work/build/initramfs.gz, 将其拷贝到 PXE Server 的 /var/lib/tftpboot/ubuntu-installer/amd64/, 接下来你就可以去我们的 PXE 环境调试下, 将 PXE Server 的 `/var/lib/tftpboot/ubuntu-installer/amd64/boot-screens/txt.cfg 中的内容调整为如下:

default install
label install
  menu label ^Automatically Install Ubuntu 16.04
  kernel ubuntu-installer/amd64/linux
  append vga=788 initrd=ubuntu-installer/amd64/initramfs.gz

然后启动一下 PXE Client 虚拟机, 看看是否启动了一个完整的 OS.

【腾讯云】境外1核2G服务器低至2折,半价续费券限量免费领取!
https://cloud.tencent.com/act/cps/redirect?redirect=1068&cps_key=e4b50f6c64a4480367f8a8d16fd07c5a&from=console

标签: kernel, initramfs, chroot, init, ramos, debootstrap, yum, root, centos-release, busybox, cpio

添加新评论