web-dev-qa-db-ja.com

Ubuntu 16.04とKVMでは、NATを使用せずにvmsをネットワークに接続できません

ローカルネットワーク上に独自の物理ネットワークインターフェイスがあるかのように動作するKVMで実行されているvmを取得しようとしています。これはブリッジングと呼ばれるものだと思いますが、オンラインでさまざまなガイドに従ってみましたが、うまくいきませんでした。ローカルネットワークと通信できない仮想ネットワークアダプターを備えたVMになるたびに。

私のホストとゲストはすべてUbuntuサーバー16.04を実行しています。

br0/etc/network/interfacesファイルに追加することから始めました。このファイルは次のようになります。

~$ cat /etc/network/interfaces
source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

iface enp2s0 inet manual

auto br0
iface br0 inet dhcp
  bridge_ports enp2s0
  bridge_stp off
  bridge_fd 0
  bridge_maxwait 0

再起動後、ifconfigは次のようになります。

~$ ifconfig
br0       Link encap:Ethernet  HWaddr d0:50:99:c0:25:fb
          inet addr:192.168.113.2  Bcast:192.168.113.255  Mask:255.255.255.0
          ...

docker0   Link encap:Ethernet  HWaddr 02:42:dc:4f:96:9e
          ...

enp2s0    Link encap:Ethernet  HWaddr d0:50:99:c0:25:fb
          inet6 addr: fe80::d250:99ff:fec0:25fb/64 Scope:Link
          ...

lo        Link encap:Local Loopback
          ...

veth009cb0a Link encap:Ethernet  HWaddr 66:d6:6c:e7:80:cb
          inet6 addr: fe80::64d6:6cff:fee7:80cb/64 Scope:Link
          ...

virbr0    Link encap:Ethernet  HWaddr 52:54:00:1a:56:65
          inet addr:192.168.122.1  Bcast:192.168.122.255  Mask:255.255.255.0
          ...

ホストにはDHCPサーバーに静的なエントリがあるため、常に192.168.113.2を取得するため、br0のIPは正しいものになります。私が理解しているように、今やるべきことは、br0インターフェイスを使用して新しいvmを開始することだけです。だから私はこれを実行します:

Sudo virt-install --virt-type=kvm --name myvm \
--hvm --ram 4096 --vcpus=2 --graphics vnc \
--network bridge=br0 \
--os-type=linux --os-variant=ubuntu16.04 \
--cdrom=/var/lib/libvirt/boot/ubuntu-16.04.2-server-AMD64.iso \
--disk path=/var/lib/libvirt/images/myvm.qcow2,size=16,bus=virtio,format=qcow2

この時点でVNCをvmにインストールしてインストールを進め、「DHCPでネットワークを構成する」フェーズに到達するまで進みます。このフェーズではタイムアウトし、IPを取得できません。

デフォルトのNATインターフェースを使用すると、正常に動作し、192.168.112.xxxの範囲でIPを取得し、ローカルネットワークとインターネットにアクセスできます。問題ありません。この作業中のvmのvirsh構成を変更してbr0にブリッジすると、ローカルまたはその他のネットワークと通信できなくなります。 DHCPはIPの取得に失敗し、静的IPを設定しても外部のトラフィックは生成されません。

役に立つ場合は、インストーラーの実行中に別のターミナルを開き、ホストから詳細情報を取得しました。

~$ brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.d05099c025fb       no              enp2s0
                                                        vnet0
docker0         8000.0242dc4f969e       no              veth009cb0a
virbr0          8000.5254001a5665       yes             virbr0-nic

~$ brctl showmacs br0
port no mac addr                is local?       ageing timer
  1     00:04:20:eb:7e:96       no                 3.90
  1     00:11:32:63:9c:cf       no                 1.86
  1     30:46:9a:0f:81:cd       no                 3.39
  1     44:8a:5b:9e:d1:90       no                 0.00
  1     88:de:a9:13:86:48       no                 0.29
  1     b8:ae:ed:73:3e:ca       no                 3.89
  1     d0:50:99:c0:25:fb       yes                0.00
  1     d0:50:99:c0:25:fb       yes                0.00
  1     d0:50:99:e0:21:46       no                 2.90
  1     f0:f6:1c:e3:7f:be       no               173.56
  2     fe:54:00:6f:b8:64       yes                0.00
  2     fe:54:00:6f:b8:64       yes                0.00

~$ ip route
default via 192.168.113.1 dev br0
172.17.0.0/16 dev docker0  proto kernel  scope link  src 172.17.0.1
192.168.113.0/24 dev br0  proto kernel  scope link  src 192.168.113.2
192.168.122.0/24 dev virbr0  proto kernel  scope link  src 192.168.122.1 linkdown

誰かが望むなら、ここにdumpxml全体を投げ入れても構いませんが、ここにネットワークセクションのみを示します。

<interface type='bridge'>
  <mac address='52:54:00:6f:b8:64'/>
  <source bridge='br0'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

PDATE 2017-03-25:以下を変更することにより:

    <interface type='network'>
      <mac address='52:54:00:6f:b8:64'/>
      <source network='default'/>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>

その後、NATが機能し、192.168.122.xxx IPを取得し、外部サービスなどと通信できます。ホストbr0に何か問題がありますか?もしそうなら、なぜホストはそれでうまくIPを取得するのですか?ブリッジングをサポートしていないイーサネットデバイスはありますか?ホストでのlspciの結果は次のとおりです。

~$ lspci | grep Ethernet
02:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)
03:00.0 Ethernet controller: Intel Corporation I210 Gigabit Network Connection (rev 03)

2番目のイーサネットコントローラーをまったくセットアップしていません。セットアップして、代わりにそのブリッジを試みます。

