我正在尝试从 systemd 服务启动网络命名空间内的应用程序。我尝试使用,但当我使用NetworkNamespacePath=
它时,所有网络请求都失败。如果我使用启动应用程序,它可以工作,但它不是很干净,我必须使用重置用户。我做错了什么?ExecStart
ip netns exec
sudo
NetworkNamespacePath=
我认为这没什么大不了的,但我正在运行 Ubuntu Server 20.04 LTS。这是我的服务文件。
[Unit]
Description=My Service
# netns.service sets up the network namespace
After=network-online.target netns.service
Requires=network-online.target netns.service
[Service]
Type=simple
# The following doesn't work, app starts but every network request fails
NetworkNamespacePath=/run/netns/mynetns
User=user
Group=user
ExecStart=/usr/bin/app
# If I change it to this, it works
ExecStart=/usr/sbin/ip netns exec mynetns sudo -u user /usr/bin/app
[Install]
WantedBy=multi-user.target
答案1
这可能与 DNS 有关,或者至少对我来说在相同情况下是这样的。默认系统解析器可能无法从网络命名空间访问。
正如手册页,ip netns exec
自动创建命名空间特定的配置绑定挂载,这些配置不会由你的 systemd 单元复制:
对于了解网络命名空间的应用程序,惯例是先在 中查找全局网络配置文件,
/etc/netns/NAME/
然后在 中查找/etc/
。例如,如果您想要一个/etc/resolv.conf
用于隔离 VPN 的网络命名空间的不同版本,您可以将其命名为/etc/netns/myvpn/resolv.conf
。
ip netns exec
通过创建挂载命名空间并将每个网络命名空间的所有配置文件绑定挂载到其传统位置,自动处理此配置,即针对不了解网络命名空间的应用程序的文件约定/etc
。
因此,如果您在中设置了自定义解析器/etc/netns/mynetns/resolv.conf
,则必须在服务文件中绑定它:
[Service]
NetworkNamespacePath=/run/netns/mynetns
BindReadOnlyPaths=/etc/netns/mynetns/resolv.conf:/etc/resolv.conf