我将 /etc/network/interfaces 中的 dhcp 修改为静态(如下所示)。
# The primary network interface
auto eth0
iface eth0 inet static
netmask 255.255.0.0
address 10.10.130.128
gateway 10.10.1.1
然后重新启动界面。
$ sudo ifdown eth0; sudo ifup eth0
...
$ ifconfig
eth0 Link encap:Ethernet
inet addr:10.10.130.128 Bcast:10.10.255.255 Mask:255.255.0.0
因此新地址开始生效。
但是 DHCP 还在那里?
$ ps aux | grep dhc
root ... dhclient3 -e IF_METRIC=100 -pf /var/run/dhclient.eth0.pid -lf /var/lib/dhcp/dhclient.eth0.leases -1 eth0
这正常吗?如果不正常,如何在静态 IP 中重新启动接口并同时停止 DHCP?
多谢。
答案1
- 您首先必须关闭接口(在 dhcp 模式下)
sudo ifdown eth0
然后编辑配置
nano /etc/network/interfaces
# The primary network interface auto eth0 iface eth0 inet static netmask 255.255.0.0 address 10.10.130.128 gateway 10.10.1.1
恢复界面
sudo ifup eth0
否则dhclient
无法正确关闭,
答案2
我遇到了同样的问题(Ubuntu 16.04)。但是,这是一个云实例,我无法轻松关闭界面。
简短回答:我删除了该文件/etc/network/interfaces.d/50-cloud-init.cfg
ifup 是由该特定文件触发的。
长答案:我使用静态 IP 地址配置了接口/etc/network/interfaces
,但我仍然在 daemon.log 中发现 dhclient 仍在从 DHCP 请求 IP,并且 dhclient 是通过 systemd 启动的。具体来说,systemd 调用 networking.service 单元,后者调用 ifup,后者读取接口文件和 50-cloud-init.cfg 文件。这导致了一些冲突,但仍然是一个功能正常的网络。
答案3
我发现,这是因为 gnome 的 NetworkManager 仍在运行,并认为它负责管理该设备。事后看来,这应该是显而易见的,因为ps
显示 dhclient 是由 NetworkManager 启动的。
重新启动系统后,设备在 NetworkManager 中变为“未管理”,并且停止尝试配置它。也许我可以通过停止/重新启动 NetworkManager 来实现同样的效果,但我不确定。
答案4
在我的例子中,我尝试在我的 KVM 主机上使用 cloud-init 和静态 IP 配置 Debian 11 通用云镜像(使用 dmacvicar libvirt Terraform 提供程序)
我的网络配置文件是:
version: 2
ethernets:
ens3:
dhcp4: false
addresses: [10.1.0.100]
gateway4: 10.1.0.1
nameservers:
addresses: [10.1.0.1 1.1.1.1]
search: [home.lab]
然后令我惊讶的是,在创建虚拟机期间,接口正在请求 DHCP 租约前cloud-init config 实际上会启动并根据我的静态设置配置接口(完全像 OP 描述的一样)
大约一分钟后,“神秘的”dhclient 放弃等待请求(这是预料之中的,因为我的 libvirt 网络上禁用了 DHCP),并在后台运行。然后启动顺序继续并cloud-init
启动,在 中呈现正确的静态配置/etc/network/interfaces.d/50-cloud-init.cfg
。此时,接口获取预期的静态 IP(ip address show
证明了这一点,您也可以通过 IP ping 东西),但是 DNS 解析中断。我猜这是 dhclient 失败的副作用。
经过一番挖掘,我发现/etc/network/interfaces
除了文件之外,source-directory /etc/network/interfaces.d
它还提供了额外的目录/run/network/interfaces.d/
。令我惊讶的是,该目录包含在模式下配置的/run
接口定义!ens3
dhcp
所以现在我知道了意外的 dhcp 请求来自哪里,接下来就是禁用它,因为它与中的正确设置相冲突/etc/network/interfaces.d/50-cloud-init.cfg
。
不幸的是,在 cloud-init 启动之前会禁用初始 dhcp 请求,因此实际上没有简单的方法可以防止 dhclient 浪费宝贵的一分钟左右的时间去尝试获取永远不会出现的报价。
不过,我能做的是,bootcmd:
在我的user-data
bootcmd:
- cloud-init-per once down ifdown ens3
- cloud-init-per once bugfix rm /run/network/interfaces.d/ens3
- cloud-init-per once up ifup ens3
在上面的命令中,我关闭了接口,从而停止了休眠的 dhclient 进程,然后我删除了ens3
以 dhcp 模式设置的接口定义文件,最后我重新启动了接口,这样就可以像冠军一样ens3
应用设置的内容。/etc/network/interfaces.d/50-cloud-init.cfg
这样,初始启动过程中的后续 cloud-init 阶段现在能够通过名称完全访问互联网。这对于后续阶段(例如阻止)的packages:
成功至关重要,因为它需要 DNS 工作来解析 apt repo 服务器名称。
以下是更详细的user-data
摘录:
bootcmd:
- cloud-init-per once ifdown ifdown ens3
- cloud-init-per once bugfix rm /run/network/interfaces.d/ens3
- cloud-init-per once ifup ifup ens3
packages:
- qemu-guest-agent
- locales-all
package_update: true
package_upgrade: true
package_reboot_if_required: true
runcmd:
- [ systemctl, start, qemu-guest-agent ]
final_message: "The system is finally up, after $UPTIME seconds"
我认为这可能会对在 cloud-init 设置中遇到 OP 问题的其他人有所帮助。
参考:
- https://cloudinit.readthedocs.io/en/latest/topics/network-config.html#network-configuration
- https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html
- https://cloudinit.readthedocs.io/en/latest/topics/modules.html#bootcmd
- https://cloudinit.readthedocs.io/en/latest/topics/modules.html#package-update-upgrade-install
- https://cloud.debian.org/images/cloud/bullseye/latest/debian-11-genericcloud-amd64.qcow2