如何使用systemd-nspawn进行Linux系统恢复

02/02 07:41
阅读数 254

systemd linux_如何使用systemd-nspawn进行Linux系统恢复

systemd linux

只要存在GNU / Linux系统,系统管理员就需要从根文件系统损坏,意外的配置更改或其他阻止系统启动到“正常”状态的情况中恢复。 

Linux发行版通常在启动时提供一个或多个菜单选项(例如,在GRUB菜单中),这些菜单选项可用于营救损坏的系统。 通常,他们在禁用大多数系统服务的情况下将系统引导到单用户模式。 在最坏的情况下,用户可以修改引导加载程序中的内核命令行,以将标准外壳用作初始化(PID 1)进程。 这种方法最复杂,并且充满了复杂性,在需要抢救系统时可能会导致挫败感和浪费时间。 

当另一个系统(具有相同体系结构和通常相似的配置)可用时,简化修复过程的常用技术是从损坏的系统中提取存储设备,并将它们作为辅助设备连接到工作系统。 对于物理系统,这通常很简单,但是大多数云计算平台也可以支持此操作,因为它们允许将损坏实例的根存储卷安装到另一个实例上。 

将根文件系统附加到另一个系统后,使用fsck和其他工具即可轻松解决文件系统损坏。 解决配置错误,损坏的程序包或其他问题可能会更加复杂,因为它们需要挂载文件系统以及查找和更改正确的配置文件或数据库。 

使用systemd

systemd之前,使用文本编辑器编辑配置文件是纠正配置的实用方法。 找到必要的文件并了解其内容可能是一个单独的挑战,这超出了本文的范围。 

但是,当GNU / Linux系统使用systemd时 ,最好使用它提供的工具来进行许多配置更改-例如,启用和禁用服务需要在各个位置创建或删除符号链接。 systemctl工具用于进行这些更改,但使用它需要运行一个systemd实例并正在(在D-Bus上)侦听请求。 当根文件系统作为附加文件系统挂载到另一台计算机上时,不能使用运行中的systemd实例进行这些更改。 

手动启动目标系统的systemd也不可行,因为它被设计为系统上的PID 1进程并管理所有其他进程,这将与用于修复的系统上已经在运行的实例冲突。 

幸运的是, systemd能够启动容器,具有自己的PID 1的完全封装的GNU / Linux系统以及利用Linux内核提供的各种名称空间功能的环境。 与Docker和Rocket这样的工具不同, systemd不需要容器映像来启动容器。 它可以启动一个植根于现有文件系统中任何位置的文件。 这是使用systemd-nspawn工具完成的,该工具将创建必要的系统名称空间并在容器中启动初始过程,然后在容器中提供控制台。 与chroot (仅更改文件系统的表观根目录)相反,此类型的容器将具有单独的文件系统名称空间,在/ dev , / run/ proc上安装的合适文件系统,以及单独的进程名称空间和IPC名称空间。 请查阅systemd-nspawn 手册页以了解有关其功能的更多信息。 

展示其工作原理的示例

在此示例中,包含损坏的系统根文件系统的存储设备已连接到正在运行的系统,在该系统中显示为/ dev / vdc 。 设备名称将根据现有存储设备的数量,设备的类型以及用于将其连接到系统的方法而有所不同。 根文件系统可以使用整个存储设备,也可以使用该设备内的分区。 由于最常见(简单)的配置将根文件系统放置在设备的第一个分区中,因此本示例将使用/ dev / vdc1。 确保使用系统的正确设备名称替换以下命令中的设备名称。

损坏的根文件系统也可能比设备上的单个文件系统更为复杂。 它可以是LVM卷集中的一个卷,也可以是组合到软件RAID设备中的一组设备上的卷。 在这些情况下,必须执行组成和激活保存文件系统的逻辑设备的必要步骤,然后才能将其安装。 同样,这些步骤超出了本文的范围。 

先决条件

首先,请确保已安装systemd-nspawn工具-大多数GNU / Linux发行版默认都不安装它。 大多数发行版中的systemd-container软件包都提供了该软件包,因此请使用发行版的软件包管理器来安装该软件包。 本示例中的指令已使用Debian 9进行了测试,但在任何现代GNU / Linux发行版中均应类似地工作。 

使用下面的命令几乎肯定会需要root权限,因此您要么需要以root身份登录,要么使用sudo获得具有root权限的shell,要么为每个命令加上sudo前缀。 

验证并安装文件系统

首先,使用fsck验证目标文件系统的结构和内容: 

 $ fsck /dev/vdc1 

如果发现文件系统有任何问题,请适当回答问题以更正它们。 如果文件系统已充分损坏,则可能无法修复,在这种情况下,您将不得不寻找其他方法来提取其内容。 

