やっぱり Sun がスキ! : Weblog やっぱり Sun がスキ!

やっぱり Sun がスキ!

http://blogs.sun.com/yappri/date/20090821 2009年 8月 21日 金曜日

CrossbowのVirtual NICとQoS制御を試してみる

以前より前評判の高かった Project Crossbow ですが、OpenSolaris 2009.06 の目玉機能として晴れて標準機能となり、誰でも簡単に使えるようになりま した。簡単に説明しますと、Project Crossbow とはネットワークの仮想化、 つまり仮想インターフェースの作成やネットワーク帯域分割、優先制御と いった機能を、可能であれば NICデバイスのハードウェアアシストも利用 しながら高速かつ低負荷に実現するものです。これを使えば、例えばサーバー 仮想化とあわせて、10本の GbE ケーブルを、お互いの帯域に干渉すること なく1本の 10GbEケーブルに統合するなど、管理性を向上させかつ複雑性を 排除することが可能です。例えば次のようなシチュエーションにも絶大な 効果を発揮するはずです。

  1. ある金融サービス会社がオンラインで無料情報提供サービスを開始 した。人気は上々だが、有料会員のサービスがスローダウンし、お客が 離れていった。。。
  2. ホスティングサービス会社がCPUコア数やメモリ量による価格体系を 用意したが、どのコースでもネットワーク帯域は使い放題。。。
  3. バックアップデータ転送中のため、重要な処理がネットワークタイム アウトしてしまった。。。

Virtual NIC の作成

では早速試してみましょう。必要なものは、OpenSolaris の動作する PC1台とインターネット接続だけです。まず、まだ PC に OpenSolaris を入れてない方は今すぐインストールしましょう。OpenSolaris は Live CD 形式になっているので、とりあえず手持ちのPCで動作確認した 後にボタン一発でインストールできるので、とても手軽です。

Crossbow では図のように、仮想インターフェース (VNIC: Virtual NIC) を物理インターフェース経由で直接外部ネットワークに接続することも 出来ますし、etherstub という仮想 HUB / Switch を使ってプライベート な Virtual Network を作ることも可能です。



今回は、後者の構成でプライベート・ヴァーチャル・ネットワークを 作成し、NAT 経由でインターネットと通信できるようにしてみます。

手順としては、まず、Virtual Network の要となる etherstub を作成し、 その上に Virtual NIC (vnic0, 1, 2) を作成します。vnic0 は Private Address 192.168.10.10 で up させます。

# dladm create-etherstub etherstub0   … etherstub を作成
#
# dladm show-link
LINK        CLASS    MTU    STATE    OVER
bfe0        phys     1500   down     --
etherstub0  etherstub 9000  unknown  --
#

# dladm create-vnic -l etherstub0 vnic0   … etherstub0上にvnic0を作成
# dladm create-vnic -l etherstub0 vnic1   … etherstub0上にvnic1,2を作成
# dladm create-vnic -l etherstub0 vnic2
#
# dladm show-link
LINK        CLASS    MTU    STATE    OVER
bfe0        phys     1500   down     --
etherstub0  etherstub 9000  unknown  --
vnic0       vnic     9000   up       etherstub0
vnic1       vnic     9000   up       etherstub0
vnic2       vnic     9000   up       etherstub0
#
# ifconfig vnic0 plumb   ... VNIC の設定&リンクアップ
# ifconfig vnic0 192.168.10.10 up

NAT のセットアップ

vnic1 と vnic2 が、この後作成するコンテナ(zone)に与えられるのですが、 zoneを作る前に、NAT サービスを起動しておきましょう。

# routeadm
              Configuration   Current              Current
                     Option   Configuration        System State
---------------------------------------------------------------
               IPv4 routing   enabled              enabled
               IPv6 routing   disabled             disabled
            IPv4 forwarding   disabled             disabled
            IPv6 forwarding   disabled             disabled

           Routing services   "route:default ripng:default"

Routing daemons:

                      STATE   FMRI
                     online   svc:/network/routing/ndp:default
                     online   svc:/network/routing/route:default
                   disabled   svc:/network/routing/rdisc:default
                   disabled   svc:/network/routing/legacy-routing:ipv4
                   disabled   svc:/network/routing/legacy-routing:ipv6
                   disabled   svc:/network/routing/ripng:default
