読者です 読者をやめる 読者になる 読者になる

らくがきちょう

なんとなく

Ryu&OvS 入り OpenWrt イメージを作成し Cisco VIRL で利用する

OpenWrt はフットプリントが小さく、VIRL 上での検証時に便利です。今回は OpenWrt に Open vSwitch(以下、OvS)と Ryu を追加し、VIRL に登録します。但し、現状では Ryu は起動するものの、Open vSwitch は Segmentation Fault を起こして利用出来ませんでした。

作業の流れ

作業は以下の流れを辿ります。

  1. OpenWrt イメージのダウンロード
  2. OpenWrt イメージのサイズ拡張
    1. ディスクサイズの拡張
    2. パーティション情報の修正
    3. ファイルシステムサイズの拡張
  3. OpenWrt イメージの起動&初期設定修正
  4. パッケージの追加
  5. Ryu のインストール
  6. DHCP の設定
  7. イメージフォーマットの変更(raw → qcow2)
  8. VIRL に登録する

用意するもの

以下を用意します。

  1. 作業の母艦となる Ubuntu
    • 今回は 14.04.3 を利用
    • QEMU インストール済み
    • kpartx インストール済み

後述しますが、QEMU イメージのサイズを拡張する際に利用しますので、kpartx をインストールしておきます。

apt-get -y install kpartx

OpenWrt イメージのダウンロード

現時点で OpenWrt の最新安定版は Barrier Breaker(14.07)です。しかし、14.07 の標準リポジトリには OvS のパッケージがありません。Chaos Calmer の標準リポジトリには OvS のパッケージが存在するのですが、インストールしようとするとエラーになってしまいます(おそらく今後、解消されると思います)。Snapshots の Trunk ビルドであればエラーにならなかったので、今回は Trunk ビルドを利用しました。

Ubuntu 上でダウンロード&展開します。

wget https://downloads.openwrt.org/snapshots/trunk/x86/kvm_guest/openwrt-x86-kvm_guest-combined-ext4.img.gz
gunzip openwrt-x86-kvm_guest-combined-ext4.img.gz

OpenWrt イメージのサイズ拡張

OpenWrt の標準状態では「ディスクサイズは 50MB 程度」「利用可能領域は 40MB 程度」しかありません。

root@OpenWrt:/# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                   46.5M      4.8M     40.7M  11% /
/dev/root                46.5M      4.8M     40.7M  11% /
tmpfs                   441.3M     48.0K    441.2M   0% /tmp
tmpfs                   512.0K         0    512.0K   0% /dev

パッケージを追加していくと空き容量が不足してしまう為、OpenWrt イメージのサイズを拡張します。ダウンロード直後の OpenWrt イメージを qemu-img で確認すると、確かにディスクサイズは 53M になっていました。

# qemu-img info openwrt-x86-kvm_guest-combined-ext4.img
image: openwrt-x86-kvm_guest-combined-ext4.img
file format: raw
virtual size: 53M (55050240 bytes)
disk size: 53M

ディスクサイズの拡張

まず、qemu-img でディスクサイズを拡張します。今回は 1GB にしました。

qemu-img resize openwrt-x86-kvm_guest-combined-ext4.img 1G

virtual size が 1GB に拡張されました。

# qemu-img info openwrt-x86-kvm_guest-combined-ext4.img
image: openwrt-x86-kvm_guest-combined-ext4.img
file format: raw
virtual size: 1.0G (1073741824 bytes)
disk size: 53M

パーティション情報の修正

しかし、これだけではファイルシステム自体のサイズが拡張されていません。ディスクサイズを拡張した分に追従して、ファイルシステムのサイズも拡張します。losetup を使って OpenWrt イメージを Loopback に設定します。

losetup /dev/loop0 openwrt-x86-kvm_guest-combined-ext4.img

パーティション情報を確認しておきます。

# kpartx -l /dev/loop0
loop0p1 : 0 8192 /dev/loop0 512
loop0p2 : 0 98304 /dev/loop0 9216

fdisk を使ってパーティション情報を変更していきます。

fdisk /dev/loop0

念の為、パーティション情報を再確認しておきます。特に重要なのは拡張対象となる 2 つ目のパーティション/dev/loop0p2)の開始位置です。下記では「9,216」になっています。

Command (m for help): p

Disk /dev/loop0: 1073 MB, 1073741824 bytes
255 heads, 63 sectors/track, 130 cylinders, total 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x6775217f

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *         512        8703        4096   83  Linux
/dev/loop0p2            9216      107519       49152   83  Linux

/dev/loop0p2 の開始位置が確認出来たら、/dev/loop0p2 を削除します。

Command (m for help): d
Partition number (1-4): 2

