fdm*_*ion 125 networkmanager systemd
我对 systemd 比较陌生,正在学习它的架构。
现在,我正试图弄清楚如何使自定义 shell 脚本运行。该脚本需要运行后,网络层已启动。
我正在运行 Arch,使用 systemd 和 netctl。
为了测试,我编写了一个简单的脚本,它只执行ip addr list > /tmp/ip.txt. 我为此脚本创建了以下服务文件。
(/etc/systemd/system/test.service)
[Unit]
Description=test service
[Service]
ExecStart=/root/test.script
[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)
然后我启用了脚本,
systemctl enable test
Run Code Online (Sandbox Code Playgroud)
重新启动后,脚本确实会运行,但它会在网络启动之前运行。换句话说,中的输出ip.txt显示没有分配给主接口的 IPv4 地址。到我登录时,IPv4 地址确实已分配并且网络已启动。
我猜我可以通过弄乱WantedBy参数来改变脚本运行的点,但我不知道该怎么做。
有人能指出我正确的方向吗?
Pav*_*rda 158
很容易影响 systemd 的单元排序。另一方面,你需要注意一个完整的单元保证什么。
在目前的系统上,order afternetwork.target只是保证网络服务已经启动,而不是有一些实际的配置。您需要在之后订购network-online.target并将其拉入以实现这一目标。
[Unit]
Wants=network-online.target
After=network-online.target
Run Code Online (Sandbox Code Playgroud)
为了与旧系统兼容,您可能还需要在 network.target 之后订购。
[Unit]
Wants=network-online.target
After=network.target network-online.target
Run Code Online (Sandbox Code Playgroud)
这适用于您的服务和 systemd 的单元文件。
现在您需要确保它network-online.target按预期工作(或者您至少可以使用network.target)。
当前版本的网络管理器提供了NetworkManager-wait-online.service通过它获取拉入network-online.target,因此您的服务。此特殊服务可确保您的服务将等到所有配置为自动启动的连接成功、失败或超时。
当前版本的systemd-networkd 会阻止您的服务,直到所有设备都按要求进行配置。更简单的是,它目前仅支持在启动时应用的配置(更具体地说,是“systemd-networkd.service”的启动时间)。
为了完整起见,/etc/init.d/networkFedora 中的服务,正如 systemd 的当前版本所解释的那样,会阻塞network.target并因此间接阻塞network-online.target和您的服务。这是一个基于脚本的实现示例。
如果您的实现,无论是基于守护程序还是基于脚本,作为上述网络管理服务之一,它将延迟您的服务的启动,直到网络配置成功完成、因正当理由失败或在合理时间后超时框架来完成。
您可能想检查netctl是否以相同的方式工作,并且该信息将是此答案的宝贵补充。
我不认为你会看到足够旧的 systemd 版本,这不会很好地工作。但是您可以检查至少network-online.target存在并且在network.target.
以前NetworkManager只保证至少应用一个连接。即使要使其工作,您也必须NetworkManager-wait-online.service明确启用。这在 Fedora 中早已修复,但最近才在上游应用。
systemctl enable NetworkManager-wait-online.service
Run Code Online (Sandbox Code Playgroud)
您永远不需要让您的软件依赖于NetworkManager.service或NetworkManager-wait-online.service任何其他特定服务。取而代之的是,所有网络管理服务都应该在之前network.target和可选地进行排序network-online.target。
一个简单的基于脚本的网络管理服务应该在退出之前完成网络配置,并且应该network.target在network-online.target.
[Unit]
Before=network.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
Run Code Online (Sandbox Code Playgroud)
network.target即使不是很有用,基于守护进程的网络管理服务也应该先对自身进行排序。
[Unit]
Before=network.target
[Service]
Type=simple
ExecStart=...
Run Code Online (Sandbox Code Playgroud)
等待守护进程完成的服务应该在特定服务之后和之前对自身进行排序network-online.target。它应该Requisite在守护程序服务上使用,以便在未使用相应的网络管理服务时立即失败。
[Unit]
Requisite=...
After=...
Before=network-online.target
[Service]
Type=oneshot
ExecStart=...
RemainAfterExit=yes
Run Code Online (Sandbox Code Playgroud)
该包应该在wants目录中安装一个指向等待服务的符号链接,network-online.target以便它被想要等待配置网络的服务拉入。
ln -s /usr/lib/systemd/system/... /usr/lib/systemd/system/network-online.target.wants/
Run Code Online (Sandbox Code Playgroud)
我希望我不仅在您提出问题时帮助回答了您的问题,而且还有助于改善上游和 Linux 发行版的情况,以便我现在可以给出比撰写原始问题时更好的答案.
您可以使用Afterin[Unit]部分来定义应该在您的服务启动之前启动的服务。例如,如果您使用的是 NetworkManager,您可以在 NetworkManager 启动后启动您的服务。
[Unit]
Description=test service
After=NetworkManager.service
Run Code Online (Sandbox Code Playgroud)
        如果您的服务提供了一个可以被动等待某人连接到它的服务器,请使用以下命令:
[Unit]
After=network.target
Run Code Online (Sandbox Code Playgroud)
您的服务应该绑定在通配符接口上。如果它使用套接字激活(推荐),或者它是仅限本地的,则可以完全忽略网络目标。
如果您的服务充当客户端,或者是对等的,则更合适:
[Unit]
After=network-online.target
Requires=network-online.target
Run Code Online (Sandbox Code Playgroud)
在systemd 213之前, network-online.target 需要 Pavel 提到的解决方法(您需要手动启用将等待网络启动的服务)。从 systemd 213 开始,这是默认完成的。systemd-networkd-wait-online将等待至少一个地址(可路由或本地链路)在非环回接口上配置。
配置 systemd-networkd、NetworkManager 或等价物是一项独立的任务。DHCP(适用于 IPv4)和 NDP(适用于 IPv6)往往是开箱即用的,但您应该配置它们,以便您对“网络已启动”的精确定义是触发network-online.target.
文档:
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           169306 次  |  
        
|   最近记录:  |