0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Open vSwitch + Libvirt で VLAN over LACP (802.3ad) による VM 間通信

Last updated at Posted at 2025-02-02

LACP による bonding は、基本的に物理的なネットワークスイッチと物理マシンを用いて行われるが、物理環境への移行前の事前検証などで VM 上で LACP を試したいケースがある。
本記事では、KVM 上で Open vSwitch を使い、VM 間で VLAN over LACP を構築する手順を解説する。

  • (1) ホストに Open vSwitch のスイッチを作成する
  • (2) Terraform で VM (Open vSwitch への tap 作成を含む) を自動プロビジョニングする

本記事で説明する VM およびネットワークの構成図は次の通り:

overview.drawio.png

サンプルコード:

前提条件

ホスト OS は Rocky Linux 9.5 を使用する。また、事前に次のソフトウェアがインストールされているものとする:

  • KVM packages
    • qemu-kvm
    • libvirt
  • Terraform
    • crdtools
  • Open vSwtich

1. VM 1 台での LACP 構築

土台となる OVS bridge を手動で作成しておき、portと Linux の ネットワークインタフェース部分を自動で作成する。

1.1 OVS Bridge の作成

ovsbr0 という名前の OVS Bridge を作成する:

$ sudo ovs-vsctl add-br ovsbr0

OVS Bridge ovsbr0 が作成されたことを確認する:

$ sudo ovs-vsctl show
913e15b8-dbd7-4cf9-b6d8-2437a84cc64d
    Bridge ovsbr0
        Port ovsbr0
            Interface ovsbr0
                type: internal
    ovs_version: "3.3.1"

Bridge が作成されると、同名の (例:ovsbr0) Port および Interface のセットが自動的に作成され、これらを削除することはできない。
Bridge と Port は物理スイッチで例えるとそれぞれスイッチ本体と LAN ポートに対応する概念であり、Interface は Linux 上で認識される Network interface で、ip a コマンドから確認できる。

$ ip a
...
4: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether fe:56:9a:a7:6f:8f brd ff:ff:ff:ff:ff:ff
5: ovsbr0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 6a:39:9a:98:50:40 brd ff:ff:ff:ff:ff:ff

本記事では、OVS における Bridge, Port, Interface の構成図を次のように表すことにする。
default.png

1.2 VM の作成

1.2.1 Base image の用意

本記事では VM の OS として Rocky Linux 9.5 を使用する。Rocky Linux 公式の配布ページ よりベースイメージの qcow2 ファイルを /var/lib/libvirt/images にダウンロードする:

$ sudo curl -L -o /var/lib/libvirt/images/Rocky-9-GenericCloud.latest.x86_64.qcow2 https://download.rockylinux.org/pub/rocky/9.2/images/x86_64/Rocky-9-GenericCloud.latest.x86_64.qcow2 

1.2.2 cloudinit file の作成

次のような cloud_init.cfg を用意する。パスワード <ROOT-PASSWORD> は自身が使うものに書き換える:

cloud_init.cfg
#cloud-config
chpasswd:
  list: |
    root:<ROOT-PASSWORD>
  expire: False

1.2.3 Terraform file の作成

本記事では Terraform Libvirt Provider を用いて仮想 VM を自動プロビジョニングする。次の main.tf を作成する:

main.tf
terraform {
  required_providers {
    libvirt = {
      source  = "dmacvicar/libvirt"
      version = "0.8.1"
    }
  }
}

provider "libvirt" {
  uri = "qemu:///system"
}

resource "libvirt_cloudinit_disk" "commoninit" {
  name      = "commoninit.iso"
  user_data = templatefile("cloud_init.cfg", {})
  pool      = "default"
}

resource "libvirt_domain" "vm" {
  name   = "vm1"
  vcpu   = 4
  memory = 4096

  network_interface {
    bridge = "ovsbr0"
  }

  network_interface {
    bridge = "ovsbr0"
  }

  disk {
    volume_id = libvirt_volume.volume.id
  }

  cloudinit = libvirt_cloudinit_disk.commoninit.id

  cpu {
    mode = "host-passthrough"
  }

  graphics {
    type        = "vnc"
    listen_type = "address"
  }

  # Makes the tty0 available via `virsh console`
  console {
    type        = "pty"
    target_port = "0"
    target_type = "serial"
  }
  
  xml {
    xslt = file("${path.module}/tap.xsl")
  }
}

