LoginSignup
6
3

More than 3 years have passed since last update.

libvirtのnetworkでDHCPが同じIPを振り続ける

Posted at

dnsmasqは悪くなかった。ごめんよ。

ホスト:Ubuntu 19.10 / libvirtd 5.4.0
VM:Ubuntu 20.04 LTS

事象

  • libvirt(KVM)でUbuntu VMを作り、default networkに接続する。
  • virt-cloneする。
  • 起動する。

結果

同じIPが振られる。


default networkの例。

default(例)
<network>
  <name>default</name>
  <uuid>df3e2c4f-3071-427c-a032-8c340a72407e</uuid>
  <forward mode='nat'/>
  <bridge name='virbr0' stp='off' delay='0'/>
  <mac address='52:54:00:f4:35:24'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

こんな感じにcloneする。

clone
$ virt-clone --original vm1 --name dhcp-test2 --file /var/lib/libvirt/images/dhcp-test2.qcow2

で、cloneしたVM2台を起動すると、同じIPが振られる。

🥺ぴえんぱおん🥺

惑ったところ

  • virt-cloneはVMインターフェイスのMACアドレスを変更してくれる。
    • ログを見ると、「異なるMACからのDISCOVERに同じIPを返す」ような謎挙動に見える。
libvirtdのjournal
May 27 10:59:26 dnsmasq-dhcp[1740]: DHCPDISCOVER(virbr0) 52:54:00:be:82:59
May 27 10:59:26 dnsmasq-dhcp[1740]: DHCPOFFER(virbr0) 192.168.122.188 52:54:00:be:82:59
May 27 10:59:26 dnsmasq-dhcp[1740]: DHCPREQUEST(virbr0) 192.168.122.188 52:54:00:be:82:59
May 27 10:59:26 dnsmasq-dhcp[1740]: DHCPACK(virbr0) 192.168.122.188 52:54:00:be:82:59 testing
May 27 10:59:29 dnsmasq-dhcp[1740]: DHCPDISCOVER(virbr0) 52:54:00:8f:6a:81
May 27 10:59:29 dnsmasq-dhcp[1740]: DHCPOFFER(virbr0) 192.168.122.188 52:54:00:8f:6a:81
May 27 10:59:29 dnsmasq-dhcp[1740]: DHCPREQUEST(virbr0) 192.168.122.188 52:54:00:8f:6a:81
May 27 10:59:29 dnsmasq-dhcp[1740]: DHCPACK(virbr0) 192.168.122.188 52:54:00:8f:6a:81 testing

  • この点から「lease fileに書き込めていない?」「systemd-networkdと干渉している?」と思うなどした。
    • 間違い。

答え

  • DHCPのleaseはMAC Addressではなく、Client IDDUID)で管理されている。
  • virt-cloneしたUbuntu VMではClient IDが同じになるため、LeaseからIPを返す。

この結果、cloneしたVMには同じIPを振り続けてしまう。
image.png
1台目、Option61にClient Identifierがある。
image.png
2台目、同じ値である!

leaseを見ても、同じClient IDであることがわかる。
場所は/var/lib/libvirt/dnsmasq/<interface>.status、libvirt用の形式で通常のdnsmasqとは異なる。(この辺の事情

1台目起動。

/var/lib/libvirt/dnsmasq/virbr0.status
[
  {
    "ip-address": "192.168.122.188",
    "mac-address": "52:54:00:be:82:59",
    "hostname": "testing",
    "client-id": "ff:b5:5e:67:ff:00:02:00:00:ab:11:37:05:50:e0:d8:7b:8c:01",
    "expiry-time": 1590582921
  }
]

2台目起動。

/var/lib/libvirt/dnsmasq/virbr0.status
[
  {
    "ip-address": "192.168.122.188",
    "mac-address": "52:54:00:8f:6a:81",
    "hostname": "testing",
    "client-id": "ff:b5:5e:67:ff:00:02:00:00:ab:11:37:05:50:e0:d8:7b:8c:01",
    "expiry-time": 1590583031
  }
]

MACが変わっているが、同じレコードとして扱われている。

(気楽に見るなら、virsh net-dhcp-leases default でも。)

同じIP振られるのも納得。

なぜ同じIDになるのか

Ubuntu、というかsystemdがDHCPに使うClient IDをmachine-idをもとに計算するため。
virt-cloneはそこまで変えない。

以下manページ抜粋(networkd.conf(5))

networkd.conf(5)
       DUIDType=
           Specifies how the DUID should be generated. See RFC 3315[1] for a description of all the options.

           The following values are understood:

           vendor
               If "DUIDType=vendor", then the DUID value will be generated using "43793" as the vendor
               identifier (systemd) and hashed contents of machine-id(5). This is the default if DUIDType= is
               not specified.

ここでmachine-id/etc/machine-idに保存されていて、再起動しても変わらない

以下manページ抜粋(machine-id(5))

machine-id(5)
       The machine ID is usually generated from a random source during system installation or first boot and
       stays constant for all subsequent boots. Optionally, for stateless systems, it is generated during
       runtime during early boot if necessary.

どうすればよいのか

以下の方法でとりあえず別のIPをもらえる。

Client IDをMACにする

ゲストOSでネットワーク設定を変更。
dhcp-identifierを追加。

/etc/netplan/00-installer-config.yaml
# This is the network config written by 'subiquity'
network:
  ethernets:
    ens3:
      dhcp4: true
      dhcp-identifier: mac
  version: 2

これにより、Client IDがMACになり、別のIPをもらえる。

/var/lib/libvirt/dnsmasq/virbr0.status
[
  {
    "ip-address": "192.168.122.188",
    "mac-address": "52:54:00:8f:6a:81",
    "hostname": "testing",
    "client-id": "ff:b5:5e:67:ff:00:02:00:00:ab:11:37:05:50:e0:d8:7b:8c:01",
    "expiry-time": 1590583031
  },
  {
    "ip-address": "192.168.122.189",
    "mac-address": "52:54:00:be:82:59",
    "hostname": "testing",
    "client-id": "01:52:54:00:be:82:59",
    "expiry-time": 1590584091
  }
]

MACがユニークならこれでもよさそう…?

machine-idを変更する

ゲストで/etc/machine-idを空にすると新しいmachine-idで起動するみたい。
manページ参照。

machine-id
$ sudo bash -c "echo -n > /etc/machine-id"
$ cat /etc/machine-id 
$

再起動後のlease。抜粋。

[
  {
    "ip-address": "192.168.122.188",
    "mac-address": "52:54:00:8f:6a:81",
    "hostname": "testing",
    "client-id": "ff:b5:5e:67:ff:00:02:00:00:ab:11:37:05:50:e0:d8:7b:8c:01",
    "expiry-time": 1590583031
  },
  {
    "ip-address": "192.168.122.190",
    "mac-address": "52:54:00:be:82:59",
    "hostname": "testing",
    "client-id": "ff:b5:5e:67:ff:00:02:00:00:ab:11:fc:e8:d0:34:46:7c:85:57",
    "expiry-time": 1590584416
  }
]

Client IDが変わるため、別のIPをもらうことができる。

終わりに

DHCPの仕組みだから多分有名なんだろうが、全然知らなくて無知を晒してしまった。

Clone手法については、もっとシンプルな方法があるのかも。

6
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
3