knqyf263's blog

自分のためのメモとして残しておくためのブログ。

KVM仮想環境構築

今更ですが、KVMの環境構築についてまとめます。 というのも、ちょっとしたトラブルでHVが全て消えてしまって再構築が必要になったのに、きちんとした作業メモを残して置かなかったために現在苦労しているからです。 自分用なので簡易なメモになります。 とりあえずvirt-managerを起動するところまでのメモです。

環境

環境ですが、ホストOSにはDebian 7.3を利用しています。 OSを入れただけの状態で、インターネットにはつながっている状況を想定しています。 ホストOSとゲストOSのネットワークには192.168.122.0/24を使っています。

ホストOS:Debian 7.3(wheezy)
IPアドレス:192.168.122.1
ネットワーク:192.168.122.0/24

参考サイト

4.2. インストール
SL6.3でKVM構築

事前準備

KVMのインストールを始める前に、事前準備をします。 これはインストールの時の設定によるので、人によって違うと思いますが僕の環境でのメモなので一応残しておきます。

/sbinにパスを通す

.bashrcに次の行を追加。

$ vim ~/.bashrc
+export PATH=$PATH:/sbin
欲しいパッケージをインストール

好きなエディタをインストールしてください。今回はvimを使って設定していきます。 あとはページャとしてlessを入れました。ついでにlsb-releaseも。

$ sudo apt-get install vim less lsb-release

KVMのインストール

ではKVMのインストールをしてきます。

KVMに必要なパッケージをインストール

$ sudo apt-get install kvm libvirt-bin virt-manager sasl2-bin nfs-kernel-server

大量にパッケージがインストールされるので少し待ちます。

libvirtの設定

KVM仮想マシンの管理にlibvirtを使うので、libvirtの設定を行っていきます。

非セキュアなTCP接続を待ち受ける

後にlive migrationなどするために、TLS を使わずにベアTCP を使用します。 TCPを有効にし、TLSを無効にするため、/etc/libvirt/libvirtd.confに下記の設定を行います。 コメントアウトしてあるので、コメントアウトを外すだけでも良いです。

$ sudo vim /etc/libvirt/libvirtd.conf
+listen_tls = 0
+listen_tcp = 1

libvirtの設定を変えたので、さらにlibvirtdが起動するときのパラメータも変更します。 /etc/init/libvirt-bin.confのlibvirtd_optsの行に-lを加えます。

$ sudo vim /etc/default/libvirt-bin
- libvirtd_opts=”-d”
+ libvirtd_opts=”-d -l”
libvirt APIデーモンのアカウント設定

libvirt APIデーモンのアカウントを設定しますが、ここではtestとします。 コマンドを打つとパスワードを聞かれるので、強固なパスワードを設定してください。

$ sudo saslpasswd2 -a libvirt test
Password:
Again (for verification):
libvirtの再起動
$ sudo /etc/init.d/libvirt-bin restart

ホストOSのネットワーク設定

interfacesの編集

br0というブリッジインタフェースを作成し、そこにeth0を結びつけます。 この場合、eth0はただのパケットの通り道であり、UTPが通っているのと同じような状況なので、eth0にはアドレスはつきません。 eth0について既に設定があった場合はコメントアウトして以下の設定を追加してください。

$ sudo vim /etc/network/interfaces
+ auto eth0
+ iface eth0 inet manual
+       pre-up ifconfig eth0 up
+ auto br0
+ iface br0 inet static
+       address 192.168.122.1
+       netmask 255.255.255.0
+       network 192.168.122.0
+       broadcast 192.168.122.255
+       bridge_ports eth0
+       bridge_stp off
+       bridge_maxwait 0
+       bridge_fd 0
ネットワークを再起動
$ sudo /etc/init.d/networking restart

virt-managerの起動

サーバにsshでログインする際にオプションで-Xを使うことで、X Window Systemをローカルに飛ばすことができます。 簡単にいえば、KVMの設定画面が手元のPCでGUIで見れます。 Macの場合は、XQuartzを予めインストールしておき、以下のようにします。

