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

Mar*_*dez 5 ipv6 systemd centos7

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

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

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

[Service]
Restart=on-failure
RestartSec=10s
StartLimitInterval=1min
Run Code Online (Sandbox Code Playgroud)

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

我的系统是CentOS 7.2,禁用了 NetworkManager 和 firewalld,启用了网络和 iptables,使用静态 IP,在接口填满 IPv4/IPv6 后,所有网络都在 IN/OUT 工作。

我的 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"
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

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

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

net.ipv6.conf.eth0.accept_dad = 0
Run Code Online (Sandbox Code Playgroud)

随着 IPv6 的发展,我将关注这个引导 DAD 问题。我只在绑定到特定 IPv6 地址的服务上看到这一点。