最新版は以下に記載しました。
https://hana-shin.hatenablog.com/entry/2022/06/05/214523
#1 はじめに
仮想ブリッジやtunデバイスの仕組みを調べるための環境を構築します。
本記事では環境構築のみ。
図1のKVMホスト環境に仮想ブリッジ(br1)を作成し、
仮想マシン(vm3,vm4)のNICを仮想ブリッジ(br1)に接続します。
最終的に図2の環境を作成します。図中の[]
内はインタフェース名を表します。
+----- vm3 -----+ +----- vm4 -----+
| | | |
| | | |
| | | |
| | | |
| | | |
+--- [eth0]-----+ +--- [eth0] ----+
| .10 | .20
| |
| 192.168.122.0/24 |
| |
+--- [vnet0] ---------------- virbr0 ---------------- [vnet1] ---+
| |
| |
+------------------------- [virbr0-nic] -------------------------+
VM3とVM4のNICは、10.0.0.0/8
のネットワークに所属するように作成します。
VM3のeth1は10.0.0.30
、VM4のeth1は10.0.0.40
に設定します。
10.0.0.0/8
+----- vm3 -----+ +-- br1 --+ +----- vm4 -----+
| | | | | |
| |.30 | | .40| |
| [eth1] --- [vnet2] [vent3] --- [eth1] |
| | | | | |
| | | | | |
+--- [eth0]-----+ +---------+ +--- [eth0] ----+
| .10 | .20
| |
| 192.168.122.0/24 |
| |
+--- [vnet0] ---------------- virbr0 ---------------- [vnet1] ---+
| |
| |
+------------------------- [virbr0-nic] -------------------------+
#2 環境
VMware Workstation 15 Playerで作成した仮想マシンを使用しました。
仮想マシンの中に仮想マシンを作る、いわゆるNested VMを使って、環境を構築しました。
Nested VMの作り方は、ここ(Nested VMの作り方)を参照してください。
なお、KVMホスト、および仮想マシン(VM3,VM4)のOS版数は以下のとおりです。
[root@kvm ~]# cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)
[root@kvm ~]# uname -r
3.10.0-957.el7.x86_64
KVMホストのvirshコマンドの版数は以下のとおりです。
[root@kvm ~]# virsh -v
4.5.0
#3 環境作成手順
##3.1 仮想ブリッジの作成
KVMホスト仮想にブリッジ(br1)を作成します。
[root@kvm ~]# ip l add br1 type bridge
仮想ブリッジの状態を確認します。状態がDOWNしていることがわかります。
[root@kvm ~]# ip l show dev br1
8: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 6a:d7:01:c0:b7:7b brd ff:ff:ff:ff:ff:ff
仮想ブリッジの状態をUPにします。
[root@kvm ~]# ip l set dev br1 up
仮想ブリッジの状態を確認します。状態がUPしていることがわかります。
[root@kvm ~]# ip l show dev br1
8: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether fe:54:00:65:1c:2a brd ff:ff:ff:ff:ff:ff
##3.2 NICの追加(VM3)
仮想マシンが実行中のとき、VM3とVM4にNICを追加します。
VM3,VM4ともに実行中であることがわかります。
なお、virshコマンドの使い方は、ここ(virshコマンドの使い方)を参照してください。
[root@kvm ~]# virsh list
Id 名前 状態
----------------------------------------------------
1 vm3 実行中
2 vm4 実行中
VM3にNICを追加します。
[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model virtio vm3
インターフェースが正常に接続できました
仮想ブリッジのvnet1にVM3のNIC(52:54:00:65:1c:2a
)が追加されたことがわかります。
[root@kvm ~]# virsh domiflist vm3
インターフェース 種類 ソース モデル MAC
-------------------------------------------------------
vnet0 network default virtio 52:54:00:5e:65:7a
vnet2 bridge br1 virtio 52:54:00:4f:ae:b2
次にIPアドレスを設定するため、VM3にsshでログインします。
NetworkManagerを停止します。
動作していると、設定したIPアドレスが消えてしまうことがあるので(原因不明)、
ここでは、NetworkManagerを停止した状態にしてみます。
[root@vm3 ~]# systemctl stop NetworkManager
VM3のeth1にIPアドレスを設定します。
[root@vm3 ~]# ip addr add 10.0.0.30/8 dev eth1
インタフェース(eth1)のリンクアップをします。
[root@vm3 ~]# ip link set eth1 up
##3.3 NICの追加(VM4)
VM4にNICを追加します。
[root@kvm ~]# virsh attach-interface --type bridge --source br1 --model virtio vm4
インターフェースが正常に接続できました
仮想ブリッジのvnet3にVM4のNIC(52:54:00:f4:c1:9a
)が追加されたことがわかります。
[root@kvm ~]# virsh domiflist vm4
インターフェース 種類 ソース モデル MAC
-------------------------------------------------------
vnet1 network default virtio 52:54:00:35:03:3f
vnet3 bridge br1 virtio 52:54:00:05:06:0f
次にIPアドレスを設定するため、VM4にsshでログインします。
NetworkManagerを停止します。
動作していると、設定したIPアドレスが消えてしまうことがあるので(原因不明)、
ここでは、NetworkManagerを停止した状態にしてみます。
[root@vm4 ~]# systemctl stop NetworkManager
VM4のeth1にIPアドレスを設定します。
[root@vm4 ~]# ip addr add 10.0.0.40/8 dev eth1
インタフェース(eth1)のリンクアップをします。
[root@vm4 ~]# ip link set eth1 up
#4 動作確認
##4.1 デバイスの確認
br1が本記事で作成した仮想ブリッジです。
[root@kvm ~]# ip l show type bridge
3: virbr0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:80:1d:d6 brd ff:ff:ff:ff:ff:ff
8: br1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
link/ether fe:54:00:0a:6e:3b brd ff:ff:ff:ff:ff:ff
vnet2,vnet3が本記事で作成したtunデバイスです。
ともに、仮想ブリッジ(br1)のインタフェースです。
vnet2はVM3、vnet3はVM4と接続しています。
[root@kvm ~]# ip l show type tun
4: virbr0-nic: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast master virbr0 state DOWN mode DEFAULT group default qlen 1000
link/ether 52:54:00:80:1d:d6 brd ff:ff:ff:ff:ff:ff
5: vnet0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether fe:54:00:5e:65:7a brd ff:ff:ff:ff:ff:ff
6: vnet1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master virbr0 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether fe:54:00:35:03:3f brd ff:ff:ff:ff:ff:ff
9: vnet2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br1 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether fe:54:00:0a:6e:3b brd ff:ff:ff:ff:ff:ff
10: vnet3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br1 state UNKNOWN mode DEFAULT group default qlen 1000
link/ether fe:54:00:aa:d6:7a brd ff:ff:ff:ff:ff:ff
##4.2 pingによる確認
VM3(eth1)からVM4(eth1)に対してpingを1回実行してみます。
VM4から応答が返ってきていることがわかります。
なお、pingの使い方は、pingコマンドの使い方を参照してください。
[root@vm3 ~]# ping -I eth1 -c 1 10.0.0.40
PING 10.0.0.40 (10.0.0.40) from 10.0.0.30 eth1: 56(84) bytes of data.
64 bytes from 10.0.0.40: icmp_seq=1 ttl=64 time=1.97 ms
--- 10.0.0.40 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.970/1.970/1.970/0.000 ms
##4.3 tsharkによる確認
仮想ブリッジのvnet2を通過するICMP echo request/replyパケットをtsharkを使って確認します。
確認をするため、KVMホストでtsharkコマンドを実行します。
なお、tsharkコマンドの使い方はここ(tsharkコマンドの使い方)を参照してください。
[root@kvm ~]# tshark -i vnet2 -Y 'icmp.type==0 or icmp.type==8' -n
VM3(eth1)からVM4(eth1)に対してpingを1回実行してみます。
[root@vm3 ~]# ping -I eth1 -c 1 10.0.0.40
vnet2インタフェースをICMP echoパケットが通過していることがわかります。
[root@kvm ~]# tshark -i vnet2 -Y 'icmp.type==0 or icmp.type==8' -n
Running as user "root" and group "root". This could be dangerous.
Capturing on 'vnet2'
1 0.000000000 10.0.0.30 -> 10.0.0.40 ICMP 98 Echo (ping) request id=0x0ede, seq=1/256, ttl=64
2 0.000415425 10.0.0.40 -> 10.0.0.30 ICMP 98 Echo (ping) reply id=0x0ede, seq=1/256, ttl=64 (request in 1)
#5 あと始末
##5.1 VM3のNIC削除
VM3のNICを削除します。VM4も同様に削除します。
[root@kvm ~]# virsh domiflist vm3
インターフェース 種類 ソース モデル MAC
-------------------------------------------------------
vnet0 network default virtio 52:54:00:5e:65:7a
vnet2 bridge br1 virtio 52:54:00:4f:ae:b2
[root@kvm ~]# virsh detach-interface --type bridge --mac 52:54:00:4f:ae:b2 vm3
インターフェースが正常に切断されました
##5.2 仮想ブリッジの削除
KVMホストに作成した仮想ブリッジを削除します。
[root@kvm ~]# ip l show dev br1
11: br1: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 0e:bc:49:d4:e0:11 brd ff:ff:ff:ff:ff:ff
[root@kvm ~]# ip l del dev br1
[root@kvm ~]# ip l show dev br1
Device "br1" does not exist.
#6 メモ
0xffffffffc03f6b60 : vp_notify+0x0/0x20 [virtio_pci]
0xffffffffc03ea720 : virtqueue_kick+0x30/0x50 [virtio_ring]
0xffffffffc0475584 : start_xmit+0x264/0x500 [virtio_net]
0xffffffff9f838c66 : dev_hard_start_xmit+0x246/0x3b0 [kernel]
0xffffffff9f865cea : sch_direct_xmit+0x11a/0x250 [kernel]
0xffffffff9f83bbe1 : __dev_queue_xmit+0x491/0x650 [kernel]
0xffffffff9f83bdb0 : dev_queue_xmit+0x10/0x20 [kernel]
0xffffffff9f888736 : ip_finish_output+0x556/0x7b0 [kernel]
0xffffffff9f888c93 : ip_output+0x73/0xe0 [kernel]
0xffffffff9f886817 : ip_local_out_sk+0x37/0x40 [kernel]
0xffffffff9f8896f6 : ip_send_skb+0x16/0x50 [kernel]
0xffffffff9f889763 : ip_push_pending_frames+0x33/0x40 [kernel]
0xffffffff9f8b085d : raw_sendmsg+0x88d/0xa40 [kernel]
0xffffffff9f8bfeb9 : inet_sendmsg+0x69/0xb0 [kernel]
0xffffffff9f8193a6 : sock_sendmsg+0xb6/0xf0 [kernel]
0xffffffff9f819ad1 : SYSC_sendto+0x121/0x1c0 [kernel]
0xffffffff9f81b5ee : SyS_sendto+0xe/0x10 [kernel]
0xffffffff9f974ddb : system_call_fastpath+0x22/0x27 [kernel]
0xffffffffc08def10 : tun_net_xmit+0x0/0x300 [tun]
0xffffffff87e38c66 : dev_hard_start_xmit+0x246/0x3b0 [kernel]
0xffffffff87e65cea : sch_direct_xmit+0x11a/0x250 [kernel]
0xffffffff87e3bbe1 : __dev_queue_xmit+0x491/0x650 [kernel]
0xffffffff87e3bdb0 : dev_queue_xmit+0x10/0x20 [kernel]
0xffffffffc086c3b8 : br_dev_queue_push_xmit+0xa8/0x190 [bridge]
0xffffffffc086c4d9 : br_forward_finish+0x39/0xa0 [bridge]
0xffffffffc086c5c9 : __br_forward+0x89/0x1d0 [bridge]
0xffffffffc086c815 : br_forward+0xa5/0xb0 [bridge]
0xffffffffc086e1cd : br_handle_frame_finish+0x28d/0x580 [bridge]
0xffffffffc086e6d2 : br_handle_frame+0x1d2/0x320 [bridge]
0xffffffff87e38fca : __netif_receive_skb_core+0x1fa/0xa10 [kernel]
0xffffffff87e397f8 : __netif_receive_skb+0x18/0x60 [kernel]
0xffffffff87e39880 : netif_receive_skb_internal+0x40/0xc0 [kernel]
0xffffffff87e3991c : netif_receive_skb+0x1c/0x70 [kernel]
0xffffffffc08e0085 : tun_get_user+0x815/0xbc0 [tun]
0xffffffffc08e0496 : tun_sendmsg+0x66/0x90 [tun]
0xffffffffc0917344 : handle_tx+0x214/0x650 [vhost_net]
0xffffffffc09177b5 : handle_tx_kick+0x15/0x20 [vhost_net]
0xffffffffc0902321 [vhost]
#Z 参考情報
Add a second NIC for a libvirt guest
10.6. IP コマンドを使用したボンドおよびブリッジ上での VLAN の使用