$ ssh -X <サーバIPアドレス>

sshでログインしたあと、そこで以下のコマンドを打ちます。

$ sudo XAUTHORITY=~/.Xauthority virt-manager

これで手元のMacvirt-managerが見られれば成功です。

Open vSwitchでNetFlow設定

前回はOpen vSwitchでsFlowの設定を行ったので、今回はNetFlowを取得するための設定を行いたいと思います。 基本的にsFlowの時と同じ考え方でやっています。 NetFlowの説明を以下に引用します。

NetFlowは、米シスコシステムズが開発したトラフィック管理用技術です。主にシスコ製のルーターやLANスイッチにソフトウエア機能(IOS拡張機能)として実装されていますが、ほかのベンダーのネットワーク機器でもサポートしている製品があります。NetFlowは、ネットワーク機器上で「フロー」(TCP、UDPやICMPのあて先、送信元のIPアドレスとポート番号の組み合わせで識別するセッション)単位でパケット数やバイト数を集計し、集計データをUDPベースのNetFlowパケットで管理ステーション(NetFlowでも「コレクタ」と呼ぶ)に送信します
引用元:ネットワーク管理者のためのトラフィック管理入門 - 第3章 トラフィック管理技術とその比較:ITpro

今回はNetFlowエージェントがOpen vSwitchで、NetFlowコレクタは別にサーバを用意した環境を想定しています。 この記事ではNetFlowエージェント側の設定について説明します。 僕が用意した環境は以下のようになっています。

環境

NetFlowエージェント
Open vSwitch:1.4.2
インタフェース:ovsbr0
IPアドレス:192.168.122.1

NetFlowコレクタ
OS:Ubuntu 13.10
IPアドレス:192.168.122.22

NetFlowエージェントの設定

NetFlowの設定作成

本環境では以下の様な設定となります。

COLLECTOR_IP=192.168.122.22  
COLLECTOR_PORT=5566  
ACTIVE_TIMEOUT=30  

COLLECTOR_IPはコレクタのIPアドレスで、192.168.122.22、COLLECTOR_PORTはコレクタに送る際の送信先ポート番号で、5566番としています。 上記の値を反映するためのコマンドは以下になります。

#  ovs-vsctl -- set Bridge ovsbr0 netflow=@nf -- --id=@nf  
create NetFlow target=\"192.168.122.22:5566\" active-timeout=30 

NetFlowの設定確認

NetFlowの設定が正しく入っているかを確認します。

# ovs-vsctl list netflow
_uuid               : f7eebd0b-6a8f-4d86-911a-b61c5246273a
active_timeout      : 30
add_id_to_interface : false
engine_id           : []
engine_type         : []
external_ids        : {}
targets             : ["192.168.122.22:5566"]

次に、正しくパケットが流れているかを確認します。

# tcpdump -ni ovsbr0 udp port 5566
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on ovsbr0, link-type EN10MB (Ethernet), capture size 65535 bytes
15:46:27.870141 IP 192.168.122.1.40117 > 192.168.122.22.5566: UDP, length 72
15:46:30.873135 IP 192.168.122.1.40117 > 192.168.122.22.5566: UDP, length 120
15:46:35.878141 IP 192.168.122.1.40117 > 192.168.122.22.5566: UDP, length 72

NetFlowエージェントのIPアドレス192.168.122.1からNetFlowコレクタのIPアドレス192.168.122.22のポート番号の5566番に対してUDPパケットが送信されているのが確認できます。

NetFlowの設定削除

NetFlowの設定を削除したくなった場合、以下のコマンドで削除することができます。

$ ovs-vsctl remove bridge ovsbr0 netflow $NETFLOWUUID 

$NETFLOWUUIDは、上の設定確認で表示されている_uuidなので、今回は

$ ovs-vsctl remove bridge ovsbr0 netflow f7eebd0b-6a8f-4d86-911a-b61c5246273a