现在,创建一个临时目录并将目标文件系统挂载到该目录: 

 
   
    
$ mkdir /tmp/target-rescue
     
$ mount /dev/vdc1 /tmp/target-rescue
    
   

挂载文件系统后,启动一个以该文件系统为根文件系统的容器: 

 $ systemd-nspawn --directory /tmp/target-rescue --boot -- --unit rescue.target 

用于启动容器的命令行参数为: 

  • --directory / tmp / target-rescue提供容器的根文件系统的路径。 
  • --boot在容器的根文件系统中搜索合适的init程序并启动它,并将参数从命令行传递给它。 在此示例中,目标系统还使用systemd作为其PID 1进程,因此其余参数将用于该进程。 如果要修复的目标系统使用任何其他工具作为其PID 1进程,则需要相应地调整参数。 
  • -systemd-nspawn的参数与容器的PID 1进程的参数分开。 
  • --unit rescue.target告诉容器中的systemd在引导过程中应尝试到达的目标名称。 为了简化目标系统中的救援操作,请将其引导到“救援”模式,而不是正常的多用户模式。 

如果一切顺利,您应该会看到类似以下的输出: 

 
   
    
     Spawning container target-rescue on /tmp/target-rescue.
     
Press ^] three times within 1s to kill container.
     
systemd 232 running in system mode. (+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN)
     
Detected virtualization systemd-nspawn.
     
Detected architecture arm.
     
 
     
Welcome to Debian GNU/Linux 9 (Stretch)!
     
 
     
Set hostname to <test>.
     
Failed to install release agent, ignoring: No such file or directory
     
[  OK  ] Reached target Swap.
     
[  OK  ] Listening on Journal Socket (/dev/log).
     
[  OK  ] Started Dispatch Password Requests to Console Directory Watch.
     
[  OK  ] Reached target Encrypted Volumes.
     
[  OK  ] Created slice System Slice.
     
         Mounting POSIX Message Queue File System...
     
[  OK  ] Listening on Journal Socket.
     
         Starting Set the console keyboard layout...
     
         Starting Restore / save the current clock...
     
         Starting Journal Service...
     
         Starting Remount Root and Kernel File Systems...
     
[  OK  ] Mounted POSIX Message Queue File System.
     
[  OK  ] Started Journal Service.
     
[  OK  ] Started Remount Root and Kernel File Systems.
     
         Starting Flush Journal to Persistent Storage...
     
[  OK  ] Started Restore / save the current clock.
     
[  OK  ] Started Flush Journal to Persistent Storage.
     
[  OK  ] Started Set the console keyboard layout.
     
[  OK  ] Reached target Local File Systems (Pre).
     
[  OK  ] Reached target Local File Systems.
     
         Starting Create Volatile Files and Directories...
     
[  OK  ] Started Create Volatile Files and Directories.
     
[  OK  ] Reached target System Time Synchronized.
     
         Starting Update UTMP about System Boot/Shutdown...
     
[  OK  ] Started Update UTMP about System Boot/Shutdown.
     
[  OK  ] Reached target System Initialization.
     
[  OK  ] Started Rescue Shell.
     
[  OK  ] Reached target Rescue Mode.
     
         Starting Update UTMP about System Runlevel Changes...
     
[  OK  ] Started Update UTMP about System Runlevel Changes.
     
You are in rescue mode. After logging in, type "journalctl -xb" to view
     
system logs, "systemctl reboot" to reboot, "systemctl default" or ^D to
     
boot into default mode.
     
Give root password for maintenance
     
(or press Control-D to continue):
    
   

  1. 在此输出中,您可以看到systemd作为容器中的init进程启动,并检测到它正在容器中运行,因此可以适当地调整其行为。 启动各种单位文件以使容器处于可用状态,然后请求目标系统的根密码。 如果要具有root权限的shell提示符,可以在此处输入root密码,也可以按Ctrl + D允许启动过程继续,这将显示正常的控制台登录提示符。 

完成对目标系统的必要更改后,快速连续按三下Ctrl +] 。 这将终止容器并使您返回原始外壳。 从那里,您可以通过卸载目标系统的文件系统并删除临时目录来进行清理: 

 
   
    
$ umount /tmp/target-rescue
     
$ rmdir /tmp/target-rescue
    
   

而已! 现在,您可以删除目标系统的存储设备,并将它们返回到目标系统。 

以这种方式使用systemd-nspawn的想法,尤其是--boot参数 ,来自于StackExchange上发布的一个问题 。 感谢Shibumi和kirbyfan64sos为这个问题提供了有用的答案!

翻译自: https://opensource.com/article/18/11/systemd-nspawn-system-recovery

 

展开阅读全文
打赏
0
0 收藏
分享
加载中
更多评论
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部