dnsmasqは悪くなかった。ごめんよ。
ホスト:Ubuntu 19.10 / libvirtd 5.4.0
VM:Ubuntu 20.04 LTS
事象
- libvirt(KVM)でUbuntu VMを作り、default networkに接続する。
-
virt-clone
する。 - 起動する。
結果
同じIPが振られる。
default networkの例。
<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する。
$ 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を返す」ような謎挙動に見える。
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 ID(DUID)で管理されている。
-
virt-clone
したUbuntu VMではClient IDが同じになるため、LeaseからIPを返す。
この結果、cloneしたVMには同じIPを振り続けてしまう。
1台目、Option61にClient Identifierがある。
2台目、同じ値である!
leaseを見ても、同じClient IDであることがわかる。
場所は/var/lib/libvirt/dnsmasq/<interface>.status
、libvirt用の形式で通常のdnsmasqとは異なる。(この辺の事情)
1台目起動。
[
{
"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台目起動。
[
{
"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))
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))
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
を追加。
# This is the network config written by 'subiquity'
network:
ethernets:
ens3:
dhcp4: true
dhcp-identifier: mac
version: 2
これにより、Client IDがMACになり、別のIPをもらえる。
[
{
"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ページ参照。
$ 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手法については、もっとシンプルな方法があるのかも。