总结:如何通过machinectl/nspawn容器向主机暴露网络服务?
我正在尝试使我的设置完美,即在单独的chroot實例。
要启动它们,我需要遵守 SystemD 管理systemd-nspawn
:machinectl
# debootstrap stretch /var/lib/machines/mymachine
# machinectl start mymachine # works well!
# machinectl shell root@mymachine bash
然后我apache2
在上面安装了假人:
(jail)# apt install -y apache2 && systemctl enable apache2 && systemctl start apache2
(jail)# ss -tnlp | grep 80 # yields apache2 running.
但是,80 端口(甚至任何主机监听时看不到任何端口(例如 8080)。如何让它工作?
谢谢团队,
答案1
你需要一个nspawn公开端口的机器的文件。
[网络] 部分选项
Port= 在主机上公开容器的 TCP 或 UDP 端口。此选项对应于 --port= 命令行开关,请参阅 systemd-nspawn(1) 了解此选项所采用的参数的精确语法。此选项具有特权(见上文)。
来自 systemd-nspawn(1):
-p, --port= 如果启用了私有网络,则将主机上的 IP 端口映射到容器上的 IP 端口。采用协议说明符(“tcp”或“udp”),用冒号与范围在 1 到 65535 之间的主机端口号分隔,用冒号与范围在 1 到 65535 之间的容器端口号分隔。协议说明符及其分隔冒号可以省略,在这种情况下假定为“tcp”。容器端口号及其冒号可以省略,在这种情况下暗示与主机端口相同的端口。此选项仅在使用私有网络时才受支持,例如 --network-veth、--network-zone= --network-bridge=。
这[电子邮件保护]单元用途--network-veth
所以就像
[Network]
Port=80
应该管用。
答案2
我只是systemd-nspawn
在没有任何网络标志的情况下运行,它使用主机网络 - 然后使用 nginx 路由我的 Web 应用程序的端口。
在这种情况下$MACHINE_NAME
假设:webapp
systemd-nspawn -D /var/lib/machines/webapp -M webapp --chdir=/ ./entrypoint &
-D
是文件系统根目录,-M
是机器名称,--chdir
更改容器内的目录并./entrypoint
是我想要运行的脚本(可以是任何命令、脚本等)&
在后台运行它(这样您就可以在运行命令的特定tty中执行其他操作)。
该entrypoint
脚本最初来自导出此文件系统的 podman 容器。它的作用如下(非常简单):
#!/usr/bin/env bash
cd /home/localuser/webapp
npm run start
因此,这只是运行我在容器内开发的 Web 应用程序。它被指定在端口上运行3000
。
然后,设置 nginx 来代理80
,3000
它在防火墙中有一个开放的端口:
# cat /etc/nginx/sites-available/webapp
server {
listen 80;
server_name webapp.xyz;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:3000";
}
}
systemd-nspawn
你可以看到它正在使用环回设备 - 但在运行时,任何主机网络在容器内都可用没有 --boot
, 和没有 --network-{bridge,interface,ipvlan,macvlan,veth}
chroot
。跟这个方式很相似。
然后,一旦systemd-nspawn
运行(在后台,因为&
位于命令末尾),就可以运行:
machinectl enable $MACHINE_NAME
它将根据.nspawn
模板生成一个带有机器名称的符号链接。
.nspawn
模板在这里:/lib/systemd/system/[email protected]
$MACHINE_NAME.nspawn
链接将添加到此处:/etc/systemd/system/machines.target.wants/systemd-nspawn@$MACHINE_NAME.service
如果您希望默认使用主机网络运行新机器,只需备份原始机器并删除一些运行时参数:
/* backup original unit file */
# mv /lib/systemd/system/[email protected] \
/lib/systemd/system/[email protected]
/* echo a more simple file into its place */
# echo '[Unit]
Description=Container %i
Documentation=man:systemd-nspawn(1)
[email protected]
PartOf=machines.target
Before=machines.target
After=systemd-resolved.service [email protected]
RequiresMountsFor=/var/lib/machines/%i
[Service]
ExecStart=systemd-nspawn --quiet --keep-unit --link-journal=try-host --machine=%i --chdir=/ ./entrypoint
KillMode=mixed
Type=notify
RestartForceExitStatus=133
SuccessExitStatus=133
Slice=machine.slice
Delegate=yes
TasksMax=16384
WatchdogSec=3min
DeviceAllow=char-pts rw
DeviceAllow=/dev/loop-control rw
DeviceAllow=block-loop rw
DeviceAllow=block-blkext rw
# these two only nec. for LUKS - can remove
DeviceAllow=/dev/mapper/control rw
DeviceAllow=block-device-mapper rw
[Install]
WantedBy=machines.target' > /lib/systemd/system/[email protected]
您可以看到,在这里,在单元文件内运行的命令基本相同,我只是添加了标志--link-journal=try-host
,它将日志放置在/var/log/journal/$MACHINE_UUID
用于监控容器的位置。
因为这是一个模板,它假定我将调用一个entrypoint
从每个容器的根目录命名的脚本,这为它们提供了更多的“命令调用容器”行为(例如 Docker 风格而不是 LXC 风格)。
问题说明:
我想使用--user
标志,但它似乎无法使用 ATM。有一些在这里讨论回归关于标志,但它与 CentOS 上的 v237 有关,因此不确定它是否与 Ubuntu 20.04 上的 241 有关,我现在正在使用 Ubuntu 20.04。无论如何,容器现在将使用 root UID 运行...
systemd-networkd
应该与--network-veth
在上创建 DHCP 主机host0
和客户端ve-$MACHINE_NAME
(限制 16 个字符)一起使用 -如果主机和客户端都使用systemd-networkd
。但是,在 Ubuntu 20.04 上,我无法让它正常工作。我猜我的 systemd 版本中存在与此功能相关的错误,我将在以后的版本中进行进一步测试。
环境信息:
# cat /etc/os-release && systemd --version
NAME="Ubuntu"
VERSION="20.04.2 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.2 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
systemd 245 (245.4-4ubuntu3.6)
+PAM +AUDIT +SELINUX +IMA +APPARMOR +SMACK +SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT +GNUTLS +ACL +XZ +LZ4 +SECCOMP +BLKID +ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=hybrid
进一步阅读: