我有一台 Debian 机器,运行多个由systemd
自身管理的静态 IPv4 和 IPv6 地址,/etc/systemd/network/10-static-eth0.network
如下所示:
[Match]
Name=eth0
[Network]
Address=2a04:----::149/64
Address=2a04:----::242/64
Address=2a04:----::243/64
Gateway=2a04:----:0001
Address=5.----.149/25
Address=5.----.242/25
Address=5.----.243/25
Gateway=5.----.129
DNS=89.----.4
DNS=46.----.104
我有多个进程,它们通过 OpenVPN、Bind9 等单元从系统启动。systemd
它们都设置为绑定到接口的特定 IP eth0
。然而,它们无法启动,因为它们在启动后无法绑定到IPv6
地址。
我怎么知道这个?
我制作了两个测试单元,它们在目标之后使用ping
和ping6
来测试网络network.target
,network-online.target
并且发生了这种情况:
IPv4测试结果:
server.example:~# systemctl status abootping.service
● abootping.service - A boot-time ping for network testing
Loaded: loaded (/lib/systemd/system/abootping.service; enabled)
Active: inactive (dead) since Thu 2015-11-26 11:01:58 CET; 45s ago
Main PID: 433 (code=exited, status=0/SUCCESS)
Nov 26 11:01:54 server.example ping[433]: PING test-ping-host.example (89.-----.8) from 5.----.149 : 56(84) bytes of data.
Nov 26 11:01:54 server.example ping[433]: 64 bytes from test-ping-host.example (89.-----.8): icmp_seq=1 ttl=59 time=4.92 ms
Nov 26 11:01:55 server.example ping[433]: 64 bytes from test-ping-host.example (89.-----.8): icmp_seq=2 ttl=59 time=4.92 ms
Nov 26 11:01:56 server.example ping[433]: 64 bytes from test-ping-host.example (89.-----.8): icmp_seq=3 ttl=59 time=4.84 ms
Nov 26 11:01:57 server.example ping[433]: 64 bytes from test-ping-host.example (89.-----.8): icmp_seq=4 ttl=59 time=5.41 ms
Nov 26 11:01:58 server.example ping[433]: 64 bytes from test-ping-host.example (89.-----.8): icmp_seq=5 ttl=59 time=4.95 ms
Nov 26 11:01:58 server.example ping[433]: --- test-ping-host.example ping statistics ---
Nov 26 11:01:58 server.example ping[433]: 5 packets transmitted, 5 received, 0% packet loss, time 4007ms
Nov 26 11:01:58 server.example ping[433]: rtt min/avg/max/mdev = 4.843/5.010/5.414/0.209 ms
IPv6测试结果:
server.example:~# systemctl status abootping6.service
● abootping6.service - A boot-time ping6 for network testing
Loaded: loaded (/lib/systemd/system/abootping6.service; enabled)
Active: failed (Result: exit-code) since Thu 2015-11-26 11:01:54 CET; 56s ago
Main PID: 436 (code=exited, status=2)
Nov 26 11:01:54 server.example ping6[436]: ping: bind icmp socket: Cannot assign requested address
Nov 26 11:01:54 server.example systemd[1]: abootping6.service: main process exited, code=exited, status=2/INVALIDARGUMENT
Nov 26 11:01:54 server.example systemd[1]: Failed to start A boot-time ping6 for network testing.
Nov 26 11:01:54 server.example systemd[1]: Unit abootping6.service entered failed state.
正如您所看到的,IPv4 在启动后可以正常工作,但 IPv6 则不然,并且所有需要 IPv6 的启动过程都会失败并进行绑定。
关于我network-online.target
为了真正确保我的启动单元仅在网络真正工作后启动,我添加了After=network.target network-online.target
所有这些单元。
network-online.target
本身有这个wants
:
包括了:
[Unit]
Description=Wait for Network to be Configured
Documentation=man:systemd-networkd-wait-online.service(8)
DefaultDependencies=no
Conflicts=shutdown.target
Requisite=systemd-networkd.service
After=systemd-networkd.service
Before=network-online.target
[Service]
Type=oneshot
ExecStart=/lib/systemd/systemd-networkd-wait-online
RemainAfterExit=yes
[Install]
WantedBy=network-online.target
根据文档:
systemd-networkd-wait-online 是一项一次性系统服务,用于等待网络配置。默认情况下,它将等待它知道的以及由 systemd-networkd.service(8) 管理的所有链接完全配置或失败,并等待至少一个链接获得运营商。
此服务等待的实际效果在启动时非常明显,我的测试ping
服务也尊重它:
ping
SSH登录后
在大家认为我的 IPv6 网络配置不正确之前,这里有一些其他证据:
如果我在启动后立即通过 SSH 连接到机器并尝试使用
ping6
它,它会起作用:server.example:~# ping6 -I 2a04:-----::242 test-ping-host.example -c 5 PING test-ping-host.example(test-ping-host.example) from 2a04:-----::242 : 56 data bytes 64 bytes from test-ping-host.example: icmp_seq=1 ttl=59 time=7.41 ms 64 bytes from test-ping-host.example: icmp_seq=2 ttl=59 time=7.41 ms 64 bytes from test-ping-host.example: icmp_seq=3 ttl=59 time=7.31 ms ^C --- test-ping-host.example ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 7.314/7.381/7.415/0.047 ms
例如,如果我重新启动,
lighttpd
它会正确绑定到它应该绑定的 IPv6,并且我可以使用 IPv6 客户端或ping6
从另一台计算机打开托管网站。
这是我的问题: 这正常吗? IPv6 是否也应该工作,因为systemd-networkd-wait-online
确保它可用?或者...at least one link to gain a carrier.
真的意味着在我获得可用的 IPv4 后,它将停止等待并且 IPv6 地址仍然不可路由?我怎样才能解决这个问题?
答案1
显然我是对的,它不是在等待 IPv6。我在项目的 Github 上发布了这个问题,有人将其标记为 RFE:https://github.com/systemd/systemd/issues/2037
检查此解决方案(禁用 IPv6 DAD),以暂时解决该问题:http://serverfault.com/questions/766253/ensure-systemd-wait-for-ipv6-before-start-service-unit