确保 systemd 在启动服务单元之前等待 IPv6

确保 systemd 在启动服务单元之前等待 IPv6

当我有一个服务正在侦听特定的 IPv6 地址时,它在启动时失败,声称该地址仍然不可用。每个正在侦听特定地址的服务都会发生这种情况。

为了避免这种情况,我为该服务创建了一个插件,After=... network.target通过After=... network-online.target这个插件可以解决 IPv4 地址绑定问题,但不能解决 IPv6 地址绑定问题。我尝试使用一些特定于接口的目标,但没有成功,它们等待 IPv4 位不启动,因为 IPv6 已启动。

作为一种解决方法,我还添加到服务部分:

[Service]
Restart=on-failure
RestartSec=10s
StartLimitInterval=1min

似乎每个人都在这样做来解决这个问题,但我对此并不满意,并且似乎是某种允许 systemd 等待 IPv6 地址的方法。

我的系统是CentOS 7.2,已禁用 NetworkManager 和 Firewalld,启用网络和 iptables,使用静态 IP,接口充满 IPv4/IPv6 后,所有网络均可进行输入/输出工作。

我的ifcfg-eth0:

DEVICE=eth0
BOOTPROTO=none
NM_CONTROLLED="no"
ONBOOT=yes
IPADDR=X.X.X.X
PREFIX=24
GATEWAY=X.X.X.X
DNS1=X.X.X.X
DNS2=8.8.8.8
SEARCH=xxx.xxx
IPV6INIT=yes
IPV6_AUTOCONF=no
IPV6ADDR="X:X:X:X::X"

我还注意到,在一些双栈 IPv4/IPv6 部署的系统中,IPv6 也需要更长的时间来初始化静态地址,这是由路由设置和一些其他新的 IPv6 内容引起的。

所以我的问题是,如何确保仅在将 IPv6 链路全局分配给接口后才启动服务单元?

编辑:在收到一些关于 DAD 的评论后,我发现 systemd-networkd 已合并 DAD 等待,但仅在主分支上,在系统 220 上不存在(Centos 7.2 有 systemd 219)。NetworkManager 似乎有一些补丁,但我没有使用任何补丁。

读完这篇文章后,我找到了一个可以接受的临时解决方案,并进行了一些测试,对于我的情况,服务器上的 IP 是固定的,不能分配另一个,这篇文章向我展示了解决方案:

https://www.agwa.name/blog/post/beware_the_ipv6_dad_race_condition

我还测试了基于乐观DAD的注释DAD解决方案RFC4429,这并不能解决我的绑定问题。最后禁用了接口上的 DAD,服务在启动时正常启动。:D。

net.ipv6.conf.eth0.accept_dad = 0

随着 IPv6 的发展,我将密切关注此启动 DAD 问题。我只在绑定到特定 IPv6 地址的服务上看到此问题。

相关内容