KVM (Kernel-based Virtual Machine) による仮想環境の構築手順(KVMのインストールと仮想ネットワーク作成手順)

公開日:2013/07/09 更新日:2013/07/09
KVM (Kernel-based Virtual Machine) による仮想環境の構築手順(KVMのインストールと仮想ネットワーク作成手順)のサムネイル

私は、ApacheやSquid、vyattaやその他多くのソフトウェアを検証する環境として、ubuntu上のKVM (Kernel-based Virtual Machine)によって構築した仮想環境を利用しています。そこで、備忘録として、よく使用する基本的なKVM仮想環境の構築手順を載せておきます。

KVMを使う前の確認事項

KVMを使用するには、KVMを動作させるPCのCPUが、仮想化支援機構(Intel-VTもしくはAMD-V)に対応している必要があります。今回はubuntuにKVMをインストールするので、ubuntuがインストールされたPCのCPUが仮想化支援機構に対応しているかを確認します。確認方法は、IntelのCPUの場合は、ubuntuのターミナル上で以下のコマンドを実行します。

$ grep vmx /proc/cpuinfo

実行した結果、下記のようにflagsから始まる出力が得られれば使っているCPUが仮想化支援機構に対応していることになります。

$ flags  : fpu vme de pse tsc msr pae mce cx8 apic...(省略)

AMDのCPUの場合は以下のコマンドを実行して確認します。

$ grep smv /proc/cpuinfo

ただし、CPUが仮想化支援機構に対応していても、有効になっていない場合は上記のコマンドを実行しても何も出力されません。よって、何も表示されなかった場合はBIOS設定から仮想化支援機構が有効にできるかどうかを確認すると良いと思います。なお、BIOS設定の確認方法は下記のサイトを参考にすると良いと思います。

BIOSの設定変更 https://www.oss-d.net/virt/kvm

KVMを用いて構築する仮想環境の概要

KVMを用いて構築する仮想環境のイメージ図は以下の図になります。下図のように、仮想マシンとしてubuntu1、ubuntu2、vyattaA、vyattaB、vyattaCの合計5台を作成し、ubuntu1とubuntu2同士が、vyattaA,B,Cによって構築されたネットワークを介して通信し、各ubuntuがインターネットへアクセスできる仮想環境を構築します。