resource "libvirt_volume" "volume" {
  name           = "system.qcow2"
  pool           = "default"
  format         = "qcow2"
  base_volume_id = "/var/lib/libvirt/images/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2"
  size           = 500 * 1024 * 1024 * 1024
}

1.2.4 XSLT patch の作成

次のような XSLT patch を用意̩する:

  • domain に <virtualport type="openvswitch"/> を追加することで、Libvirt が Open vSwitch に対して port を自動的に作成できるようになる。
  • <!-- Enable Open vSwitch support ... のブロックで、tap の名前を固定するようにする。(tap1p<N> のような固定した名前を割り当てる)このように tap 名を固定することが後に重要になる
patch.xsl
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <!-- Identity transform to copy everything as is -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Enable Open vSwitch support and assign a static name to each device -->
  <xsl:template match="/domain/devices/interface[@type='bridge']">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
      <virtualport type="openvswitch"/>
      <target>
        <xsl:attribute name="dev">
          <xsl:value-of select="concat('tap1p', count(preceding::interface[@type='bridge']) + 1)"/>
        </xsl:attribute>
      </target>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

Libvirt domain の Open vSwitch サポートについては
libvirt: Domain XML format #Bridge to LAN を参照。

1.2.5 VM の作成

次のコマンドを実行し、VM を作成する:

$ ls
main.tf  cloud_init.cfg  patch.xsl
$ terraform init --upgrade
$ terraform apply -auto-approve

VM が作成されると、libvirt が次のように tap に対応した ports が自動で作成される(ただし、これらは次のステップですぐに削除する。)。

$ sudo ovs-vsctl show
913e15b8-dbd7-4cf9-b6d8-2437a84cc64d
    Bridge ovsbr0
        Port tap1p1
            Interface tap1p1
        Port tap1p2
            Interface tap1p2
        Port ovsbr0
            Interface ovsbr0
                type: internal
    ovs_version: "3.3.1"

この時点でのネットワーク構成図を表すと下図のようになる:

created.png

1.3 OVS 側の Bonding 設定

libvirt によって自動的作成されたポートを削除する:

sudo ovs-vsctl del-port ovsbr0 tap1p1
sudo ovs-vsctl del-port ovsbr0 tap1p2

次のコマンドを実行し、新たに bond bond-vm1 を作成する:

sudo ovs-vsctl add-bond ovsbr0 bond-vm1 tap1p1 tap1p2 \
        -- set port bond-vm1 \
        lacp=active \
        bond_mode=balance-tcp \
        other_config:lacp-time=fast \
        other_config:bond-hash-policy=layer2+3

bond が作成されたことを確認する:

$ sudo ovs-vsctl show
913e15b8-dbd7-4cf9-b6d8-2437a84cc64d
    Bridge ovsbr0
        Port ovsbr0
            tag: 10
            Interface ovsbr0
                type: internal
        Port bond-vm1
            Interface tap1p1
            Interface tap1p2
    ovs_version: "3.3.1"

この時点でのネットワーク構成図を表すと下図のようになる:

bond.png

1.4 VM 側の Bonding 設定

次のコマンドを実行し、eth0eth1 から成る bond0 を作成する:

nmcli con add type bond con-name bond0 ifname bond0 bond.options "mode=802.3ad,lacp_rate=fast,xmit_hash_policy=layer2+3" ipv6.method disabled  connection.autoconnect-slave 1
nmcli con add type ethernet con-name bond0p0 ifname eth0 master bond0 
nmcli con add type ethernet con-name bond0p1 ifname eth1 master bond0
nmcli con mod bond0 ipv4.method manual ipv4.address 10.0.0.1/24

bond option の説明は本記事では割愛する。

ここで、KVM 特有の設定として、NIC の Speed と Duplex(=通信速度の上限および送受信方式のモード)の設定が必要になる。これは、物理的な NIC と異なり、KVM がデフォルトで使用する NIC モデル virtio には Speed や Duplex の値が設定されていないためである。

この状態のままでは Bonding を有効化できない。試しに、現時点で bond0 の有効化を試みると、次のようなエラーメッセージが延々と表示される:

# nmcli con up bond0
[ 1298.601300] net_ratelimit: 88 callbacks suppressed
[ 1298.601322] bond0: (slave eth1): failed to get link speed/duplex
[ 1298.601325] bond0: (slave eth0): failed to get link speed/duplex
[ 1298.705236] bond0: (slave eth1): failed to get link speed/duplex
[ 1298.705249] bond0: (slave eth0): failed to get link speed/duplex
[ 1298.809231] bond0: (slave eth1): failed to get link speed/duplex
[ 1298.809240] bond0: (slave eth0): failed to get link speed/duplex
[ 1298.913249] bond0: (slave eth1): failed to get link speed/duplex
[ 1298.913261] bond0: (slave eth0): failed to get link speed/duplex
[ 1299.017328] bond0: (slave eth1): failed to get link speed/duplex
[ 1299.017356] bond0: (slave eth0): failed to get link speed/duplex
...

各 Interface に Speed および Duplex がセットされていないことは次のコマンドから確認できる:

# ethtool eth0 | grep -e Speed -e Duplex
    Speed: Unknown!
    Duplex: Unknown! (255)
# ethtool eth1 | grep -e Speed -e Duplex
    Speed: Unknown!
    Duplex: Unknown! (255)

本記事では、各 NIC を 25G Ethernet としてエミュレートすることにする。次のコマンドを実行し、Speed: 2500 [MB/s], Duplex: Full (双方向で同時通信) をセットする:

nmcli con mod bond0p0 \
  802-3-ethernet.speed 2500 \
  802-3-ethernet.duplex full \
  802-3-ethernet.auto-negotiate no
nmcli con mod bond0p1 \
  802-3-ethernet.speed 2500 \
  802-3-ethernet.duplex full \
  802-3-ethernet.auto-negotiate no

設定を反映させる:

nmcli con up bond0

bond0 が正常に起動したことを確認する:

$ nmcli con show
NAME         UUID                                  TYPE      DEVICE
bond0        0be0bec5-fe4f-4394-a93e-6cf99a808623  bond      bond0
bond0p0      30bedb37-1e0e-4b60-b96f-06ee3c3a56eb  ethernet  eth0
bond0p1      3cd0f51f-6d76-4a15-a1f1-b3a66cbc9922  ethernet  eth1
...

virtio に期待される挙動については次のリンクを参照:Why is the KVM guest VM not displaying the Speed: Unknown! and Duplex: Unknown! (255)? - Red Hat Customer Portal

なお、virtio 以外の Device Model Type を使用する場合、上記のように Speed / Duplex を手動で設定する必要はない。たとえば e1000e は 1Gbps、rtl8139 は 100Mbps が既定値として設定されており、ゲストはこの値を自動で取得することができる。

# ethtool <e1000e-device-name> | grep -e Speed -e Duplex
        Speed: 1000Mb/s
        Duplex: Full

# ethtool <rtl8139-device-name> | grep -e Speed -e Duplex
        Speed: 100Mb/s
        Duplex: Full

この時点で、VM 側の Bond と Open vSwitch 側の Bond の間で LACP のネゴシエーションが完了する。
ホスト側で次のコマンドを実行し、bond の lacp_statusnegotiated になっていることを確かめる:

$ sudo ovs-appctl bond/show
---- bond-vm1 ----
bond_mode: balance-tcp
bond may use recirculation: yes, Recirc-ID : 20
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
next rebalance: 5849 ms
lacp_status: negotiated
lacp_fallback_ab: false
active-backup primary: <none>
active member mac: fe:54:00:d6:2b:70(tap1p1)

member tap1p1: enabled
  active member
  may_enable: true

member tap1p2: enabled
  may_enable: true

この時点でのネットワーク構成図を表すと下図のようになる:

bond.png

1.5 VLAN over bonding

ホスト側で次を実行し、Tap の各 port を Trunk port にする:

sudo ovs-vsctl set port bond-vm1 trunks=10,20

各 port が Trunk port になったことを確認する:

$ sudo ovs-vsctl show
913e15b8-dbd7-4cf9-b6d8-2437a84cc64d
    Bridge ovsbr0
        Port ovsbr0
            tag: 10
            Interface ovsbr0
                type: internal
        Port bond-vm1
            trunks: [10, 20]
            Interface tap1p1
            Interface tap1p2
    ovs_version: "3.3.1"

ゲスト側で次を実行し、VLAN ports を作成する:

sudo nmcli con mod bond0 ipv4.method disabled ipv4.address ""
sudo nmcli con add type vlan con-name vlan10 dev bond0 id 10
sudo nmcli con add type vlan con-name vlan20 dev bond0 id 20
sudo nmcli con mod bond0 ipv4.method manual ipv4.address 10.0.10.1/24
sudo nmcli con mod bond0 ipv4.method manual ipv4.address 10.0.20.1/24