/dev/loop0p2 をサイズ拡張して再作成します。開始位置(First sector)は必ず先に確認した数字に合わせる必要があります。

Command (m for help): n
Partition type:
   p   primary (1 primary, 0 extended, 3 free)
   e   extended
Select (default p): p
Partition number (1-4, default 2): 2
First sector (8704-2097151, default 8704): 9216
Last sector, +sectors or +size{K,M,G} (9216-2097151, default 2097151):
Using default value 2097151

パーティションテーブル情報の変更を書き戻す前に、変更内容を確認しておきます。

Command (m for help): p

Disk /dev/loop0: 1073 MB, 1073741824 bytes
255 heads, 63 sectors/track, 130 cylinders, total 2097152 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0x6775217f

      Device Boot      Start         End      Blocks   Id  System
/dev/loop0p1   *         512        8703        4096   83  Linux
/dev/loop0p2            9216     2097151     1043968   83  Linux

パーティション情報を書き戻し、fdisk を終了します。

Command (m for help): w
The partition table has been altered!

Calling ioctl() to re-read partition table.

WARNING: Re-reading the partition table failed with error 22: Invalid argument.
The kernel still uses the old table. The new table will be used at
the next reboot or after you run partprobe(8) or kpartx(8)
Syncing disks.

ファイルシステムサイズの拡張

kpartx を使ってパーティションテーブルからデバイスファイルを作成します。

kpartx -a /dev/loop0

/dev/mapper を確認すると、デバイスファイルが作成されていることを確認出来ます。

# ls /dev/mapper/
control  loop0p1  loop0p2

ファイルシステムをリサイズする前に念の為、e2fsck で整合性チェックを実行しておきます。

e2fsck -f /dev/mapper/loop0p2

resize2fsファイルシステムをリサイズします。

resize2fs /dev/mapper/loop0p2

以降は後片付けです。パーティションマッピングを削除します。

kpartx -d /dev/loop0

デバイスファイルのマッピングが削除されました。

# ls /dev/mapper/
control

最後に Loopback を解除します。

losetup -d /dev/loop0

このイメージで OpenWrt を起動してディスク使用率を確認すると以下の通り、ファイルシステムも拡張されていることが分かります。

root@OpenWrt:/# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                 1007.7M      4.9M    986.8M   0% /
/dev/root              1007.7M      4.9M    986.8M   0% /
tmpfs                   441.3M     48.0K    441.2M   0% /tmp
tmpfs                   512.0K         0    512.0K   0% /dev

OpenWrt イメージの起動&初期設定修正

OpenWrt イメージを起動します。OpenWrt には virtio ドライバーが含まれていたので、NIC のモデルは virtio を指定しました。

qemu-system-i386 \
-enable-kvm \
-m 1024 \
-k ja \
-net nic,model=virtio -net user,vlan=0 \
-serial mon:stdio -nographic \
openwrt-x86-kvm_guest-combined-ext4.img

OpenWrt が起動してきます。しばらくして「Please press Enter to activate this console.」と表示されたら、エンターキーを押すだけで root としてログイン出来ます。

                          GNU GRUB  version 2.02~beta2

 +----------------------------------------------------------------------------+
 |*OpenWrt                                                                    |
 | OpenWrt (failsafe)                                                         |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 |                                                                            |
 +----------------------------------------------------------------------------+

      Use the ^ and v keys to select which entry is highlighted.
      Press enter to boot the selected OS, `e' to edit the commands
      before booting or `c' for a command-line. ESC to return
      previous menu.
   The highlighted entry will be executed automatically in 5s.

デフォルト状態は「br-lan」というブリッジが作成されており、eth0 はそのメンバーになっています。eth0 のアドレスは 192.168.1.1/24 に固定設定されていました。

# ifconfig -a
br-lan    Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          inet addr:192.168.1.1  Bcast:192.168.1.255  Mask:255.255.255.0
          inet6 addr: fe80::5054:ff:fe12:3456/64 Scope:Link
          inet6 addr: fd6b:6528:85a0::1/60 Scope:Global
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1152 (1.1 KiB)  TX bytes:2540 (2.4 KiB)

eth0      Link encap:Ethernet  HWaddr 52:54:00:12:34:56
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:14 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1180 (1.1 KiB)  TX bytes:2116 (2.0 KiB)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:32 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:2232 (2.1 KiB)  TX bytes:2232 (2.1 KiB)

OvS 等のパッケージをダウンロードするには外部ネットワークと通信する必要がありますので、DHCP でアドレス取得し、外部にアクセス出来るように設定変更します。udhcpc でブリッジインターフェイスを(固定アドレス設定では無く)DHCP 設定に変更します。