#
#
# routeadm -u -e ipv4-forwarding      … ipv4-fowardingを活性化
# routeadm -u -d ipv4-routing         … ipv4-routingを非活性化
#
# routeadm
              Configuration   Current              Current
                     Option   Configuration        System State
---------------------------------------------------------------
               IPv4 routing   disabled             disabled
               IPv6 routing   disabled             disabled
            IPv4 forwarding   enabled              enabled
            IPv6 forwarding   disabled             disabled

           Routing services   "route:default ripng:default"

Routing daemons:

                      STATE   FMRI
                     online   svc:/network/routing/ndp:default
                   disabled   svc:/network/routing/route:default
                   disabled   svc:/network/routing/rdisc:default
                   disabled   svc:/network/routing/legacy-routing:ipv4
                   disabled   svc:/network/routing/legacy-routing:ipv6
                   disabled   svc:/network/routing/ripng:default
#
#
# cd /etc/ipf       … ipfilter / ipnat の設定
#
# cat ipnat.conf
map bfe0 192.168.10.0/24 -> 0/32 portmap tcp/udp auto
map bfe0 192.168.10.0/24 -> 0/32
#
#
# svcadm enable network/ipfilter       … ipfilterサービスの起動
# svcs network/ipfilter
STATE          STIME    FMRI
online         12:16:34 svc:/network/ipfilter:default
#
#
# ipnat -l
List of active MAP/Redirect filters:
map bfe0 192.168.10.0/24 -> 0.0.0.0/32 portmap tcp/udp auto
map bfe0 192.168.10.0/24 -> 0.0.0.0/32

List of active sessions:
#

これで 192.168.10.0/24 プライベートネットワークからインターネット へ出られるようになりました。

Zone と Virtual Network の作成

では zone を作りましょう。VNIC を占有するので ip-type は Exclusive IP Zone となります。