VLAN ports bond0.10bond0.20 が作成されたことを確認する:

$ nmcli con show
NAME                UUID                                  TYPE      DEVICE
bond0.10            e56ff19c-ac35-401f-a360-2c6d25b5658b  vlan      bond0.10
bond0.20            cf36a0c3-1768-4cce-93ed-fcb47f56a5cc  vlan      bond0.20
bond0               33b02755-6b66-4e68-b728-c40f53179b2f  bond      bond0
bond0p0             8d0124bd-e3f1-4dbb-8404-63230f8c4386  ethernet  eth0
bond0p1             52a93d2e-ddd6-494d-b89f-6ee06241df58  ethernet  eth1
...

この時点でのネットワーク構成図を表すと下図のようになる:

vlan.png

2. VM 2 台での LACP 構築

2.1. VM の作成

1章の内容をおさえた上で、次の図のような2台の VM による検証環境を改めて自動構築する。

vlan-2vms.png

サブネットの構成だけ表現すれば、次のようなネットワーク構成に過ぎない:
simple.png

さきほど作成した VM と OVS Bridge は削除しておく:

# VM の削除
terraform destroy

# OVS Bridge の削除
sudo ovs-vsctl del-br ovsbr0

改めて OVS Bridge ovsbr0 を作成する:

$ sudo ovs-vsctl add-br ovsbr0

OVS Bridge が作成されたことを確認する:

$ sudo ovs-vsctl show
913e15b8-dbd7-4cf9-b6d8-2437a84cc64d
    Bridge ovsbr0
        Port ovsbr0
            Interface ovsbr0
                type: internal
    ovs_version: "3.3.1"

2.1.1 cloudinit file の作成

次のような cloud_init.cfg を作成する:

cloud_init.cfg
#cloud-config
users:
  - name: root
    ssh-authorized-keys:
      - <SSH_KEY>

runcmd:
  - nmcli con add type bond con-name bond0 ifname bond0 bond.options "mode=802.3ad,lacp_rate=fast,xmit_hash_policy=layer2+3" ipv4.method disabled ipv6.method disabled connection.autoconnect-slave 1
  - nmcli con add type ethernet con-name bond0p0 ifname eth0 master bond0 802-3-ethernet.speed 1000 802-3-ethernet.duplex full 802-3-ethernet.auto-negotiate no
  - nmcli con add type ethernet con-name bond0p1 ifname eth1 master bond0 802-3-ethernet.speed 1000 802-3-ethernet.duplex full 802-3-ethernet.auto-negotiate no
  - nmcli con add type vlan con-name bond0.10 dev bond0 id 10 ipv4.method manual ipv4.address ${vlan10_ipv4_address} connection.autoconnect yes
  - nmcli con add type vlan con-name bond0.20 dev bond0 id 20 ipv4.method manual ipv4.address ${vlan20_ipv4_address} connection.autoconnect yes
  - nmcli con up bond0

2.1.2 XSLT patch の作成

次の XLST patch を作成する。なお、1章で使用したものと異なるのは <xsl:value-of ... で tap の prefix も自動で決定するようにした点であり、残りの部分は同じである。

tap.xsl.template
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <!-- Identity transform to copy everything as is -->
  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <!-- Enable Open vSwitch support and assign a static name to each device -->
  <xsl:template match="/domain/devices/interface[@type='bridge']">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
      <virtualport type="openvswitch"/>
      <target>
        <xsl:attribute name="dev">
          <xsl:value-of select="concat('${tap_prefix}p', count(preceding::interface[@type='bridge']) + 1)"/>
        </xsl:attribute>
      </target>
    </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

2.1.3 Terraform file の作成

次の main.tf を作成する:

main.tf
terraform {
  required_providers {
    libvirt = {
      source  = "dmacvicar/libvirt"
      version = "0.8.1"
    }
  }
}

provider "libvirt" {
  uri = "qemu:///system"
}

resource "libvirt_cloudinit_disk" "commoninit" {
  count     = 2
  name      = "commoninit_${count.index}.iso"
  user_data = templatefile("cloud_init.cfg", {
    vlan10_ipv4_address = "10.0.10.${count.index + 1}/24"
    vlan20_ipv4_address = "10.0.20.${count.index + 1}/24"
  })
  pool      = "default"
}

resource "libvirt_domain" "vm" {
  count  = 2
  name   = "vm${count.index}"
  vcpu   = 4
  memory = 4096

  network_interface {
    bridge = "ovsbr0"
  }

  network_interface {
    bridge = "ovsbr0"
  }

  disk {
    volume_id = libvirt_volume.volume[count.index].id
  }

  cloudinit = libvirt_cloudinit_disk.commoninit[count.index].id

  cpu {
    mode = "host-passthrough"
  }

  graphics {
    type        = "vnc"
    listen_type = "address"
  }

  # Makes the tty0 available via `virsh console`
  console {
    type        = "pty"
    target_port = "0"
    target_type = "serial"
  }
  
  xml {
    xslt = templatefile("tap.xsl.template", {
      tap_prefix = "tap${count.index + 1}"
    })
  }
}

resource "libvirt_volume" "volume" {
  count          = 2
  name           = "system_${count.index}.qcow2"
  pool           = "default"
  format         = "qcow2"
  base_volume_id = "/var/lib/libvirt/images/Rocky-9-GenericCloud-Base.latest.x86_64.qcow2"
  size           = 500 * 1024 * 1024 * 1024
}

次のコマンドで VM を作成する

$ terraform init --upgrade
$ terraform apply --auto-approve

2.2 Open vSwitch の設定

VM 1台のときと同様に、自動作成される OVS 側の port を削除して、新たに bond bond-vm1 および bond-vm2 を作成する:

# Delete the existing ports
sudo ovs-vsctl del-port ovsbr0 tap1p1
sudo ovs-vsctl del-port ovsbr0 tap1p2
sudo ovs-vsctl del-port ovsbr0 tap2p1
sudo ovs-vsctl del-port ovsbr0 tap2p2

# Creating new bonds 
# 1. Set each LACP port to active mode
# 2. Set each bond as balance-tcp mode
# 3. Accelerate LACP negotiation by setting it to fast mode
# 4. Use layer2+3 policy 
# 5. Configure the bond to allow VLAN trunking for VLANs
sudo ovs-vsctl add-bond ovsbr0 bond-vm1 tap1p1 tap1p2 \
        -- set port bond-vm1 \
        lacp=active \
        bond_mode=balance-tcp \
        other_config:lacp-time=fast \
        other_config:bond-hash-policy=layer2+3 \
        trunks=10,20
sudo ovs-vsctl add-bond ovsbr0 bond-vm2 tap2p1 tap2p2 \
        -- set port bond-vm2 \
        lacp=active \
        bond_mode=balance-tcp \
        other_config:lacp-time=fast \
        other_config:bond-hash-policy=layer2+3 \
        trunks=10,20

bond が作成されたことを確認する:

$ sudo ovs-vsctl show
913e15b8-dbd7-4cf9-b6d8-2437a84cc64d
    Bridge ovsbr0
        Port ovsbr0
            tag: 10
            Interface ovsbr0
                type: internal
        Port bond-vm2
            trunks: [10, 20]
            Interface tap2p1
            Interface tap2p2
        Port bond-vm1
            trunks: [10, 20]
            Interface tap1p1
            Interface tap1p2
    ovs_version: "3.3.1"

lacp_statusnegotiated になっていることを確認する:

$ sudo ovs-appctl bond/show
---- bond-vm2 ----
bond_mode: balance-tcp
bond may use recirculation: yes, Recirc-ID : 23
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
next rebalance: 5593 ms
lacp_status: negotiated
lacp_fallback_ab: false
active-backup primary: <none>
active member mac: fe:54:00:72:d3:42(tap2p2)

member tap2p1: enabled
  may_enable: true

member tap2p2: enabled
  active member
  may_enable: true

---- bond-vm1 ----
bond_mode: balance-tcp
bond may use recirculation: yes, Recirc-ID : 22
bond-hash-basis: 0
lb_output action: disabled, bond-id: -1
updelay: 0 ms
downdelay: 0 ms
next rebalance: 5593 ms
lacp_status: negotiated
lacp_fallback_ab: false
active-backup primary: <none>
active member mac: fe:54:00:d6:2b:70(tap1p1)

member tap1p1: enabled
  active member
  may_enable: true

member tap1p2: enabled
  may_enable: true

3. 疎通テスト

3.1 (Optional) VM ネットワークにホストを接続する

