Linux 内核崩溃的时候会将当前内存的一些信息保存到硬盘方便调试并重启,而内核内核崩溃了是谁存储到信息呢?答案是另一个内核
Linux 通过 kdump 服务在自身崩溃的时候拉起自己的一个“分身”,通过特定内核参数让“分身”收集日志。
这背后的技术就是 kexec
由于 kexec 切换内核会跳过 bios 自检等环节,大大缩短重启时间( x86 物理机开机约 5-10 分钟)
很自然的就想到,可不可以用 kexec 技术重装系统?
之所以 k 搞这么复杂,一来是因为特殊场景,二来是提高一种 k 思路和可能性。少量机器推荐通过 u 盘安装
pxe+bootOS+kexec+官方镜像
描述的比较粗略,实际每个步骤都可以写一篇教程,当然网上也都可以搜到
跟 pxe 相比可能不支持 Linux 外的一些系统,比如 esxi
不知道 bootOS 这种称呼对不对
不知道会不会有什么坑。理论上 Linux 都支持 bootOS 做一次就能满足所有 Linux 官方镜像
不知道大家批量装机,并且时不时重装等场景是怎么做到怎么做的。
1
huahsiung 2023-05-19 21:18:27 +08:00
我做过差不多的事情,发现可以通过注入 /sbin/init 程序(现在差不多是 systemd )实现在不改变内核的版本下快速切换系统(类似 openvz 模板),准备多个模板,可以快速切换系统。我现在就在用呢。我编写了一个软件叫“init 截胡”。
后来发现也可以劫持 initrd.img 实现,这个可以实现不改变 mbr 启动项的情况下,启动其他系统,同时不会破坏原有硬盘数据,这个可以在有强制要求启动签名的 vps 上实现“软 dd” [initrd.img 把真正的根 /dev/sda1 挂载到 /root ,然后 chroot /root 启动 /sbin/init ,你可以逆向最后一段 exec run-init ${drop_caps} "${rootmnt}" "${init}" "$@" <"${rootmnt}/dev/console" >"${rootmnt}/dev/console" 2>&1 ] 劫持 iinitrd.img ,如果把根挂载到其他地方,或者挂载其他根,就可以实现“截胡”,启动其他系统。 这个我做出来了,程序也写出来了,在我的服务器上面用,所以可以确定这个方法可行。 kexec ???你可以写个程序验证一下 在不切换内核,实现“init 截胡”切换系统,这个我已经验证过了,就是要额外处理一下 kmod 而已。 |
2
huahsiung 2023-05-19 21:41:12 +08:00
@huahsiung 我实现“init 截胡”遇到的坑就是不同的系统(模板)会加载不同的 kmod ,在却换系统的时候,“init 截胡”要实现卸载上一个系统的 kmod 。不然只能启动第一个系统,启动第二个的时候就会卡死。
我的方法是写了一个守护程序,但是不知道为什么污染了 /dev/pts ,导致控制台输入没有回显,原因未知,可能是我程序问题。反正我是在服务器上用 ssh,不用控制台,这个 bug 没有影响就没有修复 |
3
leonshaw 2023-05-19 21:49:40 +08:00
相当于把 linux 当 boot loader 用,区别就是加载的物理地址受限制,然后有的硬件或者驱动可能初始化状态不对?
@huahsiung 看一下 switch_root 或者 pivot_root ,man 里有一些对 console 的处理。实际上从 initramfs 切换到最终 root 就是这样做的。 |
4
WuSiYu 2023-05-19 23:28:17 +08:00
kexec 挺有意思的用法,不过服务器不能直接用 bmc 装系统吗?按说和物理上机操作是一样的,就是通过网络挂 iso 比较慢
|
5
nuk 2023-05-20 00:43:16 +08:00
前几年试过 UEFI 直接 tftp 加载 kernel 和 ramfs 作为 rootfs (加载速度非常快),个人感觉 ipxe 完全可以定制化引导,安装成功后不再提供引导项,不管是 DHCP 选项,还是 tftp 文件,都可以和 MAC 地址和 IP 地址绑定。kexec 限制蛮多的,相比 ipxe 来说是锯了大腿了。
|
6
ysc3839 2023-05-20 01:15:30 +08:00 via Android
一般来说服务器为了求稳还是建议跑一遍自检从头开始启动内核的,kexec 可能影响稳定性。
|
7
bt7vip 2023-05-20 06:17:43 +08:00 via Android
@ysc3839 忘了在哪里看到的了,大致是既然 Linux 内核崩溃会自动进入另一个可以确保可以进系统的内核,那为什么不始终用那个可以进系统的那个呢。
答:只是确保能进,其他的都做最保守的策略,直接用哪个内核跑很多东西用不了或者性能低。差不多就是像 Windows 的安全模式一样,只加载启动,很多驱动都不加载。 |
10
zhlxsh OP @nuk ipxe.efi 确实能做很多事情,甚至本身就是一个操作系统了,在我说的这种场景下,(先组 raid ,然后用官方镜像装系统)。不用 kexec 会遇到一个问题,就是没有很好的办法区分两次进 pxe ,需要返回的内核文件…
你说的 mac 地址和 IP 绑定,然后返回不同 boot.scripts 区分应该可以,这样的话批量安装要改造 dhcp ?或者写脚本动态删减 dhcp 的配置? 组 raid 和升级固件的操作肯定是不能放进 uefi 和 ipxe 里面的。或者改造过于复杂,。。 这块能详细说一下怎么实现吗:个人感觉 ipxe 完全可以定制化引导,安装成功后不再提供引导项 |
11
tywtyw2002 2023-05-20 12:40:05 +08:00 via iPhone
nixos 目前就已经支持用 ipxe 和 kexec 去装。
我远程装,很多时候都是用 debian img 然后 kexec 了 |
12
huahsiung 2023-05-20 16:49:14 +08:00
@leonshaw 发现"init 截胡"出 bug 了,无法创建 user namespace 。今天使用 docker 时候发现的。
之后调试发现使用 clone()的 CLONE_NEWUSER 的时候返回-1 ,而其他 CLONE_NEWNS,CLONE_NEWPID 等等都没有问题。 疑似 kmod 没有切除处理干净导致??? 使用 unshare 验证 unshare -m bash ,unshare -p xxx ,unshare -n ,unshare -i 等等都正常,只有 unshare -U,提示`unshare: unshare failed: Operation not permitted` 原因未知???。 看来奇淫技巧还是要付出一些代价 |
13
nuk 2023-05-20 18:24:28 +08:00
@zhlxsh 是的,要改造 dhcp 和 tftp ,安装完了之后就删除 DHCP option ,最好是写一个自己的 tftp 服务器,比如一个文件对不同 IP 第一次下载和第二次下载返回不同的文件,tftp 本身就能做很多事情了
|
16
leonshaw 2023-05-21 10:46:45 +08:00
@huahsiung
man 2 unshare: ERRORS EPERM (since Linux 3.9) CLONE_NEWUSER was specified in flags and the caller is in a chroot environment (i.e., the caller's root directory does not match the root directory of the mount namespace in which it resides). |