我试图启动一个 LXC 容器,然后在其中运行命令。问题是,即使容器处于 RUNNING 状态,它也没有完成所有启动。这会导致 /tmp 出现问题(我猜还有其他初始化问题)。
可以通过以下调用序列来说明,该序列创建一个容器,启动它,等待其运行状态并执行一些命令;这些命令创建一个文件 /tmp/hello,显示一个目录,等待一会儿然后再次显示该目录:
lxc-clone -B overlayfs -s -o vm -n c1 ; lxc-start -n c1 ; lxc-wait -n c1 -s RUNNING ; lxc-attach -n c1 -- su -c "touch /tmp/hello; ls -la /tmp; sleep 5; ls -la /tmp" slave ; lxc-stop -n c1 ; lxc-destroy -n c1
其输出是
Created container c1 as snapshot of vm total 16 drwxrwxrwt 1 root root 4096 May 24 09:37 . drwxr-xr-x 1 root nogroup 4096 May 24 09:37 .. drwxrwxrwt 2 root root 4096 May 22 21:19 .ICE-unix drwxrwxrwt 2 root root 4096 May 22 21:19 .X11-unix -rw-rw-r-- 1 slave slave 0 May 24 09:37 hello total 16 drwxrwxrwt 1 root root 4096 May 24 09:37 . drwxr-xr-x 1 root nogroup 4096 May 24 09:37 .. drwxrwxrwt 2 root root 4096 May 24 09:37 .ICE-unix drwxrwxrwt 2 root root 4096 May 24 09:37 .X11-unix
并显示文件 /tmp/hello 已被某些初始化脚本删除。
如何在容器内等待系统完全启动?此外,如何从容器外部执行此操作?
答案1
对于在 systemd 上运行的容器,这似乎效果很好:
lxc-attach -n [CONTAINER NAME] -- systemctl isolate multi-user.target
sysvinit
您可能可以对或基于容器应用相同的逻辑upstart
(运行一个阻塞的命令直到达到运行级别),但我无法告诉您哪些命令可以做到这一点。
答案2
就我而言,当 LXC 容器具有网络连接时,我认为它已“准备就绪”(例如,诸如此类的命令apt update
将在 LXC 容器设置脚本中运行)。
在 Debian 11 bullseye 作为 lxc 主机上,使用 Debian 11 bullseye lxc 容器,我成功利用了以下模式:
lxc-unpriv-start -n "$LXC_CONTAINER"
lxc-wait -n "$LXC_CONTAINER" -s RUNNING
# the lxc-wait RUNNING state is not that useful;
# a container is already considered RUNNING even though the network is not yet up
# the following command blocks until the container's network is up
lxc-unpriv-attach -n "$LXC_CONTAINER" -- systemctl start systemd-networkd-wait-online.service
# when the script reaches this part, the lxc container's network probably is completely up and running
lxc-unpriv-attach -n "$LXC_CONTAINER" -- apt update
# ...
相关systemctl start systemd-networkd-wait-online.service
部分是:
systemd-networkd-wait-online.service
是开箱即用的 systemd 服务,只需要network-online.target
(至少我是这样理解的)。
因此执行systemctl start systemd-networkd-wait-online.service
块直到网络启动为止。