我正在运行 Debian Buster 的 Google Compute Engine 中启动一个虚拟机,并为其配置两个网络接口。
第一个使用临时 IP 配置,并分配给公共可路由网络,通过 DHCP 配置。我想保持原样。
第二个接口使用静态 IP 配置,并分配给私有网络。我想阻止 GCE 使用 DHCP 配置此接口,而是使用 systemd-networkd 自行配置,以便轻松添加一些自定义路由。
虽然 systemd-networkd 配置确实能成功运行,但问题是,当机器重新启动时,GCE 的 DHCP 设置在 systemd-networkd 设置之后运行,并覆盖我的自定义配置。
到目前为止,我尝试了很多方法来解决此问题,包括:
- 禁用 /etc/network/interfaces 中的 /var/run/interfaces.d 条目
- 添加自定义 systemd 服务以在 GCE 的网络服务之后运行
到目前为止唯一有效的方法是使用一个可怕的脚本来破解,在启动后等待 30 秒,然后再次启动 systemd-networkd 来覆盖 GCE 配置。
我可以在操作系统级别进行一些更清晰的配置更改吗,或者在网络/服务器设置期间进行配置设置,以防止 GCE 自动配置第二个网络接口?
编辑#1:
这是我喜欢使用的 systemd-networkd 配置的示例:
[Match]
Name=ens5
[Network]
Address=10.1.3.30/32
LinkLocalAddressing=no
[Route]
Destination=10.1.3.1/32
Scope=link
[Route]
Gateway=10.1.3.1
Destination=10.1.3.0/24
GatewayOnlink=yes
[Route]
Gateway=10.1.3.1
Destination=10.1.1.0/24
GatewayOnlink=yes
[Route]
Gateway=10.1.3.1
Destination=10.1.2.0/24
GatewayOnlink=yes
[Route]
Gateway=10.1.3.1
Destination=10.10.0.0/24
GatewayOnlink=yes
使用此配置,我可以在接口上设置到其他子网的其他路由。请注意,这些其他子网可能位于 GCP 上,也可能不位于 GCP 上。
即使我必须在 GCE 服务器设置中声明 10.1.3.30 静态 IP 地址,上述配置仍然有效。问题只是我无法让 GCE 停止对接口进行自己的配置,这会覆盖上面的配置。在 Azure 上,我只需注释掉对 的引用source
即可。/var/run/network/interfaces.d
/etc/network/interfaces
至于为什么我更喜欢这种设置,因为它是一种通过我的服务器配置管理软件设置我的内部网络的优雅方法——我只需将上述配置放入/etc/systemd/network/
并发出systemctl enable systemd-networkd && systemctl restart systemd-networkd
,它就会处理配置接口并设置配置在启动时发生。
更新 #1:
我已经提交https://issuetracker.google.com/issues/153513472在 GCP 的问题跟踪器中,希望他们能解决。当他们解决时,我会相应地更新问题。
更新 #2:
在经过一轮付费 GCP 支持后,他们向我指出了另一个持续存在的问题:https://issuetracker.google.com/issues/167371074
支持代理还建议其他用户简单地使用 cron 脚本来定期重启网络。
我根据自己的特定网络需求调整了此建议,并添加了以下 crontab 条目:
* * * * * /usr/bin/test -z "$(/sbin/ip route | /bin/grep "10.1.1.0/24")" && /bin/systemctl restart systemd-networkd
其中 '10.1.1.0/24' 是我知道在我的路由配置中应该不是失踪。
更新 #3:
最后,一个干净而令人满意的答案!Google 工程师告诉我,google-guest-agent.service
在 Debian 系统上作为其客户环境的一部分运行的 有一个网络守护进程,当它重新配置任何接口时,它会dhclient
直接调用。似乎以dhclient
这种方式调用会清除现有路由。鉴于此,一个简单的解决方法是通过在 中添加 shell 脚本来创建 dhclient 退出钩子/etc/dhcp/dhclient-exit-hooks.d/
。
就我而言,我添加了以下脚本/etc/dhcp/dhclient-exit-hooks.d/systemd-networkd
:
case $reason in
BOUND|RENEW|REBIND|REBOOT)
systemctl restart systemd-networkd.service
;;
esac
这似乎解决了问题,包括重启后的问题。
答案1
不幸的是,目前你无法在 GCP 上实现这种情况。你可以按照以下文档使用描述的方法管理内部 IP,例如对辅助网络接口使用静态内部 IP 地址。
作为一种可能的解决方法,您可以提交功能要求在Google 问题追踪器在下面这个组件。