OpenWrt はフットプリントが小さく、VIRL 上での検証時に便利です。今回は OpenWrt に Open vSwitch (以下、OvS)と Ryu を追加し、VIRL に登録します。但し、現状では Ryu は起動するものの、Open vSwitch は Segmentation Fault を起こして利用出来ませんでした。
作業の流れ
作業は以下の流れを辿ります。
- OpenWrt イメージのダウンロード
- OpenWrt イメージのサイズ拡張
- ディスクサイズの拡張
- パーティション情報の修正
- ファイルシステムサイズの拡張
- OpenWrt イメージの起動&初期設定修正
- パッケージの追加
- Ryu のインストール
- DHCP の設定
- イメージフォーマットの変更(raw → qcow2)
- VIRL に登録する
用意するもの
以下を用意します。
- 作業の母艦となる 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
任意のパッケージを追加します。今回は以下を追加しました。
- mtr
- nmap
- openvswitch
- python
- python-pip
- tcpdump
- 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 |
Images には以下のように登録しました。
項目 | 値 |
---|---|
Subtype | OpenWrt |
Release | trunk-2015-08-23 |
Source | Local image file |
後は VMMaestro の設定画面から Node Subtypes を再読み込みすれば OpenWrt イメージが使えるようになっているはずです。
コメント