推荐一个前几天看到的神奇的项目,takeover.sh,中文可以译为接管
引言
如果想要重装系统或者执行一些硬盘扫描修复之类的操作,一般都要进入到另一个维护环境内进行。
- 如果是本地机器,可以用优盘安装PE系统
- 如果是vps,可以使用救援系统
- 如果是杜甫,可以用IPMI
总之,你没法直接格式化一个正在运行的系统,因为硬盘被各种进程占用并处于忙碌状态。
于是,曾经琢磨过一个问题,有没有可能在系统不重启的前提下,使系统进入一种临时的维护状态,比如在内存加载一个临时系统,并将目前的运行环境切换过去,由新的临时系统来接管当前的系统资源。
如果你想到了这个问题,那么takeover.sh便是这个问题的解答!
看一下takeover.sh的英文介绍:
A script to completely take over a running Linux system remotely, allowing you to log into an in-memory rescue environment, unmount the original root filesystem, and do anything you want, all without rebooting. Replace one distro with another without touching a physical console.
一个脚本,用于完全远程接管正在运行的 Linux 系统,允许您登录内存救援环境,卸载原始根文件系统,并执行任何您想要的操作,所有这些都无需重新启动。 将一个发行版替换为另一个发行版,而无需接触物理控制台。
天呐,这是什么魔法,看了下代码,没有几行,但是很灵活的运用了telinit/chroot/pivot_root/tmpfs等技巧。
怎么使用
那么问题来了,怎么用呢。想要进入这个临时的接管系统中,大概可以分为以下几个步骤:
挂载临时系统
mkdir /takeover
mount -t tmpfs tmpfs /takeover -o size=150M # 你需要的内存盘大小
temp_os_url='https://github.com/LloydAsp/templates/releases/download/v1.0.0/alpine-takeover.tar.gz'
curl -sL $temp_os_url | tar -C /takeover -xz
mv /takeover/takeover/* /takeover
这里我们使用了一个alpine系统作为临时系统,你可以使用任何你想要的系统,比如用debootstrap塞一个debian或者ubuntu进去,只要有对应的文件即可。
准备一些工具并编译fakeinit
apt update; apt-get install -y busybox git build-essential
wget -O /takeover/busybox https://www.busybox.net/downloads/binaries/1.26.2-defconfig-multiarch/busybox-x86_64
chmod a+x /takeover/busybox
git clone https://github.com/marcan/takeover.sh /tmp/takeover.sh/
cp -a /tmp/takeover.sh/* /takeover/
cd /takeover
gcc -static fakeinit.c -o fakeinit
cp usr/bin/passwd bin/
这里编译的fakeinit将用于替换你的默认启动进程(init/systemd)
开始接管
sh takeover.sh
每当takeover询问你是否OK的时候,就输入OK,回车
通过ssh进入到新的临时系统内
新开一个终端,连接到你的ip地址,端口为80,注意不是原来的22端口
ssh -p80 root@your_host
好了,你已就位,随心所欲的折腾
现在你已经进入了临时系统内,你可以为所欲为了,比如格式化任何硬盘,关闭任何(除了fakeinit下属进程外的)任何进程。当然,你也可以在这个环境下手动安装系统,一般的步骤是格式化硬盘,灌入文件、加载内核、修复引导等等。
来看下这个进程图
这里是临时系统内部的进程图,可以看到,根进程已经被替换为fakeinit,新系统的sshd在最下面。原系统内的各种进程仍然在运行,你可以通过按k键,然后选择SIGKILL杀死这些进程,放心这不会使你的临时系统崩溃。
退出
可以使用reboot -f或者echo b > /proc/sysrq-trigger退出
畅想
目前的kvm dd脚本,基本都是重启后进行安装步骤。takeover.sh可以提供一种新的可能,直接在未重启系统的情况下进行安装。我进行了相关的尝试,并证明这个思路完全可行,后面有时间会给出一些实验性的支持脚本。