# zonecfg -z zone1                … zone1を作成 (vnic1をアタッチ)
zone1: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zone1> create
zonecfg:zone1> set zonepath=/export/home/zone1
zonecfg:zone1> set autoboot=true
zonecfg:zone1> set ip-type=exclusive
zonecfg:zone1> add net
zonecfg:zone1:net> set physical=vnic1
zonecfg:zone1:net> end
zonecfg:zone1> verify
zonecfg:zone1> commit
zonecfg:zone1> exit
#
# zoneadm -z zone1 verify   ... 作成した zone 構成の検証
WARNING: /export/home/zone1 does not exist, so it could not be verified.
When 'zoneadm install' is run, 'install' will try to create
/export/home/zone1, and 'verify' will be tried again,
but the 'verify' may fail if:
the parent directory of /export/home/zone1 is group- or other-writable
or
/export/home/zone1 overlaps with any other installed zones.
#
#
# zoneadm -z zone1 install   ... zone1 のインストール
WARNING: skipping network interface 'vnic1' which is used in the global zone.
A ZFS file system has been created for this zone.
   Publisher: Using opensolaris.org (http://pkg.opensolaris.org/release/).
       Image: Preparing at /export/home/zone1/root.
Sanity Check: Looking for 'entire' incorporation.
  Installing: Core System (output follows)
...

# zoneadm list -iv   ... インストールの確認
  ID NAME             STATUS     PATH                           BRAND    IP
   0 global           running    /                              native   shared
   - zone1            installed  /export/home/zone1             ipkg     excl

#
# zoneadm -z zone1 boot
#
# zlogin -C zone1      ... Zone の初期設定

                  Host name: zone1
                 IP address: 192.168.10.11
    System part of a subnet: Yes
                    Netmask: 255.255.255.0
                Enable IPv6: No
              Default Route: Specify one
          Router IP Address: 192.168.10.10

vnic1 を持った zone1 が完成しました。global zone の vnic0 とつな がっているか確認してみましょう。

zone1# ping 192.168.10.10       … global zoneの vnic0と通信できた
192.168.10.10 is alive

次に clone 機能を使ってもう1つの zone を作ります。先に zone1 を shutdown しておいてください。

# zoneadm list -iv  ........ zone1 は停止している
  ID NAME             STATUS     PATH                           BRAND    IP
   0 global           running    /                              native   shared
   - zone1            installed  /export/home/zone1             ipkg     excl


# zonecfg -z zone2      ... zone2 を作成する
zone2: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:zone2> create
zonecfg:zone2> set zonepath=/export/home/zone2
zonecfg:zone2> set autoboot=true
zonecfg:zone2> set ip-type=exclusive
zonecfg:zone2> add net
zonecfg:zone2:net> set physical=vnic2
zonecfg:zone2:net> end
zonecfg:zone2> verify
zonecfg:zone2> commit
zonecfg:zone2> exit



# zoneadm -z zone2 clone zone1   ... zone1 を基に clone を実行
sys-unconfig started 2009年07月15日 15時52分03秒
rm: /export/home/zone2/root/etc/vfstab.sys-u: No such file or directory
sys-unconfig completed Wed Jul 15 15:52:04 2009
#

# zoneadm list -iv
  ID NAME             STATUS     PATH                           BRAND    IP
   0 global           running    /                              native   shared
   - zone1            installed  /export/home/zone1             ipkg     excl
   - zone2            installed  /export/home/zone2             ipkg     excl

zone1 と zone2 をそれぞれ起動します。zone2 は初回起動なので、パラ メータを与えます。

# zoneadm -z zone1 boot

# zoneadm -z zone2 boot     ...  zone2 を起動
                  Host name: zone2
                 IP address: 192.168.10.12
    System part of a subnet: Yes
                    Netmask: 255.255.255.0
                Enable IPv6: No
              Default Route: Specify one
          Router IP Address: 192.168.10.10

これで Virtual Network が完成しました。 ネットワーク構成は次のようになっているはずです。それぞれお互いに 接続可能か ping コマンドなどで試してみましょう。

global zone   vnic0   192.168.10.10
zone1         vnic1   192.168.10.11
zone2         vnic2   192.168.10.12

etherstub に対して snoop コマンドも使えます。

# snoop -d etherstub0


Flow Control (Network QoS) を設定する

Project Crossbow の Flow Control では帯域制御と優先制御が可能ですが、 今回は帯域制御により HTTP コンテンツダウンロードの速度を制限して みましょう。global zone 上で Apache2 Web Server を立ち上げ、zone1 のクライアントがコンテンツをリクエストします。

まず global zone に Apache2 をインストールします。パッケージ マネージャを使えば簡単です。

* Apache2 を global zone へインストールする
  - Package Manager GUI を利用し Apache2.2 をインストール
  - /etc/apache2/2.2/httpd.conf はデフォルトのまま

# svcadm enable apache22   ... Apache2 を起動
# svcs apache22
STATE          STIME    FMRI
online         11:15:27 svc:/network/http:apache22

DocumentRoot は /var/apache2/2.2/htdocs なので、ここに大きめのファイルを置くこととします。何でも良いのですが、手元にあった OpenSolaris 2009.06 の ISO イメージを使ってみました。

次に zone1 へログインし wget をインストールします。 パッケージマネージャが外部のサーバへアクセスするので DNS の設定をして置いてください。

zone1# pkg install SUNWwget     … wgetのインストール
DOWNLOAD                                    PKGS       FILES     XFER (MB)
Completed                                    1/1       41/41     0.60/0.60

PHASE                                        ACTIONS
Install Phase                                132/132

zone1# which wget
/usr/bin/wget

できました。とりあえずダウンロードしてみます。

zone1# wget http://192.168.10.10/osol-0906-x86.iso   ... global zone からデータ取得
--11:33:42--  http://192.168.10.10/osol-0906-x86.iso
           => `osol-0906-x86.iso'
Connecting to 192.168.10.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 709,871,616 (677M) [application/octet-stream]

100%[====================================>] 709,871,616   76.01M/s    ETA 00:00

11:33:51 (73.18 MB/s) - `osol-0906-x86.iso' saved [709871616/709871616]

73.18 MB/s ほどの転送速度がでています。ちなみにリアルタイムの I/O statistics を見るには、以下のように dladm コマンドを使います (global zone で実行してください)。

(global zone)

# dladm show-link -s -i3 vnic0    ... トラフィック監視コマンド
LINK            IPACKETS   RBYTES   IERRORS    OPACKETS     OBYTES       OERRORS
vnic0           127454     7726611  0          182076       1469324223   0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0
vnic0           8          816      0          16           1248         0
vnic0           5339       289972   0          9863         81142533     0
vnic0           15542      841460   0          29119        239992394    0
vnic0           15484      837928   0          29291        241410706    0
vnic0           9836       532824   0          18448        152009568    0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0

では、vnic0 に http port 番号で帯域制限をかけてみましょう。

(global zone)

(vnic0_httpflow の作成)
# flowadm add-flow -l vnic0 -a transport=tcp,local_port=80 vnic0_httpflow
# flowadm show-flow
FLOW        LINK        IPADDR                         PROTO  PORT    DSFLD
vnic0_httpflow vnic0    --                             tcp    80      --


(flow に帯域制限を設定)
# flowadm set-flowprop -p maxbw=100 vnic0_httpflow
#
# flowadm show-flowprop
FLOW         PROPERTY        VALUE          DEFAULT        POSSIBLE
vnic0_httpflow maxbw           100          --             100
vnic0_httpflow priority      --             --

もう一度 wget でダウンロードしてみます。

(zone1)

zone1# wget http://192.168.10.10/osol-0906-x86.iso
--12:15:53--  http://192.168.10.10/osol-0906-x86.iso
           => `osol-0906-x86.iso.1'
Connecting to 192.168.10.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 709,871,616 (677M) [application/octet-stream]

100%[====================================>] 709,871,616   12.41M/s    ETA 00:00

12:16:47 (12.47 MB/s) - `osol-0906-x86.iso.1' saved [709871616/709871616]

確かに 12.47 MB/s (100Mbps) に帯域制限されています。

ではもう一度、今度は remote_ip で帯域制限を掛けてみます。 zone1(192.168.10.11) からのパケットを flow として切り出し、この帯域を50Mbpsに制限します。

(global zone)

# flowadm add-flow -l vnic0 -a remote_ip=192.168.10.11 zone1flow
    (zone1 の IP-address は 192.168.10.11)

# flowadm show-flow
FLOW        LINK        IPADDR                         PROTO  PORT    DSFLD
zone1flow   vnic0       RMT:192.168.10.11/32           --     --      --

# flowadm set-flowprop -p maxbw=50 zone1flow

# flowadm show-flowprop
FLOW         PROPERTY        VALUE          DEFAULT        POSSIBLE
zone1flow    maxbw              50          --             50
zone1flow    priority        --             --

zone1 にて wget を実行します。

zone1# wget http://192.168.10.10/osol-0906-x86.iso
--12:42:32--  http://192.168.10.10/osol-0906-x86.iso
           => `osol-0906-x86.iso.3'
Connecting to 192.168.10.10:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 709,871,616 (677M) [application/octet-stream]

100%[====================================>] 709,871,616    5.96M/s    ETA 00:00

12:44:50 (4.92 MB/s) - `osol-0906-x86.iso.3' saved [709871616/709871616]

4.92 MB/s (50Mbps) に帯域制限されています。この時の I/O statistics は次の通りです。

(global zone でtrafficを確認)

# dladm show-link -s -i3 vnic0
LINK            IPACKETS   RBYTES   IERRORS    OPACKETS     OBYTES       OERRORS
vnic0           315631     18038505 0          541417       4421741359   0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0
vnic0           0          0        0          0            0            0
vnic0           835        47092    0          1625         13252705     0
vnic0           1036       57864    0          2035         16657730     0
vnic0           935        52282    0          1821         14901278     0
vnic0           1012       56712    0          1969         16113494     0
vnic0           1064       59392    0          2075         16995762     0
vnic0           1004       56136    0          1958         16030980     0
vnic0           985        54982    0          1924         15742424     0
vnic0           899        50338    0          1751         14332250     0
vnic0           959        53450    0          1882         15404284     0
....


以上、いかがだったでしょうか?Crossbow / Zone 共に高機能かつ軽量な 最強コンビです。仮想化統合の定番として是非ご活用ください。