仮想化環境における
パケットフォワーディング
浅田 拓也 @ 東京工科大学
Twitter: @syuu1228
おさらい
仮想化技術とは
1台のコンピュータ上に複数の仮想的なコンピュータを
動作させ、それぞれの上でOS・アプリケーションを実
行
ハードウェア
OS
ハードウェア
ハイパーバイザ
OS OS
プロセス プロセス
プロセス
従来 仮想化
ハードウェア仮想化支援機能に
よる仮想化
• CPUにハイパーバイザを実行するモードとゲス
トOSを実行するモードを追加:IntelVT、AMD-V
• ハードウェアレベルで仮想化に対応する事によ
り仮想化オーバヘッドを低減し、ハイパーバイ
ザの実装を単純に出来る
• ハードウェア支援出来る範囲を広げつつある
• メモリ管理の仮想化支援:EPT
• デバイスIOの仮想化支援:IntelVT-d + SR-IOV
カーネル
モード
ユーザ
モード
カーネル
モード
ユーザ
モード
ハイパーバイザ
モード
ゲストモード
ring 0
ring 3
LINUX KVMの仕組み
LINUX KVM 概要
• Linuxカーネルに組み込まれたシンプルなハイパーバイザ(仮想化支
援機能のあるCPUを前提)
• CPU仮想化以外の機能はKVM対応のQEMUが担当(仮想デバイス、メ
モリ確保、BIOS…)
Linuxカーネル
KVM
QEMU
カーネルユーザ
ハイパーバイザモード ゲストモード
KVM
サポート
仮想デバイス
ゲストOS
QEMU
• プログラムでCPUをエミュレート、ゲスト環境のプログラムを実行
• 異なるアーキテクチャをエミュレート出来る(これが本来の目的)
• 非常に遅い・エミュレーションは仮想化には無駄
QEMU mov dx,3FBh
mov al,128
out dx,al
CPU
エミュ
レータ
実行
仮想デ
バイス
OS
物理デ
バイス
物理
CPU
IO
QEMU-KVM
• CPUエミュレータを動かす代わりにKVMへゲストモードへの切り替
えを要求するように改造
• ゲストからIOが発生した場合、KVMからQEMUへ仮想デバイスへの
IOが送れるように改造
QEMU
仮想デ
バイス
OS
物理デ
バイス
物理
CPU
KVM
モード切替
ゲストモードへの切り替え
• QEMUはCPUエミュレーションを行う代わりにゲストへのモード切り替えを依頼するioctlをカー
ネルへ発行
• KVMはCPUのモードをゲストモードへ移行
• ゲストOSがハードウェアへのIOなどトラップされるような動作を行うか、物理ハードウェアか
らの割込みがかかるまでゲストモードが実行される
Linuxカーネル
KVM
QEMU
カーネルユーザ
ゲストOS
KVM
サポート
仮想デバイス
① ioctl(KVM_RUN)
② VMLAUNCH
ハイパーバイザモード ゲストモード
仮想デバイスへのIO
• ゲストOSがデバイスへIO、ゲストモードが中断され制御がKVMへ戻る
• QEMUへデバイスエミュレーションを依頼
• QEMUでデバイスエミュレーション、結果をKVMへ通知
Linuxカーネル
KVM
QEMU
カーネルユーザ
ゲストOS
KVM
サポート
仮想デバイス
①デバイスへのIO
ハイパーバイザモード ゲストモード
②QEMUへ処理を依頼
③デバイスエミュレーション
KVMの仮想NIC
NICエミュレーション
• QEMUを使って実在のNICをエミュレート→ゲストOSで既存のドライバが使える
• 仮想レジスタへのアクセスのたびにゲストモードの実行を中断し、カーネルから
QEMUに切り替えてエミュレーションを行わなければならない
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
フォワード
割り込み
物理割り込み
パケット
バッファ
レジスタ
アクセス
割り込み
レジスタ
アクセス
コピー
コピー
NICエミュレーションの動作
• パケットがNICに着信、物理割り込みが発生
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
NICエミュレーションの動作
• NICドライバがパケットを受信
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
NICエミュレーションの動作
• ブリッジがパケットをtapデバイスへフォワード
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
NICエミュレーションの動作
• tapからQEMUへコピー
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
NICエミュレーションの動作
• QEMUからゲストのパケットバッファへコピー
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー
NICエミュレーションの動作
• QEMUからKVMへ仮想割り込みを要求
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー⑥仮想割り込み要求
NICエミュレーションの動作
• KVMはゲストに仮想割り込みをセットしてモード切替
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー⑥仮想割り込み要求⑦仮想割り込み
NICエミュレーションの動作
• ゲストのNICドライバがレジスタアクセスを行い、ゲストモードが中断
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー⑧仮想レジスタアクセス
⑥仮想割り込み要求
NICエミュレーションの動作
• KVMはQEMUにエミュレーションを要求
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー⑧仮想レジスタアクセス
⑨エミュレーション要求
NICエミュレーションの動作
• QEMUはe1000エミュレーションを行い、結果をKVMへ通知
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー⑧仮想レジスタアクセス
⑩エミュレーション結果通知
NICエミュレーションの動作
• KVMエミュレーション結果をセットしてゲストへ復帰
以降、レジスタアクセスのたびに⑧∼⑪の繰り返し
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー
⑪ゲストへ復帰
⑩エミュレーション結果通知
NICエミュレーションの動作
• ゲストのNICドライバがパケットを受信
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー
⑪ゲストへ復帰
⑩エミュレーション結果通知
⑫パケット受信
NICエミュレーションの動作
• TCP/IPスタックがパケットをフォワード
カーネル
カーネル
ゲスト
ハイパーバイザ ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
e1000
エミュレーションkvm
e1000
ドライバ
TCP/IP
スタック
NIC2
①物理割り込み
パケット
バッファ
②パケット受信
③tapへブリッジ
④コピー
⑤コピー
⑪ゲストへ復帰
⑩エミュレーション結果通知
⑫パケット受信
⑬パケットフォワード
VIRTIO-NET
• IO仮想化フレームワーク「virtio」を用いてパケットの入出力を行う
→ゲストOSにvirtio用ドライバが必要
• 仮想レジスタは存在せず、virtio ring上の情報を見ながらパケットを取り出す
→ハイパーバイザへの切り替え回数が少ない
カーネル
カーネル
ゲスト
ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
tapクライアント
virtio serverkvm
virtio
ドライバ
TCP/IP
スタック
NIC2
フォワード
割り込み
物理割り込み
コピー
virtio ring
コピー
割り込み
ハイパーバイザ
VHOST-NET
• QEMUを通さず、カーネル内のvhost-netモジュールがホスト ゲス
トのパケットやり取りを制御
• QEMU KVMの切り替えコストを削減
カーネル
カーネル
ゲスト
ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
vhost-netkvm
virtio
ドライバ
TCP/IP
スタック
NIC2
フォワード
割り込み
物理割り込み
virtio ring
割り込み
ハイパーバイザ
コピー
コピー
SR-IOV
• 物理NICがVMに対して仮想NICを直接提供 IOはハイパーバイザーを介在せずに行われる
• 割込みだけは仮想化出来ていないのでKVMを通じて転送される
• 最も性能が高いがハード対応が必要/ゲストのパケットをフィルター・改変する事は難しい
NIC
カーネル
カーネル
ゲスト
ユーザ
PF
PFドライバ
qemu
kvm
VF
ドライバ
TCP/IP
スタック
NIC2
フォワード
割り込み
物理割り込み
割り込み
割込み
ハンドラ
VF
DMAパススルー
ハイパーバイザ
どれを使うべき?
• 幅広いOSで仮想NICが動作する必要がある
→NICエミュレーション、e1000が最も高速
• 最近のLinuxを動かす予定、SR-IOV対応NICが無い
→vhost-net
• SR-IOV対応NICがある
→SR-IOV
KVMの仮想ネットワーク
BRIDGE +TAP
• STPを含む802.1d標準準拠のブリッジ実装
• netfilterによるフィルタリング
• ブリッジ自体をインタフェースとしてコンフィグレーション可能
ブリッジ
xx:xx:xx:xx:xx:01
物理NIC
xx:xx:xx:xx:xx:00
tap0
xx:xx:xx:xx:xx:02
tap1
xx:xx:xx:xx:xx:03
QEMU
QEMU
BRIDGE+TAPでNAT
• ブリッジにTAPのみを繋ぎ、ブリッジインタフェースに
IPマスカレードを設定してNATを構成
ブリッジ
xx:xx:xx:xx:xx:01
物理NIC
xx:xx:xx:xx:xx:00
tap1
xx:xx:xx:xx:xx:03
QEMU
tap0
xx:xx:xx:xx:xx:02
QEMU
NAT
MACVTAP
• 物理NICに対して追加のMACアドレスを付与、独立したインタフェースとして動作
• netfilterには非対応、bridgeより簡易的な実装で「速い」とされている
• 構造上、NAT構成には使えない
物理NIC
xx:xx:xx:xx:xx:00
macvtap0
xx:xx:xx:xx:xx:01
macvtap1
xx:xx:xx:xx:xx:02
QEMUQEMU
MACVTAPのモード
• bridge
tap tap間、tap NIC間通信を行えるモード
• private
tap tap間、tap NIC間通信を許可しないモード
• vepa
全てのパケットを外部スイッチでスイッチングするモード
• passthrough
NICに入ってくる全てのパケットを特定のtapに流すモード
OPENVSWITCH
• 仮想マシンに対し仮想OpenFlowスイッチを提供
• 物理構成に縛られない柔軟な仮想ネットワークを
L2レベルで構築可能
どれを使うべき?
• NAT環境を構成、パケットフィルタリングなどを行う
→bridge + tap
• 高速なブリッジ環境
→macvtap
• OpenFlowを用いて柔軟なL2ネットワークを構築
→OpenvSwitch
実験的な機能・実装中の機能
VHOST-NETのゼロコピー対応
• tap→vhost-net、vhost-net→ゲスト間のパケットコピーを抑制
• スループットの向上、レイテンシの削減が期待される
カーネル
カーネル
ゲスト
ユーザ
NIC
NICドライバ tapドライバ
bridge
qemu
vhost-netkvm
virtio
ドライバ
TCP/IP
スタック
NIC2
フォワード
割り込み
物理割り込み
virtio ring
割り込み
ハイパーバイザ コピーなし
コピーなし
VHOST-NETの
マルチキュー対応
• 現状のシングルキューな仮想
NICでは、ブリッジ以降のパ
スが同時に1スレッドでしか
処理できない為、パフォーマ
ンスネックになる
• vCPUが複数ある環境での性能
向上が期待されている singlequeue
vhost-net
NIC
NICドライバ
bridge
tap
virtio push
kvm
virtioドライバ
TCP/IP
ロック競合
が発生!
multiqueue
vhost-net
NIC
NICドライバ
bridge
tap
virtio push
kvm
virtioドライバ
TCP/IP
SR-IOVのマルチキュー対応
• 82599のVFは最大4キューまでのRSSに対応
• 現状ではドライバに実装されていないが、ドライバ対
応で利用可能になると思われる
EVB: EDGEVIRTUAL BRIDGING
• VEB:SR-IOV対応NIC上のスイッチでVM間通信を処理
• VEPA:物理スイッチでVM間通信を処理
VM VM VM
tap tap tap
switch
virtio
driver
NIC
switch
VM VM VM
VF VF VF
LinuxKernel
Linux
Kernel
SR-IOVNIC
ソフトブリッジ
switch
switch
VEB
VM VM VM
VF VF VF
Linux
Kernel
SR-IOVNIC
switch
VEPA
まとめ
• KVMにおける仮想NICのマルチコア環境への最適化は未
だ不十分
• 仮想化のハードウェアによる支援はNICに留まらずス
イッチへも広がりつつ有る

仮想化環境におけるパケットフォワーディング