[![kvm_standard1.png](/images/2013/04/kvm_standard1.png)](https://virment.com/images/2013/04/kvm_standard1.png) 図1 KVMによって構築する仮想環境イメージ図

KVM仮想環境構築に必要なステップ

上図の仮想環境を構築するためには、以下の8ステップが必要になります。

      1. KVMと関連ソフトウェアをインストール
      2. 仮想ネットワークの作成
      3. 仮想マシンの作成
      4. 仮想マシンのIPアドレス、ゲートウェイの設定
      5. vyattaのOSPFの設定
      6. iptablesの設定
      7. ip_forwardの設定
      8. vyattaのNAT、DNSの設定
各ステップの詳細を何回かに分けてメモしていきたいと思います。以下ではKVMのインストール手順と仮想ネットワークの作成手順について説明してきます。

1. KVMと関連ソフトウェアをインストール

ubuntu12.04に以下の3つのソフトウェアをインストールします。

  • KVM : 仮想環境ソフトウェア
  • virt-manager : GUIで仮想マシンの管理を行うためのソフトウェア
  • virt-top : 仮想マシンのリソース使用率(CPU使用率、メモリ使用率など)を把握するためのコマンドを実行可能にするソフトウェア
以下のコマンドをターミナル上で実行することによって、上記3つがインストールされます。
$ sudo apt-get install kvm
$ sudo apt-get install virt-manager
$ sudo apt-get install virt-top

インストール完了後、次は仮想ネットワークを作成していきます。

仮想ネットワークの作成

まずは仮想マシンから作成していきたいところですが、説明の便宜上、まずはじめに仮想ネットワークについて簡単に説明し、仮想ネットワークを先に作成します。

KVMによる仮想ネットワークについて

今回構築する仮想環境には、以下の図のように、「isolate_net1」、「isolate_net2」、「WAN1」、「default」の4つの仮想ネットワークが存在します。

virtual_net_configure.png 図2 仮想ネットワーク図

各仮想ネットワークのネットワークアドレスは以下のように設定します。また、各仮想マシンのIPアドレスは図2中のように設定します。ただし、「default」はKVMをインストールした時点でデフォルトで作成される仮想ネットワークであり、ネットワークアドレスが「192.168.122.0/24」に設定されます。

      isolate_net1 : 192.168.100.0/24
      isolate_net2 : 192.168.200.0/24
      WAN1 : 172.16.10.0/24
      deafult : 192.168.122.0/24 (KVMインストール時点でデフォルトで作成されます)
ここでは、仮想ネットワーク「isolate_net1」の作成方法について説明していきます。他の「isolate_net2」、「WAN1」についても同様の方法で作成できます。

仮想ネットワークの作成手順

まずubuntuのターミナル上で以下のコマンドを実行しvirt-managerを起動します。

$ virt-manager

virt-managerを起動すると、以下のような画面が表示されます。

virt_manager_screen.png

virt-managerを起動した状態で、以下のようにvirt-managerのメニューの「編集」から「接続の詳細」を開きます。

connect_detail.png

「接続の詳細」を開いた後、「仮想ネットワーク」タブをクリックすると、以下のように作成済みの仮想ネットワーク一覧が表示されます。これまでに仮想ネットワークを作成していない場合は、以下のようにデフォルトで作成済みの「default」のみが表示されると思います。

create_net01.png

そして、上の画面内の左下にある十字マークをクリックすると、以下のように「新しい仮想ネットワークの作成」というタイトルのウィンドウが表示されます。ここから新しく仮想ネットワークを作成していきます。「進む」をクリックして次に進みます。

create_netwrok1.png

すると、以下のように「仮想ネットワークの名前の指定」というタイトルのウィンドウが表示されますので、適当な名前を入力して「進む」をクリックします。以下では「isolate_net1」という名前を指定しています。

create_network2.png

次に「IPv4アドレス領域の指定」というタイトルのウィンドウが表示されます。ここでは、これから作成する仮想ネットワークで使用するネットワークアドレスを指定します。isolate_net1は「192.168.100.0/24」に設定したいので、192.168.100.0/24を入力します。

create_network3.png

進むと次は指定した範囲のIPアドレスを割り振るDHCPサーバの設定を行います。DHCPサーバを使用しない場合は、「DHCPを有効に(E)」のチェックボックスを外して次に進みます。DHCPサーバを使用する場合は、割り振るIPアドレスの範囲を開始と終了で指定して次に進みます。

create_network4.png

「進む」をクリックすると、以下の「物理ネットワークへの接続」というタイトルの画面が表示されます。KVMでは「隔離された仮想ネットワーク」、「物理ネットワークにフォワード」を選択できます。なお、「物理ネットワークにフォワード」を選択した場合は、さらに宛先とモードを選択します。ここでは、「隔離された仮想ネットワーク」を選択して次に進みます。なお、「隔離された仮想ネットワーク」と「物理ネットワークにフォワード」の違いについては、後述します。

create_network5.png

進むと以下のようにこれまでの設定内容が表示されます。問題なければ完了をクリックして仮想ネットワークの作成は完了です。

create_network6.png

仮想ネットワークの作成の意味

仮想ネットワークについて補足するために、図2の「isolate_net1」の部分を簡単なブロック図に変換すると、図3のようになります。上記の手順によって仮想ネットワークを作成すると、図3のように、同じ仮想ネットワーク内に存在する仮想マシン同士(ubuntu1とvyatta A)を接続するための仮想スイッチ「virbr1」が作成されます。すなわち、仮想ネットワークを作成することは、仮想スイッチを作成することと同義です。そして仮想マシンの作成の際に、作成する仮想マシンをどの仮想スイッチに接続するか、すなわち仮想マシンをどの仮想ネットワーク下に配置するかを指定することができます。

isolate_net1_wan1.png 図3 isolate_net1のブロック図

なお、図3中の「vnet0」は、ubuntu1がeth0を通してホストマシンと通信するためのTAPデバイスというものです。「vnet2」についても同様であり、今回の場合はvyatta Aがeth2を通してホストマシンと通信するためのTAPデバイスです。「virbr」「vnet」についてまとめると以下のようになります。

  • vnetX (X = 1, 2, ...)
  • 仮想マシンとホストマシンが通信するために使用するTAPデバイスです。仮想マシンのNIC(図中eth0、eth2)と同じ数だけ作成されます。そしてvnetXは仮想マシンが起動すると同時に起動します。このことは、仮想マシンを起動する前後で、ホストマシンのターミナル上でifconfigコマンドを実行することで確認できます。
  • virbrY (Y = 1, 2, ...)
  • 仮想スイッチです。仮想ネットワークの作成順に連番が振られていきます。KVMをインストールした時点では、virbr0がデフォルトで作成されています。virbr0は仮想ネットワーク「default」の仮想スイッチです。virbrもifconfigコマンドによって確認することができ、virbrはKVMが起動した時点(通常はvirt-managerの起動と同時に)に起動します。

仮想ネットワークの種類について

KVMで仮想ネットワークを作成する際、「物理ネットワークにフォワード」と「隔離された仮想ネットワーク」を選択できます。また、「物理ネットワークにフォワード」を選択した場合は、さらに「宛先」と「モード」を選択することができ、「モード」については「NAT」と「ルーティング」の2種類から選択できます。宛先については、ubuntuでは「いずれかの物理デバイス」しか選択できないようです。ここでは、今回使用する「隔離された仮想ネットワーク」(以下では隔離ネットワークと呼びます)と「物理ネットワークのフォワード」でモードを「NAT」(以下ではNATネットワークと呼びます)に選択した場合について説明します。「ルーティング」を選択した場合についてはまた使用した時に備忘録として載せたいと思います。

  • 隔離ネットワークの場合
  • 「隔離された仮想ネットワーク」を選択すると、以下の図4のような仮想スイッチ (図4中Virtual switch)が作成され、この仮想スイッチに接続されている仮想マシン同士(図4中のVirtual machine 1とVirtual machine 2)は通信することができます。また、仮想マシンとホストマシン同士の通信も可能です。しかし、仮想マシンからホストマシンの外部、また、ホストマシンの外部から仮想マシンへのアクセスはできません。

    なお、KVMでは仮想マシン同士が通信できる環境をホストマシンのiptablesにルールを追加することで実現しています。iptablesへのルール追加はKVMが自動的に行ってくれます。したがって、もしKVMの起動中にiptablesのルールを変更したり、iptablesを停止したりすると、別々の隔離ネットワークに属する仮想マシン同士が通信できてしまうなど、意図しないことが発生するので注意して下さい。具体的にどのようなルールがiptablesに追加されるかは後述します。 今回構築する図2の仮想環境では、「isolate_net1 : 192.168.100.0/24」、「isolate_net2 : 192.168.200.0/24」、「WAN1 : 172.16.10.0/24」の3つを隔離された仮想ネットワークとして作成します。

    [![isolated.png](/images/2013/04/isolated.png)](https://virment.com/images/2013/04/isolated.png) 図4 隔離ネットワークのイメージ図

    また、隔離ネットワークを作成すると、/etc/libvirt/qemu/networks/に、以下の内容のisolate_net1.xmlというファイルが作成されます。
    <network>
      <name>isolate_net1</name>
      <uuid>1e1d-36bf-1e1d-1e1d-1e1dc</uuid>
      <bridge name='virbr1' stp='on' delay='0' />
      <mac address='52:54:00:94:08:5E'/>
      <ip address='192.168.100.1' netmask='255.255.255.0'>
        <dhcp>
          <range start='192.168.100.128' end='192.168.100.254' />
        </dhcp>
      </ip>
    </network>
    

    上記のxmlファイルを見ると、仮想ネットワークの作成時に設定した仮想ネットワークの名前などが記述されていることが分かります。なお、仮想ネットワークの作成時にDHCPを有効にすると、この仮想スイッチがDHCPサーバとして動作することになり、上記のようにDHCPのIPアドレスの範囲がxmlファイルに記述されます。

  • NATネットワークの場合
  • 「物理ネットワークにフォワード」でモードを「NAT」に選択した場合、仮想スイッチ (図5中Virtual switch)は、接続されている仮想マシン同士、仮想マシンとホストマシン同士の通信が可能なだけでなく、ホストマシンを通して外部へアクセスすることができます。なお、隔離ネットワーク同様、KVMはこの仮想スイッチに接続された仮想マシンが外部ネットワークと通信できる環境をホストマシンのiptablesにIPマスカレードのルールを追加することで実現しています。iptablesへのIPマスカレードのルール追加はKVMが自動的に行ってくれます。ただし、もしKVMの起動中にiptablesのルールを初期化したり、iptablesを停止したりすると、仮想マシンは外部へアクセスできなくなるので注意して下さい。もしKVM上で思うような通信が出来なくなった場合は、iptablesのルールを確認すると良いかもしれません。なお、KVMが自動的に追加するルールは後述します。

    [![nat.png](/images/2013/04/nat.png)](https://virment.com/images/2013/04/nat.png) 図5 NATネットワークのイメージ図

    ちなみに、KVMはデフォルトで 「default」という名前のNATネットワークを作成します。 よって、「default」に接続された仮想マシンは、ホストマシンを通してインターネットへアクセスすることができます。 また、/etc/libvirt/qemu/networks/に、以下の内容のNAT1.xmlというファイルが作成されます。

    <network>
      <name>NAT1</name>
      <uuid>f3b9f3b9f3b9f3b9f3b9f3b9</uuid>
      <forward mode='nat'/>
      <bridge name='virbr2' stp='on' delay='0' />
      <mac address='52:54:00:91:1F:86'/>
      <ip address='192.168.200.1' netmask='255.255.255.0'>
        <dhcp>
          <range start='192.168.200.128' end='192.168.200.254' />
        </dhcp>
      </ip>
    </network>
    

    上記のxmlファイルを見ると、隔離ネットワークの場合にはなかった、「<forward mode='nat'/>」という行が追加されていることが分かります。この行がNATを有効にするための記述になります。

    KVMがiptablesに追加するルールについて

    上記でKVMによる仮想ネットワーク作成時には、iptablesにルールが追加されることを書きました。ここでは、具体的に隔離ネットワーク、NATネットワーク、それぞれを選択した場合にどのようなルールがiptablesに追加されるかをメモします。なお、iptablesについて知りたい方はiptablesの概要メモiptablesの設定内容確認と設定例が参考になるかもしれません。

    • 隔離ネットワークの場合
    • 隔離ネットワークを作成した場合、iptablesのfilterテーブルに以下のルールが追加されます。 ・filterテーブル
      $ sudo iptables -nvL
      Chain INPUT (policy ACCEPT 1000 packets, 1000 bytes)
       pkts bytes target     prot opt in     out     source               destination
          0     0 ACCEPT     udp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53
          0     0 ACCEPT     tcp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53
          0     0 ACCEPT     udp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67
          0     0 ACCEPT     tcp  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67
      
      Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
       pkts bytes target     prot opt in     out     source               destination
          0     0 ACCEPT     all  --  virbr1 virbr1  0.0.0.0/0            0.0.0.0/0
          0     0 REJECT     all  --  *      virbr1  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
          0     0 REJECT     all  --  virbr1 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
      
    • NATネットワークの場合
    • NATネットワークを作成した場合、iptablesのfilterテーブルとnatテーブルにそれぞれ以下のルールが追加されます。
      • filterテーブル
      • $ sudo iptables -nvL
        Chain INPUT (policy ACCEPT 1000 packets, 1000K bytes)
         pkts bytes target     prot opt in     out     source               destination
            0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           udp dpt:53
            0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:53
            0     0 ACCEPT     udp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           udp dpt:67
            0     0 ACCEPT     tcp  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           tcp dpt:67
        
        Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
         pkts bytes target     prot opt in     out     source               destination
            0     0 ACCEPT     all  --  *      virbr0  0.0.0.0/0            192.168.122.0/24    state RELATED,ESTABLISHED
            0     0 ACCEPT     all  --  virbr0 *       192.168.122.0/24     0.0.0.0/0
            0     0 ACCEPT     all  --  virbr0 virbr0  0.0.0.0/0            0.0.0.0/0
            0     0 REJECT     all  --  *      virbr0  0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
            0     0 REJECT     all  --  virbr0 *       0.0.0.0/0            0.0.0.0/0           reject-with icmp-port-unreachable
        
      • natテーブル
      • $ sudo iptables -t nat -nvL
        Chain POSTROUTING (policy ACCEPT 1000 packets, 1000 bytes)
         pkts bytes target     prot opt in     out     source               destination
            0     0 MASQUERADE  tcp  --  *      *       192.168.122.0/24    !192.168.122.0/24    masq ports: 1024-65535
            0     0 MASQUERADE  udp  --  *      *       192.168.122.0/24    !192.168.122.0/24    masq ports: 1024-65535
            0     0 MASQUERADE  all  --  *      *       192.168.122.0/24    !192.168.122.0/24
        

      以上のことから、図2のイメージ図をブロック図に変換すると、下の図6のようになります。(図はクリックで拡大できます)図6から分かるように、作成する仮想ネットワークの数だけ仮想スイッチ「virbrX」があり、仮想マシンのNICの数だけ「vnetY」があります。また、「default」の仮想マシンはホストマシンのiptablesによってインターネットへアクセスできます。

      whole_netwrok.png 図6 仮想ネットワークのブロック図

      以上が仮想ネットワークの作成手順になります。次回は仮想マシンの作成手順について載せたいと思います。 こちらに KVMにおける仮想マシンの作成手順をメモしたので必要な方は見てみて下さい。

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。