Назад | Перейти на главную страницу

Настройка маршрутизации во вложенном кластере виртуализации на vagrant / hyper-v / libvirt

Я пытаюсь настроить конкретный кластер виртуальных машин с помощью vagrant на моем локальном ноутбуке. У меня Win10 Pro с HyperV в качестве хоста. К сожалению, я не могу его изменить, поэтому я хочу создать виртуальную машину Linux на HyperV (я назвал ее «вложенной») с включенной вложенной виртуализацией. Затем во «вложенном» Linux я хочу создать несколько виртуальных машин с помощью KVM / libvirt. Для простоты в примере кода только один («гость»).

Предполагается, что необходимо выполнить минимальную настройку на Windows Host и подготовить все с помощью Vagrant. Но на самом деле это не так просто, потому что провайдер HyperV не позволяет настраивать статический IP-адрес как в общедоступных, так и в частных интерфейсах.

Цель состоит в том, чтобы создать частную сеть (например, 10.75.10.0/24) и назначить каждой виртуальной машине статический IP-адрес и разрешить видеть друг друга. Я частично добился этого. Мои виртуальные машины могут пинговать друг друга, кроме вложенной ('guest1' <-> 'guest2', 'guest' <-> Host, Host <-> Nested). guest <-> nested не видят друг друга в обоих направлениях.

Требования: 1. Win10 с включенным HyperV 2. Пользователь должен быть в группе администратора HyperV.

Я создал внутренний переключатель в Host с помощью сценария PowerShell (Adm):

New-VMSwitch –SwitchName “NAT-Switch” –SwitchType Internal –Verbose
Get-NetAdapter
#put the proper index in the next line
New-NetIPAddress –IPAddress 10.75.0.1 -PrefixLength 24 -InterfaceIndex 16 –Verbose
New-NetNat –Name NATNetwork –InternalIPInterfaceAddressPrefix 10.75.0.0/24 –Verbose
Get-VM | Get-VMNetworkAdapter | Connect-VMNetworkAdapter –SwitchName “NAT-Switch”

ipconfig:

Ethernet adapter vEthernet (NAT-Switch):

   Connection-specific DNS Suffix  . :
   Description . . . . . . . . . . . : Hyper-V Virtual Ethernet Adapter #5
   Physical Address. . . . . . . . . : XXXX
   DHCP Enabled. . . . . . . . . . . : No
   Autoconfiguration Enabled . . . . : Yes
   Link-local IPv6 Address . . . . . : XXXX
   IPv4 Address. . . . . . . . . . . : 10.75.10.1(Preferred)
   Subnet Mask . . . . . . . . . . . : 255.255.255.0
   Default Gateway . . . . . . . . . :
   DNS Servers . . . . . . . . . . . : fec0:0:0:ffff::1%1
                                       fec0:0:0:ffff::2%1
                                       fec0:0:0:ffff::3%1
   NetBIOS over Tcpip. . . . . . . . : Enabled

Это моя структура проекта:

./nested
./nested/Vagrantfile
./provision.sh
./Vagrantfile

кошка Vagrantfile

$bridge_script = <<EOF
    ifconfig eth0 10.75.10.10 netmask 255.255.255.0 up
    route add default gw 10.75.10.1
EOF

Vagrant.configure("2") do |config|

    config.vm.box = "generic/ubuntu1804"
    config.vm.define "nested"
    config.vm.hostname = "nested"
    config.vm.provider "hyperv" do |hv|
        hv.cpus = "2"
        hv.memory = "2048"
        hv.maxmemory = "2048"
        hv.enable_virtualization_extensions = true
        hv.differencing_disk = true
    end

    config.vm.network "public_network", :bridge => "NAT-Switch", auto_config: false
    config.vm.provision :"shell", run: "always", inline: $bridge_script
    config.vm.provision :file, source: "nested", destination: "~/"
    config.vm.provision :shell, :path => "provision.sh"
    config.vm.provision :shell, inline: "sudo -i -u vagrant bash -c 'cd ~vagrant/nested; vagrant up --provider=libvirt'"