で削除できる。
また、NetFlowの設定全てを削除する場合は、removeでなくclearを使っても良い。

$ ovs-vsctl clear Bridge ovsbr0 netflow

NetFlowコレクタの設定は次回以降にします。

Open vSwitchでsFlow設定

今回はOpen vSwitchでsFlowを取得するための設定を行いたいと思います。 設定方法はOpen vSwitchの公式サイトを参考にしました( sFlow | Open vSwitch)。 というかそのままのことをやってみただけです。 自分の解釈なので間違ってたらすみません。。 sFlowの説明を以下に引用します。

sFlowは、LANスイッチやルーターなどを流れるトラフィックをモニターして、トラフィックに関する情報を送信するsFlowエージェントと、トラフィック情報を受信して解析するsFlowコレクタで構成します。sFlowエージェントは、主にLANスイッチに内蔵する形で実装されています。
引用元:ネットワーク管理者のためのトラフィック管理入門 - 第1章 sFlowとは:ITpro

今回はsFlowエージェントがOpen vSwitchで、sFlowコレクタは別にサーバを用意した環境を想定しています。 僕が用意した環境は以下のようになっています。

環境

sFlowエージェント
Open vSwitch:1.4.2
インタフェース:ovsbr0
IPアドレス:192.168.122.1

sFlowコレクタ
OS:Ubuntu 13.10
IPアドレス:192.168.122.22

sFlowエージェントの設定

sFlowの設定作成

今回はsFlowエージェントであるOpen vSwitchの設定をします。 本環境では以下の様な設定となります。

COLLECTOR_IP=192.168.122.22
COLLECTOR_PORT=6343
AGENT_IP=ovsbr0
HEADER_BYTES=128
SAMPLING_N=64
POLLING_SECS=10

COLLECTOR_IPはコレクタのIPアドレスで、192.168.122.22、COLLECTOR_PORTはコレクタに送る際の送信先ポート番号で、6343番としています。 6343番はsFlowのデフォルトポートです。 AGENT_IPはエージェントがsFlowのパケットを送信する際の送信元のIPアドレスで、今回はovsbr0としたので192.168.122.1から送信されます。
上記の値を以下のコマンドに代入します。

# ovs-vsctl — –id=@sflow create sflow agent=${AGENT_IP}  
target=\”${COLLECTOR_IP}:${COLLECTOR_PORT}\”  
header=${HEADER_BYTES} sampling=${SAMPLING_N} 
polling=${POLLING_SECS} — set bridge br0 sflow=@sflow

僕の環境では以下のようになります。

# ovs-vsctl -- --id=@s create sFlow agent=ovsbr0   
target=\"192.168.122.22:6343\" header=128  
sampling=64 polling=10 -- set Bridge ovsbr0 sflow=@s

sFlowの設定確認

sFlowの設定が正しく入っているかを確認します。

# ovs-vsctl list sflow
_uuid               : 4854f279-eadf-4257-ba1d-b1e862e5f9a2
agent               : "ovsbr0"
external_ids        : {}
header              : 128
polling             : 10
sampling            : 64
targets             : ["192.168.122.22:6343"]

次に、正しくパケットが流れているかを確認します。

# tcpdump -ni ovsbr0 udp port 6343
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode  
listening on ovsbr0, link-type EN10MB (Ethernet), capture size 65535 bytes  
19:22:30.269169 IP 192.168.122.1.46682 > 192.168.122.22.6343: sFlowv5, IPv4 agent 192.168.122.1, agent-id 2, length 260  
19:22:35.269066 IP 192.168.122.1.46682 > 192.168.122.22.6343: sFlowv5, IPv4 agent 192.168.122.1, agent-id 1, length 144  
19:22:37.269026 IP 192.168.122.1.46682 > 192.168.122.22.6343: sFlowv5, IPv4 agent 192.168.122.1, agent-id 1, length 144  

sFlowエージェントのIPアドレス192.168.122.1からsFlowコレクタのIPアドレス192.168.122.22のポート番号の6343番に対してUDPパケットが送信されているのが確認できる。

