在 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
以容器用户身份运行正常。如果是这样,请执行以下操作:
~/.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
- 然后以该用户身份运行:
systemctl --user enable lxc-autostart
(请注意,该--user
选项告诉 systemctl 您正在用户模式下使用它。我通常使用 systemctl 执行的所有操作,如 start、stop、statuc、enable 等,都可以使用 --user 进行。)
- 然后运行以下命令,其中
$user
是拥有 lxc 容器的用户的名称:
sudo loginctl enable-linger $user
这是 systemd 在启动时启动 systemd 用户实例所必需的$user
。否则它只会在$user
登录时启动一个。
欲了解更多信息,我推荐 archlinux wikisystemd/计时器页面和systemd 手册页。
以 root 身份访问用户的 systemd 实例
实际上,您可以以 root 身份启动/停止/执行任何用户的 systemd 服务,但这需要您设置XDG_RUNTIME_DIR
环境变量。假设$user
您要访问其实例的用户及其$uid
uid,那么您可以这样启动上面定义的 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
(请注意,如果没有--wait
systemd-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”时传入的。我还没有查看系统在启动过程中如何查找非特权容器。