end

cat provision.sh

apt-get update
apt-get install -y bridge-utils qemu-kvm virtinst libvirt-bin qemu-utils qemu ebtables dnsmasq vagrant vagrant-libvirt
usermod -aG libvirt-qemu,libvirt vagrant
systemctl enable libvirt-bin
systemctl start libvirt-bin
vagrant plugin install vagrant-libvirt
vagrant plugin list

кошка вложена / Vagrantfile

Vagrant.configure("2") do |config|
        config.vm.box = "generic/ubuntu1604"
        config.vm.define "guest"
        config.vm.network "public_network", ip: "10.75.10.11", netmask: "24"
        config.vm.hostname = "guest"

        config.vm.provider :libvirt do |libvirt|
                libvirt.uri = 'qemu+unix:///system'
                libvirt.cpus = "1"
                libvirt.memory = "1024"
        end
end

После запуска:

vagrant --provider=hyperv

Получаю такой результат:

вложенная ВМ:

vagrant @ nested: ~ $ ip адрес

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:15:5d:38:01:5c brd ff:ff:ff:ff:ff:ff
    inet 10.75.10.10/24 brd 10.75.10.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::215:5dff:fe38:15c/64 scope link
       valid_lft forever preferred_lft forever
3: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:6f:8e:84 brd ff:ff:ff:ff:ff:ff
    inet 192.168.122.1/24 brd 192.168.122.255 scope global virbr0
       valid_lft forever preferred_lft forever
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:6f:8e:84 brd ff:ff:ff:ff:ff:ff
5: virbr1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:6c:f9:2f brd ff:ff:ff:ff:ff:ff
    inet 192.168.121.1/24 brd 192.168.121.255 scope global virbr1
       valid_lft forever preferred_lft forever
6: virbr1-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master virbr1 state DOWN group default qlen 1000
    link/ether 52:54:00:6c:f9:2f brd ff:ff:ff:ff:ff:ff
7: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master virbr1 state UNKNOWN group default qlen 1000
    link/ether fe:54:00:bc:01:c9 brd ff:ff:ff:ff:ff:ff
8: macvtap0@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 500
    link/ether 52:54:00:a7:eb:55 brd ff:ff:ff:ff:ff:ff

vagrant @ nested: ~ $ route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         10.75.10.1      0.0.0.0         UG    0      0        0 eth0
10.75.10.0      0.0.0.0         255.255.255.0   U     0      0        0 eth0
192.168.121.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr1
192.168.122.0   0.0.0.0         255.255.255.0   U     0      0        0 virbr0

Для ВМ1:

vagrant @ guest: ~ $ ip адрес

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:bc:01:c9 brd ff:ff:ff:ff:ff:ff
    inet 192.168.121.45/24 brd 192.168.121.255 scope global eth0
       valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 52:54:00:a7:eb:55 brd ff:ff:ff:ff:ff:ff
    inet 10.75.10.11/24 brd 10.75.10.255 scope global eth1
       valid_lft forever preferred_lft forever

бродяга @ гость: ~ $ route -n

Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.121.1   0.0.0.0         UG    0      0        0 eth0
10.75.10.0      0.0.0.0         255.255.255.0   U     0      0        0 eth1
192.168.121.0   0.0.0.0         255.255.255.0   U     0      0        0 eth0

Надеюсь, кому-то удастся воссоздать состояние. Я предоставил 99% автоматизированных скриптов.

Возникает вопрос: как я могу улучшить эту настройку, чтобы сделать вложенную виртуальную машину видимой? Манипуляции с адресацией интерфейсов и маршрутизацией приводят к долгому перерыву в работе vagrant. Могу я также это улучшить? Есть ли лучший способ настроить сеть во вложенной виртуальной машине?