TL;DR:如何通过 machinectl/nspawn 容器向主机公开网络服务?
我正在努力使事情变得完美适合我的设置,即将我的服务安装在单独的chroot实例中。
systemd-nspawn
要启动它们,我想使用and遵守 SystemD 管理machinectl
:
# debootstrap stretch /var/lib/machines/mymachine
# machinectl start mymachine # works well!
# machinectl shell root@mymachine bash
然后我在上面安装 dummy apache2
:
(jail)# apt install -y apache2 && systemctl enable apache2 && systemctl start apache2
(jail)# ss -tnlp | grep 80 # yields apache2 running.
但是,在主机上侦听时,80 端口(甚至任何端口,例如 8080)都不可见。如何使它工作?
谢谢团队,
您需要一个用于公开端口的机器的nspawn文件。
从 systemd-nspawn(1):
systemd- nspawn @.service 单元使用
--network-veth
所以像
应该管用。
我只是在
systemd-nspawn
没有任何网络标志的情况下运行,它使用主机网络 - 然后使用 nginx 路由我的网络应用程序的端口。假设
$MACHINE_NAME
在webapp
这种情况下:-D
是文件系统根目录,-M
是机器名称,--chdir
更改容器内的目录和./entrypoint
是我要运行的脚本(可以是任何命令、脚本等)&
在后台运行它(因此您可以在运行命令的特定 tty 中执行其他操作)。该
entrypoint
脚本最初来自从该文件系统导出的 podman 容器。这是它正在做的事情(非常简单):所以这只是运行我在容器内开发的网络应用程序。它被指定在端口上运行
3000
。然后,将 nginx 设置为代理
80
,3000
它在防火墙中有一个开放端口:您可以看到它正在使用环回设备 - 但是当在没有和没有
systemd-nspawn
的情况下运行时,您的任何主机网络都可以在容器内使用。这与这种方式非常相似。--boot
--network-{bridge,interface,ipvlan,macvlan,veth}
chroot
然后,一旦
systemd-nspawn
运行(在后台,因为&
在命令的末尾),可以运行:它将从
.nspawn
模板生成带有机器名称的符号链接。.nspawn
模板在这里:/lib/systemd/system/[email protected]
$MACHINE_NAME.nspawn
此处将添加链接:/etc/systemd/system/machines.target.wants/systemd-nspawn@$MACHINE_NAME.service
如果您想默认使用主机网络运行新机器,只需备份原始并删除一些运行时参数:
您可以在这里看到在单元文件中运行的命令基本相同,我只是添加了 flag
--link-journal=try-host
,它放置了一个/var/log/journal/$MACHINE_UUID
用于监视容器的日志。由于这是一个模板,它假设我将调用一个
entrypoint
从每个容器的根目录命名的脚本,这给了它们更多的“命令调用容器”行为(例如 Docker 风格而不是 LXC 风格)。关于问题的说明:
我想使用
--user
标志,但它似乎是非功能性 ATM。这里有一些关于标志回归的讨论,但它与 CentOS 上的 v237 相关,所以不确定它是否与 Ubuntu 20.04 上的 241 相关,这就是我正在使用的 ATM。无论如何,容器现在将使用 root UID 运行......systemd-networkd
应该与--network-veth
创建 DHCP 主机host0
和客户端一起使用ve-$MACHINE_NAME
(限制 16 个字符) -如果主机和客户端都使用systemd-networkd
. 但是,在 Ubuntu 20.04 上,我无法让它在实践中正常工作。我猜有一个错误:我的 systemd 版本中有这个功能,并将在以后的版本中做进一步的测试。环境信息:
进一步阅读: