2014年12月16日火曜日

Linux で veth のペアのデバイスを調べる方法

この記事は、OpenStack Advent Calendar の 12/16 の記事です。 Advent Calendar らしく軽い小ネタを紹介したいと思います。

OpenStack Neutron を使っていると veth のペアがたくさん作成されます。 @enakai00 さんが書いた nova-compute内のネットワーク詳細 の図を見ると、veth pai がたくさん作成されるのが分かります。

ネットワークデバイスの種類を知る方法

VM が2個しか起動していない Compute Node でもたくさんのデバイスがあります。 ネットワークデバイスにはいろいろ種類があり、通常のネットワークデバイス以外にも、 linux bridge, tap device, veth (virtual ethernet device) などいろいろあります。 でも、ip link コマンドなどを使っても、その種類は通常表示されず、名前しか情報源がありません。

-d オプションを付けて ip link コマンドを実行すると、びっくりデバイスの種類が表示されます。 これを見ると qbr0f657850-c2bridgetap0f657850-c2 は tap (tun) デバイス、 qvb0f657850-c2veth デバイスだと分かります。

この -d オプション、ip(8) コマンドのマニュアルを見ても出て来ません。どうしてなのでしょうか? どなたかご存知でしたら教えて下さい。

ubuntu@stack02:~$ ip -d link
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 promiscuity 0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 52:54:00:06:f7:0e brd ff:ff:ff:ff:ff:ff promiscuity 0
3: ovs-system: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default
link/ether 7a:1a:cb:27:31:87 brd ff:ff:ff:ff:ff:ff promiscuity 1
4: br-int: <BROADCAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/ether 9e:0d:03:df:e9:44 brd ff:ff:ff:ff:ff:ff promiscuity 1
6: virbr0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
link/ether fa:af:f9:17:d9:91 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge
7: qbr0f657850-c2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP mode DEFAULT group default
link/ether 62:d9:1f:5e:46:b5 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge
8: br-tun: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default
link/ether 06:67:1b:78:f4:48 brd ff:ff:ff:ff:ff:ff promiscuity 1
9: qvo0f657850-c2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast master ovs-system state UP mode DEFAULT group default qlen 1000
link/ether 0e:5a:08:46:0b:eb brd ff:ff:ff:ff:ff:ff promiscuity 2
veth
10: qvb0f657850-c2: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast master qbr0f657850-c2 state UP mode DEFAULT group default qlen 1000
link/ether 62:d9:1f:5e:46:b5 brd ff:ff:ff:ff:ff:ff promiscuity 2
veth
11: tap0f657850-c2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast master qbr0f657850-c2 state UNKNOWN mode DEFAULT group default qlen 500
link/ether fe:16:3e:09:9e:9e brd ff:ff:ff:ff:ff:ff promiscuity 1
tun
12: qbr2948dbdf-a4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc noqueue state UP mode DEFAULT group default
link/ether a6:ab:a4:80:f5:13 brd ff:ff:ff:ff:ff:ff promiscuity 0
bridge
13: qvo2948dbdf-a4: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast master ovs-system state UP mode DEFAULT group default qlen 1000
link/ether e6:af:80:d8:df:9d brd ff:ff:ff:ff:ff:ff promiscuity 2
veth
14: qvb2948dbdf-a4: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast master qbr2948dbdf-a4 state UP mode DEFAULT group default qlen 1000
link/ether a6:ab:a4:80:f5:13 brd ff:ff:ff:ff:ff:ff promiscuity 2
veth
15: tap2948dbdf-a4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1400 qdisc pfifo_fast master qbr2948dbdf-a4 state UNKNOWN mode DEFAULT group default qlen 500
link/ether fe:16:3e:fd:92:56 brd ff:ff:ff:ff:ff:ff promiscuity 1
tun

veth デバイスのペアを特定する方法

veth デバイスは 2個のネットワークデバイスがセットになっていて、 一方の veth デバイスに入力したパケットはそのままペアになっている veth デバイスに出力されます。

そうすると、どのネットワークデバイスがペアになっているかを知る方法がほしいです。 OpenStack では、ポートIDを元に veth デバイスが作成されるので、名前からペアを推測することはできますが、 やはりシステム上で確認したいものです。

ethtool を使うと veth の相手の veth デバイスを知ることができます。

ubuntu@stack02:~$ sudo ethtool -S qvb2948dbdf-a4
NIC statistics:
     peer_ifindex: 13

peer_ifindex が 13 になっています。 この番号は上の ip link コマンドの出力の左端に表示されているネットワークデバイスの通し番号です。 13 は qvo2948dbdf-a4 が相手だと分かります。

qvo2948dbdf-a4qvb2948dbdf-a4 がペアの veth デバイスということになります。

まとめ

Neutron でたくさん作成されるネットワークデバイスの種類を Linux で確認する方法と、 veth のペアのデバイスを作成する方法を紹介しました。 こういう小ネタもたまっていくと便利ですね。

余談

Neutron で ML2 plugin + OVS mechanism driver を使っていると、 VM のポート毎に veth ペア qvo2948dbdf-a4qvb2948dbdf-a4 とブリッジ qbr2948dbdf-a4 が作成されます。

このデバイス名の由来を見ておきましょう。

  • q: Quantum の q です。これが実装された当時は Neutron ではなく Quantum だった名残です。すでに運用されているシステムがあるので、名前の変更は簡単ではなく q が残っています。
  • 2-3文字目 : 役割を表しています。
    • vo: vveth の頭文字です。o は OVS に接続される方の veth の片割れという意味です。
    • vb: vveth の頭文字です。b は (Linux) bridge に接続される方の veth の片割れという意味です。
    • br: bridge の頭文字です。
  • 4文字目以降 : Neutron Port UUID の前の方の値