![确保 systemd 在启动服务单元之前等待 IPv6](https://linux22.com/image/679576/%E7%A1%AE%E4%BF%9D%20systemd%20%E5%9C%A8%E5%90%AF%E5%8A%A8%E6%9C%8D%E5%8A%A1%E5%8D%95%E5%85%83%E4%B9%8B%E5%89%8D%E7%AD%89%E5%BE%85%20IPv6.png)
当我有一个服务正在侦听特定的 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 地址的服务上看到此问题。