使用 systemd 用户模式自动启动非特权 lxc 容器

使用 systemd 用户模式自动启动非特权 lxc 容器

在 Ubuntu 14.04 上,我创建了一个可以手动启动和停止的非特权容器。

但我希望它可以随系统一起启动和停止。

我已将以下内容添加到容器的配置中: lxc.start.auto = 1 lxc.start.delay = 5

但是,系统脚本似乎没有选择非特权容器。

一个线程与 linuxcontainers.org 上的此问题相关,但解决方案似乎仅限于root用户。

对于非 root 用户(经 root 用户同意)来说,有没有一种干净的方法可以做到这一点?

答案1

我认为我找到了比这里介绍的解决方案更好的解决方案。部分原因是据我所知 cgmanager 已经死了,部分原因是我的解决方案感觉不像是一个黑客解决方法,但主要是因为在搜索问题解决方案时仍然会出现这个讨论。实际上它非常简单:使用 systemd 用户模式

当然,如果您不使用 systemd,此解决方案将无济于事。在这种情况下,我建议您弄清楚您的 init 系统是否有某种方式允许非特权用户在启动时运行服务,并以此作为起点。

使用 systemd 用户模式自动启动非特权 lxc 容器

我假设您拥有正常运行的非特权 lxc 容器,并且lxc-autostart以容器用户身份运行正常。如果是这样,请执行以下操作:

  1. ~/.config/systemd/user/lxc-autostart.service在拥有 lxc 容器的用户的主目录中创建文件:
[Unit]
Description="Lxc-autostart for lxc user"

[Service]
Type=oneshot
ExecStart=/usr/bin/lxc-autostart
ExecStop=/usr/bin/lxc-autostart -s
RemainAfterExit=1

[Install]
WantedBy=default.target
  1. 然后以该用户身份运行:
systemctl --user enable lxc-autostart

(请注意,该--user选项告诉 systemctl 您正在用户模式下使用它。我通常使用 systemctl 执行的所有操作,如 start、stop、statuc、enable 等,都可以使用 --user 进行。)

  1. 然后运行以下命令,其中$user是拥有 lxc 容器的用户的名称:
sudo loginctl enable-linger $user

这是 systemd 在启动时启动 systemd 用户实例所必需的$user。否则它只会在$user登录时启动一个。

欲了解更多信息,我推荐 archlinux wikisystemd/计时器页面和systemd 手册页

以 root 身份访问用户的 systemd 实例

实际上,您可以以 root 身份启动/停止/执行任何用户的 systemd 服务,但这需要您设置XDG_RUNTIME_DIR环境变量。假设$user 您要访问其实例的用户及其$uiduid,那么您可以这样启动上面定义的 lxc-autostart.service:

sudo -u $user XDG_RUNTIME_DIR=/run/user/$uid systemctl --user start lxc-autostart

您甚至可以使用systemd-run该用户身份运行任意命令,而不会破坏 lxc。我在备份之前/之后使用以下命令来停止/启动我的容器,其中$name是正在备份的 lxc 容器的名称:

sudo -u $user XDG_RUNTIME_DIR=/run/user/$uid systemd-run --user --wait lxc-stop -n $name
sudo -u $user XDG_RUNTIME_DIR=/run/user/$uid systemd-run --user --scope lxc-start -n $name

(请注意,如果没有--waitsystemd-run,则不会阻止,直到容器停止。)

答案2

我建议使用方便的@reboot别名Ubuntu 的 cron跑步lxc-autostart

作为拥有非特权容器的用户,运行crontab -e并添加以下行:

@reboot lxc-autostart

答案3

如果有人偶然发现了这个问答,想知道如何自动启动非特权 LXC 容器(我肯定会经常回来查看这里),这里有一个效果很好的解决方案,我按照这个解决方案在我的服务器上运行:

http://blog.lifebloodnetworks.com/?p=2118作者:Nicholas J Ingrassellino。

简而言之,它涉及创建两个脚本,它们在启动时协同工作,允许 LXC 启动每个列出用户的非特权容器,而无需实际登录用户帐户;换句话说,以用户身份执行命令,所有 CGroups 魔法完好无损。为了遵循 SO 最佳实践,我将在这里引用它的梗概,但值得一读他的原始文章。

允许我们的用户帐户使用桥梁……

echo "$USER veth lxcbr0 1024" | sudo tee -a /etc/lxc/lxc-usernet

创建 Upstart 脚本.../etc/init/lxc-unprivileged.conf另外...

description "LXC Unprivileged Containers"
author "Mike Bernson <[email protected]>"

start on started lxc

script
    USERS="[user]"

    for u in $USERS; do
        cgm create all lxc$u
        cgm chown all lxc$u $(id -u $u) $(id -g $u)
        lxc-autostart -L -P /home/$u/.local/share/lxc | while read line;
        do
            set -- $line
            /usr/local/bin/startunprivlxc lxc$u $u $1
            sleep $2
        done
    done
end script

确保将 [user] 替换为您的用户帐户。

创建容器启动脚本…/usr/local/bin/startunprivlxc 另外…

#!/bin/sh

cgm movepid all $1 $$
sudo -iH -u $2 -- lxc-start -n $3 -d

…并使其可执行…

sudo chmod +x /usr/local/bin/startunprivlxc

我只是想强调它确实看起来可以安全、正确地运行,并且不需要 root 身份通过 SSH 进入其他用户帐户。

这里还有更多关于该主题的内容(涉及相关的陷阱):https://gist.github.com/julianlam/4e2bd91d8dedee21ca6f这有助于理解为什么会出现这种情况。

答案4

抱歉:回答得太早了。尽管 lxc-ls 显示“AUTOSTART”为“YES”,但它不起作用。

这个链接有很多有用的信息,也许有人可以利用它: http://www.geeklee.co.uk/unprivileged-privileged-containers-ubuntu-14-04-lxc/

我之所以访问此页面,是因为我遇到了同样的问题。阅读此帖子后,我意识到如果不使用 sudo 运行,lxc-create 就无法写入通常的“/var/lib/lxc/”目录。

我环顾四周,在“~/.local/share/lxc”中找到了用于我的非特权容器的 rootfs,并将问题中的两行放入该目录中的配置中。

我查看了我使用的模板“lxc-download”以寻找线索,但我认为该路径是在调用“lxc-download”时传入的。我还没有查看系统在启动过程中如何查找非特权容器。

相关内容