Lagopus 0.2をqemu/kvm with virtio-netで動かす
本記事では
- Ubuntu14をインストールしたQemuにdpdk,ryu,Lagopusをインストールして
- pingの疎通を
- netnsを使用してHypervisor側のlinux側から確認する
- 他のQemuのVMと接続して確認する
までの手順を説明する。
前回との相違点
Lagopusをqemu/kvm with virtio-netで動かす (dpdk 1.7.1/lagopus 0.1.2)
とは以下の点が異なる。
- virtio-netのパッチ (lagopus_fix_virtio_tx_mtu_02.diff)
- /usr/local/etc/lagopus/lagopus.conf の書式
- lagopus起動時のオプション ('-b'オプションを追加)
環境
以下の環境で動作を確認した。
- Hypervisor
- Linux kernel 4.0.5
- qemu 2.1.2
- GuestOS (VM)
- Ubuntu 14.04 (amd64)
- lagopus (github, master:6cd6660e2d5e7ce79e713aa4de9ab32efa011905)
- dpdk 2.1.0
- Ryu 3.25 (pipでインストール, python 2.7.6)
前準備
ここではUbuntu14をインストールしたQemuのVMにLagopusをインストールするまでを説明する。
まず始めにUbuntu14をインストールしたQemuを用意する。
ただし、qemuの起動時に以下の設定が必要となるので注意
-
-cpu host
をつける -
-smp cores={コア数},threads=1
の指定 - (coresとthreadsを指定しないとlagopusが起動できない可能性がある為)
- 各ネットワークポートのMAC指定(全て異なるMACにすること)
- 確認する方法によって異なる
-netdev
の設定- netnsの場合にはtapを使用する
- 他のvmの場合にはsocketを使用する
参考に著者の起動時のoptionをここに示す。
# (netnsを使用して確認する場合)
cpu=3
mem=4000
qemu=qemu-system-x86_64
image=lagopus_sw.qcow2
boot=c
${qemu} -cpu host -smp ${cpu},cores=${cpu},threads=1 -numa node \
-m ${mem} ${snapshot} \
-rtc base=utc -usbdevice tablet -monitor stdio \
-drive file=${image},if=virtio -boot ${boot} -vnc ${vnc} \
-enable-kvm -L /usr/share/qemu \
-device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 \
-device virtio-net-pci,netdev=net1,mac=52:54:01:12:34:56 \
-device virtio-net-pci,netdev=net2,mac=52:54:02:12:34:56 \
-netdev bridge,id=net0,br=br0 \
-netdev socket,id=net1,listen=:5001 \
-netdev socket,id=net2,listen=:5002
# (他のQemuのVMを使用して確認する場合)
cpu=3
mem=4000
qemu=qemu-system-x86_64
image=lagopus_sw.qcow2
boot=c
${qemu} -cpu host -smp ${cpu},cores=${cpu},threads=1 -numa node \
-m ${mem} ${snapshot} \
-rtc base=utc -usbdevice tablet -monitor stdio \
-drive file=${image},if=virtio -boot ${boot} -vnc ${vnc} \
-enable-kvm -L /usr/share/qemu \
-device virtio-net-pci,netdev=net0,mac=52:54:00:12:34:56 \
-device virtio-net-pci,netdev=net1,mac=52:54:01:12:34:56 \
-device virtio-net-pci,netdev=net2,mac=52:54:02:12:34:56 \
-netdev bridge,id=net0,br=br0 \
-netdev tap,id=net1,ifname=tap11,script=no \
-netdev tap,id=net2,ifname=tap12,script=no
Ubuntuのアップデート・設定変更
まずLagopusの導入に必要なパッケージをインストールする。
sudo apt-get -y update
sudo apt-get -y install unzip build-essential libexpat1-dev libgmp-dev libncurses5-dev libssl-dev libpcap-dev byacc flex libreadline-dev python-dev python-pastedeploy python-paste python-twisted git python-setuptools python-pip libxml2-dev libxslt1-dev ethtool
Lagopus/dpdkで必要となるhugepageの設定をgrubに対して行ない、反映させるために再起動する。
GRUB_CMDLINE_LINUX="hugepages=256"
sudo update-grub
sudo reboot
dpdkのインストール
ここではdpdkの1.7.1をインストールする。
wget -O - http://dpdk.org/browse/dpdk/snapshot/dpdk-2.1.0.tar.xz | tar xvfpJ -
cd dpdk-2.1.0/
make install T=x86_64-native-linuxapp-gcc
lagopusのインストール
ここではlagopusをインストールする。release-0.2ブランチで確認した。
現在のlagopusではvirtio-netでの動作をサポートしていない12ので、公式にpatchを当てるか著者の対応済みのgithubをクローンする必要がある。
以下のどちらかの手段でもいいのでlagopusをダウンロードする。
# 公式gitにpatchを当てる方法
git clone https://github.com/lagopus/lagopus.git
cd lagopus
git checkout release-0.2.0
wget -O - http://s1061123.net/lagopus_fix_virtio_tx_mtu_02.diff | patch -p1
その後,先程コンパイルしたdpdkを指定してlagopusをコンパイルする。
./configure --with-dpdk-dir=${HOME}/dpdk-2.1.0
make
sudo make install
lagopus.confの作成
以下のconfigを作成して,/usr/local/etc/lagopus.conf
として保存する。
注意
ここのeth0,eth1はlagopusのために用意するポートの数だけ用意する。ここでのeth0,eth1はlagopusで管理されるポートであるのでLinuxから見えるeth0,eth1とは違うポートを指していることに注意。ここの例ではlagopusのVMは3ポートを持ち,内2 ポートをlagopusのスイッチ用ポートとして使うことにしている。
- Linuxのeth0
- Linuxのeth1 -> Lagopusのeth0になる (この時点でLinuxから見えなくなる)
- Linuxのeth2 -> Lagopusのeth1になる
channel channel01 create -dst-addr 127.0.0.1 -protocol tcp
controller controller01 create -channel channel01 -role equal -connection-type main
interface interface01 create -type ethernet-dpdk-phy -device eth0 -port-number 0
interface interface02 create -type ethernet-dpdk-phy -device eth1 -port-number 1
port port01 create -interface interface01
port port02 create -interface interface02
bridge bridge01 create -controller controller01 -port port01 1 -port port02 2 -dpid 0x1
bridge bridge01 enable
ryuのインストール
lagopusを動かす際にOpenFlow ControllerとしてRyuを使用するのでそれもインストールする。
ryuのinstall後にsixのパッケージをupgradeすることが今のところ必要らしい。
pip install ryu
pip install six --upgrade
lagopusを起動する
lagopusを動かす際(再起動後も含む),lagopusだけでなくdpdkのドライバのインストールやOpenFlowコントロー ラの起動が必要になる。
ここではそれらを説明する。
dpdk(lagopus)対象のPCIポートの確認
まずlagopusとして動かしたいポートが属するPCIのポートを知る必要がある。dpdk-1.7.1/tools/dpdk_nic_bind.py --status
を実行してどのポートか確認する。
$ ./tools/dpdk_nic_bind.py --status
Network devices using DPDK-compatible driver
============================================
<none>
Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device' if= drv=virtio-pci unused=igb_uio
0000:00:04.0 'Virtio network device' if= drv=virtio-pci unused=igb_uio
0000:00:05.0 'Virtio network device' if= drv=virtio-pci unused=igb_uio
Other network devices
=====================
<none>
この場合,一番上のport(linuxのeth0)は外部接続向けのポートなのでそれ以外の0000:00:04.0, 0000:00:05.0の2つが対象となる。
dpdkドライバのインストール
dpdkドライバのインストール用のスクリプトを下からコピーしておく。その際に先程確認したPCIのポートをDPDK_NIC_PCIS
に記入すること。
# !/bin/sh
# This script is derived from handson training resources.
# http://lagopus.github.io/handson/handson.tar.xz
export RTE_SDK=${HOME}/dpdk-2.1.0
export RTE_TARGET=x86_64-native-linuxapp-gcc
DPDK_NIC_PCIS="0000:00:04.0 0000:00:05.0"
HUGEPAGE_NOPAGES="256"
set_numa_pages()
{
for d in /sys/devices/system/node/node? ; do
sudo sh -c "echo ${HUGEPAGE_NOPAGES} > $d/hugepages/hugepages-2048kB/nr_hugepages"
done
}
set_no_numa_pages()
{
sudo sh -c "echo ${HUGEPAGE_NOPAGES} > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages"
}
# install module
sudo modprobe uio
sudo insmod ${RTE_SDK}/${RTE_TARGET}/kmod/igb_uio.ko
sudo insmod ${RTE_SDK}/${RTE_TARGET}/kmod/rte_kni.ko
# unbind e1000 NICs from igb and bind igb_uio for DPDK
sudo ${RTE_SDK}/tools/dpdk_nic_bind.py --bind=igb_uio ${DPDK_NIC_PCIS}
sudo ${RTE_SDK}/tools/dpdk_nic_bind.py --status
# mount fugepagefs
echo "Set hugepagesize=${HUGEPAGE_NOPAGES} of 2MB page"
NCPUS=$(find /sys/devices/system/node/node? -maxdepth 0 -type d | wc -l)
if [ ${NCPUS} -gt 1 ] ; then
set_numa_pages
else
set_no_numa_pages
fi
echo "Creating /mnt/huge and mounting as hugetlbfs"
sudo mkdir -p /mnt/huge
grep -s '/mnt/huge' /proc/mounts > /dev/null
if [ $? -ne 0 ] ; then
sudo mount -t hugetlbfs nodev /mnt/huge
fi
unset RTE_SDK
unset RTE_TARGET
install-dpdk.shを実行しdpdkドライバをインストールする。
"Network devices using DPDK-compatible driver"に対象のポートが追加されればよい。
user@packer-ubuntu-1404-server:~$ ./install-dpdk.sh
[sudo] password for user:
Network devices using DPDK-compatible driver
============================================
0000:00:04.0 'Virtio network device' drv=igb_uio unused=
0000:00:05.0 'Virtio network device' drv=igb_uio unused=
Network devices using kernel driver
===================================
0000:00:03.0 'Virtio network device' if= drv=virtio-pci unused=igb_uio
Other network devices
=====================
<none>
Set hugepagesize=256 of 2MB page
Creating /mnt/huge and mounting as hugetlbfs
lagopusの起動
以下のコマンドでlagopusを起動させる。Lagopusに認識させたくないポート(この場合はeth0)がある場合には'-b'オプションを使ってblacklist化しないとLagopusが起動しない(正確にはdpdkがエラー)するので注意。
sudo lagopus -d -- -c3 -n1 -b 00:03.0 -- -p3
ryuの起動
ここではryuのサンプルにあるsimple switchを起動する。
ryu-manager --verbose
/usr/local/lib/python2.7/dist-packages/ryu/app/simple_switch_13.py
しばらくすると"move onto main mode"というメッセージがでる。
これでlagopusはRyuと連携して簡単なL2 Switchとなった。
動作を確認する
netnsを使用してHypervisorからpingを確認
確認する場合は2つのターミナルから以下のコマンドを打つことで疎通確認が可能である。
(両方のifconfigを全て実行した後にpingを打つこと)
このコマンドでは
- c1, c2というnetwork namespaceを作成し
- そこにtap11, tap12をc1,c2と別のnamespaceに所属させた後
- c1, c2の中で/bin/bashを起動する
ことを行なっている。
# (A-side)
sudo ip netns add c1
sudo ip link set tap11 netns c1
sudo ip netns exec c1 /bin/bash
sudo ifconfig tap11 192.168.1.1/24
ping 192.168.1.2
# (B-side)
sudo ip netns add c2
sudo ip link set tap12 netns c2
sudo ip netns exec c2 /bin/bash
sudo ifconfig tap12 192.168.1.2/24
ping 192.168.1.1
他のQemuのvmからpingを確認
他のQemuのvmを使用して確認する場合は各OSで同じサブネットのIPを振ることで疎通確認が可能である。
その場合のQemuの起動オプションは以下の通り。
# (A-side)
qemu-system-x86_64 ...必要なオプション...
-device virtio-net-pci,netdev=net1,mac=52:54:11:12:34:56 \
-netdev socket,id=net1,connect=127.0.0.1:5001
# (B-side)
qemu-system-x86_64 ...必要なオプション...
-device virtio-net-pci,netdev=net1,mac=52:54:21:12:34:56 \
-netdev socket,id=net1,connect=127.0.0.1:5002
まとめ
本記事ではlagopusをubuntu14を入れたqemu(virtio-net)で動作させることについて紹介した。
謝辞
このようなソフトを作っているlagopus開発者チームの方、またlagopusのhandsonを企画した方に感謝致します。
-
Pull Requestは提出済み (https://github.com/lagopus/lagopus/pull/46) ↩
-
Pull Requestは提出済み (https://github.com/lagopus/lagopus/pull/47) ↩