PDATE 2017-03-25 b:2番目のインターフェイスは結果を変更するようには見えませんでした。結果の/ etc/network/interfacesは次のとおりです。

source /etc/network/interfaces.d/*

auto lo
iface lo inet loopback

auto enp2s0
iface enp2s0 inet dhcp

auto enp3s0
iface enp3s0 inet manual

auto br0
iface br0 inet dhcp
  bridge_ports enp3s0
  bridge_stp off
  bridge_fd 0
  bridge_maxwait 0

ip aの場合、結果は次のようになります。

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
    inet6 ::1/128 scope Host
      valid_lft forever preferred_lft forever
2: enp2s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether d0:50:99:c0:25:fb brd ff:ff:ff:ff:ff:ff
    inet 192.168.113.2/24 brd 192.168.113.255 scope global enp2s0
      valid_lft forever preferred_lft forever
    inet6 fe80::d250:99ff:fec0:25fb/64 scope link
      valid_lft forever preferred_lft forever
3: enp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master br0 state UP group default qlen 1000
    link/ether d0:50:99:c0:25:fa brd ff:ff:ff:ff:ff:ff
    inet6 fe80::d250:99ff:fec0:25fa/64 scope link
      valid_lft forever preferred_lft forever
4: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether d0:50:99:c0:25:fa brd ff:ff:ff:ff:ff:ff
    inet 192.168.113.100/24 brd 192.168.113.255 scope global br0
      valid_lft forever preferred_lft forever
    inet6 fe80::d250:99ff:fec0:25fa/64 scope link
      valid_lft forever preferred_lft forever
5: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether 52:54:00:1a:56:65 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
6: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN group default qlen 1000
    link/ether 52:54:00:1a:56:65 brd ff:ff:ff:ff:ff:ff
7: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:18:2c:73:bb brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 scope global docker0
      valid_lft forever preferred_lft forever
    inet6 fe80::42:18ff:fe2c:73bb/64 scope link
      valid_lft forever preferred_lft forever
9: vethaa3cd40@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default
    link/ether ae:05:f7:1b:f9:9e brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::ac05:f7ff:fe1b:f99e/64 scope link
      valid_lft forever preferred_lft forever
10: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br0 state UNKNOWN group default qlen 1000
    link/ether fe:54:00:3a:54:b3 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::fc54:ff:fe3a:54b3/64 scope link
      valid_lft forever preferred_lft forever

VMには、br0を使用するように指示されたときに、まったく同じ問題が引き続き発生します。

3
brakeley

解決しました。

問題は、ブリッジされたパケットをiptablesに送信するbr_netfilterモジュールのデフォルト設定でした。 libvirtのドキュメントでは ネットワークページ で言及されていますが、これまで私が従ってきたほとんどのチュートリアルではカバーしていませんでした。

何らかの理由でiptablesはそれらのパケットを食べていました(おそらくdockerが追加されたのでしょうか?).

ここで説明する方法は、実際には sysctl.d manpage の例です。

/etc/udev/rules.d/99-bridge.rulesを作成し、次の行を挿入します。

ACTION=="add", SUBSYSTEM=="module", KERNEL=="br_netfilter", RUN+="/lib/systemd/systemd-sysctl --prefix=/net/bridge"

次に、/etc/sysctl.d/bridge.confを作成し、次の3行を挿入します。

net.bridge.bridge-nf-call-ip6tables = 0
net.bridge.bridge-nf-call-iptables = 0
net.bridge.bridge-nf-call-arptables = 0

その後、元のブリッジ設定に戻す必要がありました。これには、次のような/etc/network/interfacesが含まれます。

source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto enp2s0
iface enp2s0 inet manual
auto br0
iface br0 inet dhcp
  bridge_ports enp2s0
  bridge_stp off
  bridge_fd 0
  bridge_maxwait 0

そして、次のようなvirshネットワークインターフェイスの定義:

<interface type='bridge'>
  <mac address='52:54:00:37:e1:55'/>
  <source bridge='br0'/>
  <model type='virtio'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

すべての準備が整ったら、VMが起動し、IPを取得し、ホスト、ローカルネットワーク、インターネットと自由に会話できます。

2
brakeley

ブリッジの代わりに直接使用して、動作するようにしました:

これを使用して/etc/network/interfaces

source /etc/network/interfaces.d/*
auto lo
iface lo inet loopback
auto enp2s0
iface enp2s0 inet dhcp
auto enp3s0
iface enp3s0 inet manual

そして、このvirshセットアップ:

<interface type='direct'>
  <mac address='52:54:00:37:e1:55'/>
  <source dev='enp3s0' mode='vepa'/>
  <target dev='macvtap0'/>
  <model type='rtl8139'/>
  <alias name='net0'/>
  <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
</interface>

私のローカルネットワークは、52:54:00:37:e1:55 MACアドレスを確認し、DHCPサーバーがIPを提供し、そのIPを介してこのマシンにsshで接続できるため、すべてが正常に思えます。 2番目のVMを同時に実行できます。そのMACもIPを取得するため、必要な解決策があるようです。

次に、元のイーサネットポートでこれらすべてを試してみます。また、これを読んでいる人が答えを持っている場合、ブリッジングが本当に何であり、それがその直接を解決するものはそうではありません。ありがとう!

UPDATE:このソリューションの問題は、単一の物理インターフェースを共有しているVMが相互に通信できないことです。ホストとVMが同じ物理インターフェイスを共有する場合、ホストについても同様です。

これは、ブリッジングが解決するはずの問題であると思われますが、このような経験がある人からのガイダンスを実際に使用できます。

1
brakeley