VM 上にツールを導入する際には、事前に何かしらホスト経由でネットワーク接続する必要がある(例えばホストからパッケージを直接送信したり、あるいは VM をインターネットに接続してツールをインストールする)。本節では、次の図のように、ホストを VM のネットワーク VLAN 10 に接続し、かつ NAT 化して VM からインターネットに接続できるようにする (必ずしも本記事のやり方に従う必要はない)。

nat.drawio.png

3.1.1 ホストを VLAN 10 に接続する

ホスト側で次の設定を行い、VLAN 10 にアクセスするための Interface を作成する:

  • Port ovsbr0 を VLAN 10 の access port にする
  • Interface ovsbr0 に IP 10.0.10.100 を設定する
  • Subnet 10.0.10.0/24 への route を追加する
sudo ovs-vsctl set port ovsbr0 tag=10
sudo ip addr add 10.0.10.100/24 dev ovsbr0
sudo ip link set ovsbr0 up
sudo ip route add 10.0.10.0/24 dev ovsbr0

ホストから VM1 / VM2 に ping が到達することを確認する:

$ ping 10.0.10.1
$ ping 10.0.10.2

3.1.2 ホストを NAT 化する

VM をインターネットに接続する場合は、ホスト上で次のコマンドを実行して NAT 化する:

# IP forwarding の有効化
echo 1 > /proc/sys/net/ipv4/ip_forward
# 反映
sysctl -p

masquerade を有効化する:

firewall-cmd --permanent --add-masquerade
firewall-cmd --reload

3.1.3 VM 側からのインターネット接続を確認する

VM1, VM2 側で VLAN 10 の interface に gateway と dns を追加する:

[root@vm1 ~]$ nmcli con mod bond0.10 ipv4.gateway 10.0.10.100 ipv4.dns "8.8.4.4 8.8.8.8"

インターネットに接続できることを確かめる:

[root@vm1 ~]$ ping google.com

3.2 VLAN の疎通テスト

各 VM にパケットキャプチャツール tcpdump をインストールする:

sudo dnf install -y tcpdump

Node 1 から Node 2 に VLAN 10 経由で ping する:

ping 10.0.10.2

この状態のまま、tcpdump を起動し、Node 2 側で VLAN 10 のパケットのみをキャプチャする (SSH login した状態だと、そのパケットも拾ってしまってログが見づらいので、not port 22 も指定しておく):

# tcpdump -i bond0 not port 22 and vlan 10
dropped privs to tcpdump 
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on bond0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
15:58:06.622076 IP 10.0.20.1 > localhost: ICMP echo request, id 8, seq 69, length 64
15:58:06.622132 IP localhost > 10.0.20.1: ICMP echo reply, id 8, seq 69, length 64
...

image1.png

指定したパケットをキャプチャできていることが確認できる。

同様に、宛先 の IP とキャプチャする VLAN tag の組み合わせを変えて実験すると、次の表に示す結果が得られる:

宛先 IP キャプチャする VLAN tag キャプチャ可否
10.0.10.1 10 success
10.0.10.2 10 success
10.0.20.1 10 failure
10.0.20.2 10 failure
10.0.10.1 20 failure
10.0.10.2 20 failure
10.0.20.1 20 success
10.0.20.2 20 success

3.3 LACP 動作テスト

各 VM に、次のツールをインストールする:

  • sysstat: マシンリソースのモニタリング
  • iperf3: ネットワーク用のパフォーマンス測定
sudo dnf install -y sysstat
sudo dnf install -y iperf3

iperf で VM1 から VM2 にパケットを送信する。

VM2 側で次を実行:

[root@vm2 ~]# iperf3 -s

VM1 側で次を実行

[root@vm1 ~]# perf3 -c 10.0.10.1

VM2 側で NIC の使用率を観測する:

[root@vm2 ~]# sar -n DEV 1 5

rxkB/s 列が受信パケットに関するログである。各 interface eth0, eth1 にパケットが分散されていることを確認する。

measurement.png

3.4 (Optional) 検証環境のクリーンアップ

VM を削除する:

terraform destroy

OVS Bridge を削除する:

sudo ovs-vsctl del-br ovsbr0

ホストの NAT 設定を削除:

$ echo 0 > /proc/sys/net/ipv4/ip_forward
$ firewall-cmd --permanent --remove-masquerade

参考資料

Libvirt + Open vSwitch に関する資料

Terraform Libvirt Provider + Open vSwitch に関する資料

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?