# udhcpc -i br-lan
udhcpc (v1.23.2) started
Sending discover...
Sending select for 10.0.2.15...
Lease of 10.0.2.15 obtained, lease time 86400
udhcpc: ifconfig br-lan 10.0.2.15 netmask 255.255.255.0 broadcast +
udhcpc: setting default routers: 10.0.2.2

加えてデフォルトでは /etc/resolv.conf は以下のようになっており、名前解決出来ません。

search lan
nameserver 127.0.0.1

DNS の設定を変更し、名前解決出来るようにします。例えば以下のように実行します。

echo -e "search example.local\nnameserver 8.8.8.8\nnameserver 8.8.4.4" > /etc/resolv.conf

パッケージの追加

opkg update で利用可能なパッケージ情報を取得します。

opkg update

任意のパッケージを追加します。今回は以下を追加しました。

  1. mtr
  2. nmap
  3. openvswitch
  4. python
  5. python-pip
  6. tcpdump
  7. vim
opkg install ca-certificates curl mtr nmap openssl-util openvswitch python python-pip tcpdump vim-full

Ryu のインストール

Ryu をインストールする前に greenlet をインストールします。pip install greenlet するとエラーになってしまう為、ちょっとバージョンが古いですが OpenWrt 環境用に作り直してある python-greenlet を先にインストールします。

opkg install python-greenlet_0.4.0-1_x86.ipk

greenlet のインストールが終わったら、Ryu をインストールします。

pip install ryu

必ずしも必要無いのですが、pip のバージョンが古いというメッセージが出ているのでアップグレードしておきます。

pip install --upgrade pip

これも必須では無いのですが、Ryu を検証する際にサンプルアプリケーションを参照しやすくする為、シンボリックリンクを作成しておきます。

ln -s /usr/lib/python2.7/site-packages/ryu/app /root/ryu-apps

DHCP の設定

起動する度に br-lan(eth0)に DHCP 設定を行うのは不便です。そこで起動時は自動的に DHCP でアドレスを取得するよう、設定を修正します。ネットワークの設定は /etc/config/network で定義されています。デフォルトでは以下のようになっていました。

config interface 'loopback'
	option ifname 'lo'
	option proto 'static'
	option ipaddr '127.0.0.1'
	option netmask '255.0.0.0'

config interface 'lan'
	option ifname 'eth0'
	option type 'bridge'
	option proto 'static'
	option ipaddr '192.168.1.1'
	option netmask '255.255.255.0'
	option ip6assign '60'

config interface 'wan'
	option ifname 'eth1'
	option proto 'dhcp'

config interface 'wan6'
	option ifname 'eth1'
	option proto 'dhcpv6'

config globals 'globals'
	option ula_prefix 'fd6b:6528:85a0::/48'

eth0 部分を以下のように修正します。

config interface 'lan'
	option ifname 'eth0'
	option type 'bridge'
	option proto 'dhcp'

これで準備は完了です。ここまでの修正で空き容量は以下のようになっていました。

root@OpenWrt:~# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                 1007.7M     82.3M    909.4M   8% /
/dev/root              1007.7M     82.3M    909.4M   8% /
tmpfs                   441.3M     60.0K    441.2M   0% /tmp
tmpfs                   512.0K         0    512.0K   0% /dev

OpenWrt をシャットダウンします。

poweroff

イメージフォーマットの変更(raw → qcow2)

OpenWrt イメージは raw フォーマットで配布されていますが、このままでは VIRL で起動することが出来ません。イメージフォーマットを raw から qcow2 へ変更します。変換後のイメージファイル名は「openwrt-x86-kvm_guest-ovs.img」としました。

qemu-img convert -O qcow2 openwrt-x86-kvm_guest-combined-ext4.img openwrt-x86-kvm_guest-ovs.img

イメージフォーマットが変更されました。

# qemu-img info openwrt-x86-kvm_guest-ovs.img
image: openwrt-x86-kvm_guest-ovs.img
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 87M
cluster_size: 65536
Format specific information:
    compat: 1.1
    lazy refcounts: false

VIRL に登録する

VIRL の UWM(管理画面)から Subtype は server をベースに、以下のように登録しました。

項目
Name of new subtype OpenWrt
RAM (MB) allocated per node 1,024
Name of default image OpenWrt
Name of default flavor OpenWrt

f:id:sig9:20150823154126p:plain

Images には以下のように登録しました。

項目
Subtype OpenWrt
Release trunk-2015-08-23
Source Local image file

f:id:sig9:20150823154405p:plain

後は VMMaestro の設定画面から Node Subtypes を再読み込みすれば OpenWrt イメージが使えるようになっているはずです。