sFlowの設定削除

sFlowの設定を削除したくなった場合、以下のコマンドで削除することができる。

$ ovs-vsctl remove bridge ovsbr0 sflow $SFLOWUUID 

$SFLOWUUIDは、上の設定確認で表示されている_uuidなので、今回は

$ ovs-vsctl remove bridge ovsbr0 sflow 4854f279-eadf-4257-ba1d-b1e862e5f9a2

で削除できる。
また、sFlowの設定全てを削除する場合は、removeでなくclearを使っても良い。

$ ovs-vsctl clear Bridge ovsbr0 sflow

sFlowコレクタの設定は次回以降にします。

Open vSwitchでポートミラーリング設定

前回の記事で設定したOpen vSwtichでポートミラーリングしてみます。 環境は前回と同様、Debian 7.2上で構築したKVMでVMが動作しているとします。 今回はhost01がvnet1に接続され、host02がvnet2に接続されている状況を想定しています。 また、以下の作業は全てrootとして行っています。

環境

OS:Debian 7.2
Open vSwitch:1.4.2

host01:vnet1
host02:vnet2

参考にしたサイト

設定

ovsの状態の確認

vnet1vnet2ovsbr0に接続されていることを確認する。

# ovs-vsctl show
238d066c-8354-4978-a9f4-39a98fa2d2e9
    Bridge "ovsbr0"
        Port "eth0"
            Interface "eth0"
        Port "ovsbr0"
            Interface "ovsbr0"
                type: internal
        Port "vnet1"
            Interface "vnet1"
        Port "vnet2"
            Interface "vnet2"
    ovs_version: "1.4.2"
ミラーリングの設定の確認

何も表示されないことを確認する。

# ovs-vsctl list Mirror 
#
ミラーリングの設定を作成する
# ovs-vsctl -- set bridge ovsbr0 mirrors=@m -- --id=@vnet1 get Port vnet1 -- --id=@vnet2 get Port vnet2 -- --id=@m create Mirror name=mirror_test select-dst-port=@vnet1 select-src-port=@vnet1 output-port=@vnet2 
b073490c-5a64-4d80-93ca-534f29c09027

上記設定では、vnet1を通るパケットを全てvnet2にミラーリングしている。
具体的に説明すると、set bridge [設定するbridge名]。今回はovsbr0
次に、get Portによってvnet1vnet2のidを取得する。
create Mirror name="ミラーリング名”でMirrorの名前を決める。
select-dst-portは、そのポートから出て行くパケット、select-src-portは、そのポートに入ってくるパケットを指す。今はどちらもvnet1にしているので、どちらのパケットも対象となっている。
最後にoutput-portでミラーリングしたパケットを出力する場所を決めている。
成功するとidが出力される。

ミラーリングの設定を確認する
# ovs-vsctl list Mirror 
_uuid               : b073490c-5a64-4d80-93ca-534f29c09027
external_ids        : {}
name                : mirror_test
output_port         : 6b80f606-516c-4304-91a3-0217b02e408b
output_vlan         : []
select_all          : false
select_dst_port     : [b3ef508f-cdca-4a42-921e-9a96fffff98b]
select_src_port     : [b3ef508f-cdca-4a42-921e-9a96fffff98b]
select_vlan         : []
statistics          : {tx_bytes=24430, tx_packets=380}
ミラーリングの設定削除

ミラーリングの設定が不要となった場合に全設定を削除するコマンドは以下。

# ovs-vsctl clear bridge ovsbr0 mirrors 

KVM環境でLinux標準ブリッジの代わりにOpen vSwitchを利用する

KVM環境で通常はLinux標準ブリッジであるbrctlを利用するが、今回はOpen vSwitchにbridgeの役割をさせてみようと思います。 KVM環境は構築済みとします。 OSはDebian 7.2で、apt-getでinstallしたらOpen vSwitchのバージョンは1.4.2が入ったのでそのまま利用しています。

