LoginSignup
2
1

More than 5 years have passed since last update.

Lagopus 0.2 をqemu/kvm with virtio-netで動かす (dpdk 2.1.0 + Lagopus 0.2)

Last updated at Posted at 2015-09-15

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をここに示す。

shell
#(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
shell
#(他の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の導入に必要なパッケージをインストールする。

shell
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に対して行ない、反映させるために再起動する。

/etc/default/grub
GRUB_CMDLINE_LINUX="hugepages=256"
shell
sudo update-grub
sudo reboot

dpdkのインストール

ここではdpdkの1.7.1をインストールする。

shell
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をダウンロードする。

shell
# 公式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をコンパイルする。

shell
./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になる
/usr/local/etc/lagopus.conf
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を実行してどのポートか確認する。

shell
$ ./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に記入すること。

install-dpdk.sh
#!/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がエラー)するので注意。

shell
sudo lagopus -d -- -c3 -n1 -b 00:03.0 -- -p3

ryuの起動

ここではryuのサンプルにあるsimple switchを起動する。

shell
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を起動する

ことを行なっている。

shell
#(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
shell
#(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の起動オプションは以下の通り。

shell
#(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
shell
#(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を企画した方に感謝致します。


  1. Pull Requestは提出済み (https://github.com/lagopus/lagopus/pull/46

  2. Pull Requestは提出済み (https://github.com/lagopus/lagopus/pull/47

2
1
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
2
1