您可能知道,默认情况下,当您在基于 Debian 或 Ubuntu 的系统上安装软件包时,如果该软件包包含服务,则该服务通常会在您安装该软件包时自动启用并启动。
这对我来说是个问题。
我发现自己需要管理用于构建 LXC 容器的模板。有几个容器,每个容器对应一个 Debian 或 Ubuntu 版本。(也有基于 Red Hat 的容器,但它们在这里不相关。)
/var/lib/libvirt/filesystems/debian6_template
/var/lib/libvirt/filesystems/debian7_template
/var/lib/libvirt/filesystems/ubuntu1004_template
/var/lib/libvirt/filesystems/ubuntu1204_template
有时我会发现模板缺少包或需要进行其他更改,因此我将 chroot 进入它们以安装包。不幸的是,当我这样做时,我最终运行了几个包服务的副本!
例如,我发现模板没有系统日志守护程序,所以我安装了一个:
for template in /var/lib/libvirt/filesystems/{debian,ubuntu}*_template; do
chroot $template apt-get install rsyslog
done
并立即运行了四个 rsyslog 副本。更不用说两份exim4了。哎呀!
我在某处读到(虽然我现在找不到了)它不应该在 chroot 中运行时启动服务,但这显然不会发生在这里。
一个可能可行的讨厌的黑客要求临时替换实际启动服务的各种命令,例如start-stop-daemon
and initctl
,尽管这比我真正想做的工作要多得多。如果我别无选择,虽然...
这里理想的解决方案是让基于 Debian 的系统停止做这种废话,但如果做不到这一点,可能是一个晦涩的或未记录的命令行选项apt-get
?
如果不清楚,如果可能的话,我真的想保留与管理模板之外的模板相关的任何内容。
对于 debian,您可以使用policy-rc.d执行此操作。这是一种解释:
由于您不希望任何服务启动,因此您的 policy-rc.d 脚本可以很简单
这是 pbuilder 和 Docker 的mkimage-debootstrap等工具使用的技术。
不幸的是,这种技术不适用于 Ubuntu chroots。与 upstart init 系统集成的软件包在安装过程中调用 /usr/sbin/initctl 而不是 invoke-rc.d,并且 initctl 不咨询 policy-rc.d。根据 upstart 的作者的说法,解决方法是将 /sbin/initctl 替换为 chroot 中 /bin/true 的符号链接。您也可以在 mkimage-debootstrap 中看到这一点,他们可以
你可以做:
我没有用 chroot 测试过它,但它应该可以工作。起初它设置了 RUNLEVEL 环境变量,所以 apt-get 启动的进程不会启动任何服务,因为它们会“认为”系统在单模式下运行。由于修改环境的方式可能会影响未来的命令,当不再需要修改的环境时,需要退出 shell,这是通过最后的exit命令完成的。可能有一些(罕见的?)软件包无法在单一模式下正确安装(但 AFAIK 在大多数情况下这应该不是问题)。