環境

OS:Debian 7.2
Open vSwitch:1.4.2

参考にしたサイト

Open vSwitchのインストール

openvswitch-datapathモジュールをインストール
    $ sudo apt-get install linux-headers-`uname -r` linux-source build-essential
    $ sudo apt-get install openvswitch-datapath-source module-assistant
モジュールのビルド&インストール
    $ sudo m-a a-i openvswitch-datapath
openvswitch-switchのインストール
    $ sudo apt-get install openvswitch-switch
Linuxの標準bridge(brctl)の代わりにOpen vSwtichを利用するためにbrctl互換のbridge compatibilityをインストール
    $ sudo apt-get install openvswitch-brcompat
bridge compatibilityを有効にするため/etc/default/openvswitch-switchを編集
    $ sudo vim /etc/default/openvswitch-switch
    #BRCOMPAT=no
    BRCOMPAT=yes
Linux bridgeの動作確認

Linux bridgeが動作しているとOpen vSwitchは動作しないので、動作しているか確認

    $  lsmod | grep bridge

表示された場合は、削除

    $ rmmod bridge
openvswitch再起動
    $ sudo service openvswitch-switch restart
起動確認
    $ sudo lsmod | grep brcompat
    brcompat_mod 13031 0
    openvswitch_mod 67948 1 brcompat_mod

Open vSwitch(OVS) bridgeの設定

OVS bridgeインタフェースの追加
    $ sudo ovs-vsctl add-br ovsbr0
OVS bridge(ovsbr0)とeth0を接続
    $ sudo ovs-vsctl add-port ovsbr0 eth0
eth0に付いているIPアドレスを消し、ovsbr0にIPアドレスを付ける
    $ sudo ifconfig eth0 0.0.0.0
    $ sudo ifconfig ovsbr0 192.168.100.1/24
DHCPが動いている場合、eth0で動いているdhclientをovsbr0と結びつける
    $ dhclient ovsbr0 &
現在の設定の確認
  $ sudo ovs-vsctl show
  238d066c-8354-4978-a9f4-39a98fa2d2e9
      Bridge "ovsbr0"
          Port "eth0"
              Interface "eth0"
          Port "ovsbr0"
              Interface "ovsbr0"
                  type: internal
      ovs_version: "1.4.2"

KVM上のゲストの設定

KVM上でhost01というVMが動いていると想定する。

host01をshutdownする
    $ virsh shutdown host01
host01のXMLを編集する
    $ virsh edit host01
+の付いているところを編集
[...]
        <interface type='bridge'>
                <mac address='52:54:00:ad:c1:7c'/>
                +<source bridge='ovsbr0'/>
                +<virtualport type='openvswitch'>
                <model type='virtio'/>
                <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
        </interface>
[...]
XMLを保存した後、再度表示するとinterfaceidが自動的に生成されている
$ virsh dumpxml host01 | grep bridge -A8
    <interface type='bridge'>
      <mac address='52:54:00:ad:c1:7c'/>
      <source bridge='ovsbr0'/>
      <virtualport type='openvswitch'>
        +<parameters interfaceid='81d6a11b-e89e-9037-f6bb-994b2fbc9dcc'/>
      </virtualport>
      <model type='virtio'/>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </interface>
host01を起動する
    $ virsh start host01
ovsの設定を確認する
  $ sudo ovs-vsctl show
  238d066c-8354-4978-a9f4-39a98fa2d2e9
      Bridge "ovsbr0"
          Port "eth0"
              Interface "eth0"
          Port "ovsbr0"
              Interface "ovsbr0"
                  type: internal
          Port "vnet0"
              Interface "vnet0"
                  ovs_version: "1.4.2"

host01用のインタフェースvnet0が生成され、ovsbr0に接続されている。

host01のコンソールに接続して、IPアドレスを設定したあと疎通確認する
$ virsh console host01
$ sudo ifconfig eth0 192.168.100.2/24
$ ping 192.168.100.1