Debian 10 cloud-init 在启动时使用静态网络配置等待 DHCP

Debian 10 cloud-init 在启动时使用静态网络配置等待 DHCP

运行 Debian 10 Buster 映像(用 创建build-openstack-debian-image --release buster)和由 创建的 cloud-init 映像cloud-localds -v --disk-format raw --filesystem iso9660 --network-config=network-config-v2.yaml seed.img user-data.yaml

问题是由于等待 DHCP 而导致启动延迟,尽管我有一个有效的网络配置并且它在此延迟之后应用。

[    3.619937] cloud-init[210]: Cloud-init v. 20.2 running 'init-local' at Sun, 10 Jan 2021 10:50:20 +0000. Up 3.40 seconds.
[  OK  ] Started Initial cloud-init job (pre-networking).
[  OK  ] Reached target Network (Pre).
         Starting Raise network interfaces...
[  OK  ] Started ifup for eth0.
[     *] A start job is running for Raise network interfaces (35s / 5min 1s)

我该怎么做才能避免这个延迟?

如果需要的话我可以提供更多信息。谢谢。

# systemd-analyze blame
     1min 2.639s networking.service
           951ms cloud-init-local.service
           773ms cloud-init.service
           657ms cloud-final.service
           540ms cloud-config.service
           421ms dev-vda1.device
           310ms ifupdown-pre.service

我的network-config-v2.yaml

version: 2
renderer: networkd
ethernets:
  eth0:
    match:
      name: e*
    addresses:
      - private.ipv4/24
      - public.ipv4/32
      - ipv6/64
    gateway4: private.ipv4
    routes:
      - to: 0.0.0.0/0
        via: private.ipv4
    gateway6: ipv6
    nameservers:
      addresses:
        - ipv4
        - ipv6
      search: [domain.com]

答案1

@zany 的精彩指点

在我的例子中,我尝试在我的 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 租约(journalctl是你的朋友)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接口定义!ens3dhcp

所以现在我知道了意外的 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"

尽管不是在 Debian10 上,但这个问题听起来很熟悉,所以我想分享我的经验,以防你在新版本中遇到这个问题。

参考:

答案2

我遇到了示例问题——使用静态网络配置(NoCloud 提供商元数据 ENI 或网络配置 v1/v2)不会禁用 DHCP 客户端。

/etc/network/cloud-interfaces-template似乎在写入 cloud-init 配置之前,网络配置是从模板()应用的。

auto $INTERFACE
allow-hotplug $INTERFACE

iface $INTERFACE inet dhcp

您可以通过在首次启动之前更改云图像来测试该模板是否是罪魁祸首:(
修补图像,因为更改网络配置为时bootcmd已晚。)

qemu-nbd --connect=/dev/nbd0 /tmp/debian-10-genericcloud-amd64-20210208-542.qcow2
fdisk /dev/nbd0 -l
mkdir /tmp/nbd
mount /dev/nbd0p1 /tmp/nbd
sed -i 's/dhcp/manual/' /tmp/nbd/etc/network/cloud-interfaces-template
umount /tmp/nbd
rmdir /tmp/nbd
qemu-nbd --disconnect /dev/nbd0

我仍然需要找到一种方法来应用此更改或阻止将此模板与 cloud-init 一起使用。

该模板似乎是经过处理的/etc/network/cloud-ifupdown-helper,因此该脚本可能会被更改或影响。

答案3

我遇到了同样的问题。

这里有一个更好的解决方法,只需将 DHCP 超时设置为更短的时间即可。

# virt-edit debian-10-generic-amd64.qcow2 /etc/dhcp/dhclient.conf

timeout 15;

然后该镜像就可以在NoCloud环境或DHCP网络中正常运行。

答案4

agittins 的回答似乎最好,但在我的案例中,用户数据文件中的 cloud-init “bootcmd” 命令是在 debian “75-cloud-ifupdown.rules” 之后处理的。因此,我不得不删除磁盘映像中的 debian 脚本(先安装 vm 存储,然后删除脚本并卸载):

sudo qemu-nbd --connect=/dev/nbd0 debian-11-genericcloud-arm64-backing.qcow2

sudo mount /dev/nbd0p1 /mnt

sudo rm -v /mnt/etc/udev/rules.d/75-cloud-ifupdown.rules

sudo rm -v /mnt/etc/network/cloud-ifupdown-helper

sudo rm -v /mnt/etc/network/cloud-interfaces-template

sudo umount /mnt

相关内容