我想cryptsetup
在systemd-nspawn
容器内安装一个加密的图像文件。但是,我收到此错误消息:
[root@container ~]# echo $key | cryptsetup -d - open luks.img luks
Cannot initialize device-mapper. Is dm_mod kernel module loaded?
Cannot use device luks, name is invalid or still in use.
Run Code Online (Sandbox Code Playgroud)
该dm_mod
内核模块被加载在主机系统上,虽然事情看起来有点容器内的怪异:
[root@host ~]# grep dm_mod /proc/modules
dm_mod 159744 2 dm_crypt, Live 0xffffffffc12c6000
[root@container ~]# grep dm_mod /proc/modules
dm_mod 159744 2 dm_crypt, Live 0x0000000000000000
Run Code Online (Sandbox Code Playgroud)
strace
表示cryptsetup
无法创建/dev/mapper/control
:
[root@etrial ~]# echo $key | strace cryptsetup -d - open luks.img luks 2>&1 | …
Run Code Online (Sandbox Code Playgroud) 我systemd-nspawn
用来运行几个容器。我可以使用systemctl start systemd-nspawn@foo
. 然而,有时我会从systemd-nspawn -bD foo
. 我找不到任何方法将其发送到后台。如图所示,关闭终端只会杀死容器machinectl list
。我可以这样做吗,如果可以,怎么做?
我理解容器不仅仅是一个进程,但从这个意义上说,预期的效果与后台进程相同 - 我希望容器运行,但我的原始 shell 还给了我。
我正在尝试--privileged
在 systemd 容器中创建一个粗略的 Docker 等价物,但我不知道如何允许容器访问主机上的所有可用设备(无需手动枚举它们)。
我从 systemd-nspawn 容器中遇到了Access usb 设备,并--privileged
在https://github.com/rkt/rkt/issues/2962#issuecomment-235444606看到了一个很好的描述,但我不知道如何将这些位放在一起。
我也尝试了天真,--bind=/dev
但这样就没有标准输出并且容器从未启动。
任何提示如何处理这个?
tl;dr Linux 有命名空间,特别是network namespaces
. 似乎-n
在运行时通过标志创建的命名空间在使用时systemd-nspwawn
没有显示ip netns list
(既不在主机中,也没有在假定创建的命名空间中)。它要么systemd-nspawn
或ip netns
不实际使用Linux的命名空间处理(这是我认为是这样的:https://lwn.net/Articles/531114/#series_index)?
长话短说:
我使用以下命令从我的 Arch Linux 中运行 Arch Linux 的“轻量级容器”:
systemd-nspawn -nbUD /mntpointArchLinuxSysFs
Run Code Online (Sandbox Code Playgroud)
数据/mntpointArchLinuxSysFs
已被引导,并且“运行/启动”良好。man systemd-nspawn告诉我-n
options-flag 意味着:
-n
,--network-veth
veth
在主机和容器之间创建一个虚拟以太网链接(“ ”)。以太网链路的主机端将作为以容器名称(如 指定--machine=
)命名的网络接口可用 ,前缀为“ve-
”。以太网链路的容器端将命名为“host0
”。该--network-veth
选项意味着--private-network
.
反过来,隐含--private-network
的解释如下
--private-network
Run Code Online (Sandbox Code Playgroud)Disconnect networking of the container from the host. This makes all network interfaces unavailable in the container, …
我结合了原始博客文章中的详细说明和手册页中的最新说明(使用 dnf 而不是 yum)。
# sudo dnf -y --releasever=24 --installroot=$HOME/fedora-24 --disablerepo='*' --enablerepo=fedora --enablerepo=updates install systemd passwd dnf fedora-release vim-minimal
# sudo systemd-nspawn -D fedora-24
Spawning container fedora-24 on /home/alan-sysop/fedora-24
Press ^] three times within 1s to kill container.
-bash-4.3# passwd
Changing password for user root.
New password:
Retype new password:
Run Code Online (Sandbox Code Playgroud)
结果:
passwd: Authentication token manipulation error
Run Code Online (Sandbox Code Playgroud)
和 AVC 弹出窗口,即 SELinux 错误。它说passwd
不允许取消链接(替换)/etc/passwd
。“疑难解答”按钮的建议之一是我可以将标签分配passwd_file_t
给/etc/passwd
.
怎么了,我该如何解决?
有没有办法使用类似于debootstrap
Debian/Ubuntu 的方式在 chroot 内创建 Centos 系统?我\xe2\x80\x99d 需要它用于容器项目,其中 Docker 不是解决方案(我\xe2\x80\x99d 使用 systemd 容器)。不幸的是,我\xe2\x80\x99m无法在网络上找到任何相关内容。
感谢您的帮助。
\n最近我开始systemd-nspawn
在我的 Arch 盒子上设置其他操作系统实例。我想做的一件事是检测我是否在容器内,如果是,则将发行版名称 (from lsb_release
) 添加到终端标题。在基于Debian的系统上,默认.bashrc
采用debian_chroot
了类似的目的。如何检测我是否在 nspawn 容器内运行?
我想从容器内部访问特殊的 USB 设备(不是简单的闪存驱动器)。我/dev/bus/usb
在容器内绑定,lsusb
毫不费力地列出 USB:
$ lsusb
...
Bus 002 Device 002: ID 0a89:0009
...
Run Code Online (Sandbox Code Playgroud)
但我的程序无法与此设备交互。
为什么nspawn
比docker
podman
和 甚至慢qemu
?!CPU 任务花费的时间是 docker、podman 或 qemu 中的两倍
这是我所做的基准测试:
首先,我使用以下命令禁用了主机内核(以及 qemu 基准测试中的 qemu 来宾内核)中的所有 spectre/meltdown 缓解措施:
GRUB_CMDLINE_LINUX_DEFAULT=noibrs noibpb nopti nospectre_v2 nospectre_v1 l1tf=off nospec_store_bypass_disable no_stf_barrier mds=off tsx=on tsx_async_abort=off mitigations=off spectre_v2_user=off spec_store_bypass_disable=off nx_huge_pages=off kvm.nx_huge_pages=off kvm-intel.vmentry_l1d_flush=never srbds=off
Run Code Online (Sandbox Code Playgroud)
然后我使用了这个基准测试:
git clone https://github.com/tsuna/contextswitch
cd contextswitch
time make
Run Code Online (Sandbox Code Playgroud)
我nspawn
用超级完整的权限进行了测试:
export SYSTEMD_NSPAWN_USE_CGNS=0
systemd-nspawn --keep-unit --register=no --boot --capability=all --private-users=false --system-call-filter="@default @aio @basic-io @chown @clock @cpu-emulation @debug @file-system @io-event @ipc @keyring @memlock @module @mount @network-io @obsolete @privileged @process @raw-io @reboot @resources …
Run Code Online (Sandbox Code Playgroud) 我有一个包含以下内容的脚本:
sudo machinectl start "$machinename"
sudo systemd-run -PM root@"$machinename" "$command"
Run Code Online (Sandbox Code Playgroud)
Failed to connect to bus: No such file or directory
Failed to start transient service unit: Transport endpoint is not connected
Run Code Online (Sandbox Code Playgroud)
这会失败,因为第一行仅开始启动容器;第二行在容器完成启动之前运行。目前,我有一个解决方案,可以不断轮询容器的状态并阻止直到它准备好:
while [ "$(sudo systemctl show "systemd-nspawn@$machinename" -P StatusText)" != "Container running: Ready." ]
do
true
done
Run Code Online (Sandbox Code Playgroud)
如何等待容器完成启动,而不需要不断轮询容器的状态?
systemd-nspawn ×10
container ×4
containers ×2
docker ×2
namespace ×2
systemd ×2
bind-mount ×1
centos ×1
devices ×1
fedora ×1
iproute ×1
performance ×1
podman ×1
qemu ×1
selinux ×1
usb ×1
users ×1