Ubuntu 16.04 LTS で KVM を使った仮想サーバ ()
職場で教育用に使用する新しいLinux環境が欲しくなって、Ubuntu 16.04 LTS を使った仮想環境を自宅で試してみました。教育用にわざわざハードウェアを準備するのも困難な場合もあり、どこからでも ssh で接続さえすれば同じ環境が (こっそり) 使えます。 前回の Ubuntu 9.10の KVM で仮想サーバ から6年以上経過して、Linux の構成も Systemd を始めとして色々変更されています。
今回はホストは Ubuntu 16.04 LTS 64bit のデスクトップ版で qemu-kvm を使います。ゲストは Ubuntu 16.04 LTS 64bit のサーバ版を使用しました。 vnc のクライアントは、前回 は Windows でUltraVNC を使いましたが、 MacOSXの標準機能で行いました。
今回もKVM の使い方を理解するため、 libvirt を使わずコマンドラインから直接 kvmコマンドを使って仮想マシンをコントロールすることにします。
QEMU
QEMU 自身は色々なCPUを実行できるエミュレータで、CPU命令をソフトウェアでいちいち解釈実行する方法ではなく、動的にコンパイルするような方法を使ってかなり速いエミュレータとして有名でした。PCのハードウェア全体がソフトウェアで実現されていて、昔からOSの開発でも利用されていました。
KVM
Linuxカーネルのモジュールとしての KVM はintelVTやAMD-Dという機能を持つCPUを使って、仮想環境のOSの特権命令まで直接実行する仕組みです。CPUの仮想化支援機能(intelVTまたはAMD-V)にアクセスするためのインタフェース(/dev/kvm)を提供しています。カーネルモード、ユーザモードに加えて、ゲストモードという新しい動作モードが追加されます。CPUで仮想環境の命令を直接実行してしまうので、仮想環境といえども速度の低下は全くありません。ただし、ハードディスクやネットワークカードなどの周辺機器(IO)へのアクセスはトラップされて物理的なデバイスとのインターフェイスがソフトウェアで行われるため、速度は多少遅くなります。
仮想環境としての Linux KVMはこのCPU以外の周辺機器の仮想化を、昔から使われていて安定なQEMUを使うことでPC全体を仮想化(完全仮想化)しています。したがってKVMは仮想環境として、非常に新しい部分(CPUの持つ仮想マシンモニター機能)をシンプルな仕組みでカーネル内に持ち、古い部分(QEMUによるハードウェアエミュレーション)をユーザプロセス側で受け持つ形式でうまく融合したものとなっています。KVM は2007年2月以降のLinuxのカーネル(2.6.20以降)のソースにモジュール(バイナリになると250KB程度とコンパクト)として取り込まれています。GUIが必須ではないのでホスト側のリソース(メモリ、CPU負荷)が無駄にならないため、サーバとして利用するにはよい環境ではないかと思います。
仮想環境の構成
外部のネットワークから見た場合、ホスト1台とゲスト2台の合計3台のサーバが独立して稼働しているような構成とします。 物理的にIPアドレスを別々に持つ3台のサーバがスイッチングハブで接続されているのと同じ状態になります。この例ではゲストOSが2つですが、必要ならばいくつでも増やすことができます。
外部からは以下のように見えることを目指します。ゲストは同様にいくつでも増やせます。
+------+ +-----------------------------------+ | GW +-----+ Switching HUB | +------+ +----+-------------+-------------+--+ 172.18.21.1 | | | +----+-----+ +---+-----+ +---+-----+ | HOST | | GUEST | | GUEST | +----------+ +---------+ +---------+ 172.18.21.80 172.18.21.90 172.18.21.91
ホストとしての64ビット Ubuntu 16.04LTS デスクトップ版のインストール
今回は仮想環境の入れ物(ホストOS)として 64ビット Ubuntuデスクトップ版(ubuntu-16.04-desktop-amd64.iso) をインストールしました。ゲストOSに64ビットを使う場合は64ビット版が必要です。KVMを使うため、BIOSの設定で intelVT または AMD-V を有効にしておきます。 実際のインストールは下のゲストのインストールとほぼ同じです。ホストのディスクのパーティションの構成は環境によって異なり、「Manual」を使うことになると思いますから割愛します。
KVM のインストール
今回も、libvirt を使わないで qemu-kvm を直接使って仮想環境を構築します。qemu-kvm と bridge-utils をインストールします。
jun@xerus:~$ sudo apt-get install qemu-kvm bridge-utils sudo: unable to resolve host xerus Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: cpu-checker msr-tools qemu-system-x86 seabios Suggested packages: vde2 sgabios ovmf The following NEW packages will be installed: bridge-utils cpu-checker msr-tools qemu-kvm qemu-system-x86 seabios 0 upgraded, 6 newly installed, 0 to remove and 1 not upgraded. Need to get 28.6 kB/2921 kB of archives. After this operation, 17.8 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
ホスト側のネットワークの設定
物理的には1台のマシンをネットワーク的には独立した3台のサーバがスイッチングハブで接続されている状態に設定します。
+------+ +-----------------------------------+ | GW +-----+ Switching HUB | +------+ +----+-------------+-------------+--+ 172.18.21.1 | | | +----+-----+ +---+-----+ +---+-----+ | HOST | | GUEST | | GUEST | +----------+ +---------+ +---------+ 172.18.21.80 172.18.21.90 172.18.21.91
ホストとなるマシンのネットワークカード(enp2s0)の内側にブリッジ(br0)があり、仮想マシンはtap デバイスを介してブリッジに接続します。
+-----------------------------------------+ | Host : Ubuntu 16.04LTS amd64 desktop | | | +---+----+ +---------------+ | | enp2s0 +---------+ Switching HUB | | +---+----+ | br0 | | | +-+----------+--+ | | | | | | +------+-+ +-+------+ | | | tap0 | | tap1 | | | +---+----+ +---+----+ | | | | | | +---+----+ +---+----+ | | | KVM | | KVM | | | | QEMU | | QEMU | | | +--------+ +--------+ | | | Guest1 | | Guest2 | | | | LINUX | | LINUX | | | +--------+ +--------+ | +-----------------------------------------+
NetworkManager の削除
仮想マシンをホストと同じネットワークに接続するためにブリッジを作成します。 NetworkManager のアンインストールブリッジの設定は、ネットワークの設定ファイルを編集しますが、 NetworkManagerがジャマになるため削除します。
jun@xerus:~$ sudo apt-get remove network-manager sudo: ホスト xerus の名前解決ができません パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 以下のパッケージが自動でインストールされましたが、もう必要とされていません: plainbox-secure-policy python3-checkbox-support python3-guacamole python3-jinja2 python3-padme python3-plainbox python3-pyparsing python3-xlsxwriter これを削除するには 'sudo apt autoremove' を利用してください。 以下のパッケージは「削除」されます: checkbox-converged checkbox-gui network-manager network-manager-gnome plainbox-provider-checkbox plainbox-provider-resource-generic ubuntu-desktop アップグレード: 0 個、新規インストール: 0 個、削除: 7 個、保留: 1 個。 この操作後に 15.2 MB のディスク容量が解放されます。 続行しますか? [Y/n] y 略
ブリッジの生成
最初にホストのネットワークカード(NIC)を自分宛のEthernetフレーム以外も受け付けるプロミスキャスモード(promiscuous mode)に変更します。プロミスキャスモードにすることでEthernetフレームの宛先MACアドレスが自分と異なる場合でも読み込むことができるため、ブリッジとして動作できるようになります。
次にホスト内にブリッジを生成して、enp2s0をブリッジに繋ぎかえます。ブリッジとは Ethernet Bridge のことで、物理的には普通のスイッチングハブ(レイヤー2スイッチ)と考えることができます。 qemu-kvm をインストールすると自動的にインストールされる bridge-utils パッケージのコマンド 「brctl addbr ブリッジ名」で生成できます。
ブリッジを生成して、enp2s0を繋ぎかえる時にネットワークは一旦切断されるため、シェルスクリプトにしておけばリモートからでも連続してコマンドを実行できます。ブリッジにIPアドレスを設定するとホストも外部ネットワークに接続できます。ネットワークは一旦切断されるため、リモートからSSHで接続している場合は再接続する必要があります。
次に示す「bridge.sh」で上記の設定を一気に行います。最初にあるシェル変数のIPとGATEWAYの値は環境にあわせて変更してください。「sudo sh bridge.sh」で実行できます。 ホストの起動時に自動的にブリッジを生成する方法は後述します。
jun@xerus:~~$ cat bridge.sh
#!/bin/sh
IP=172.18.21.80 # ホストのIPアドレス
GATEWAY=172.18.21.1 # ルータのLAN側IPアドレス
echo "change IP address : $IP"
ifconfig enp2s0 0.0.0.0 promisc up # プロミスキャスモードに設定
brctl addbr br0 # ブリッジの作成
brctl addif br0 enp2s0 # ブリッジにeth0を接続
ifconfig br0 up # ブリッジを起動
ifconfig br0 $IP netmask 255.255.255.0 # ブリッジにIP設定
route add default gw $GATEWAY # ゲートウェイ設定
実行すると ifconfig の出力は以下のようになります。ブリッジのbr0にIPアドレスが設定され、enp2s0 はプロミスキャスモード(PROMISC)になっていることが確認できます。
jun@xerus:~$ ifconfig
br0 Link encap:Ethernet HWaddr 00:1d:60:6d:ae:b4
inet addr:172.18.21.80 Bcast:172.18.21.255 Mask:255.255.255.0
inet6 addr: fe80::21d:60ff:fe6d:aeb4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:126698 errors:0 dropped:0 overruns:0 frame:0
TX packets:70944 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:169672781 (169.6 MB) TX bytes:10101020 (10.1 MB)
enp2s0 Link encap:Ethernet HWaddr 00:1d:60:6d:ae:b4
inet6 addr: fe80::21d:60ff:fe6d:aeb4/64 Scope:Link
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:128243 errors:0 dropped:0 overruns:0 frame:0
TX packets:71192 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:171546528 (171.5 MB) TX bytes:10128274 (10.1 MB)
Interrupt:17
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:285 errors:0 dropped:0 overruns:0 frame:0
TX packets:285 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:29238 (29.2 KB) TX bytes:29238 (29.2 KB)
ホストの起動時に自動的にブリッジを生成するには /etc/network/interfaces を以下のように変更します。
# interfaces(5) file used by ifup(8) and ifdown(8) auto lo iface lo inet loopback #auto enp2s0 #iface enp2s0 inet manual auto br0 iface br0 inet static address 172.18.21.80 netmask 255.255.255.0 network 172.18.21.0 broadcast 172.18.21.255 gateway 172.18.21.1 pre-up ifconfig enp2s0 down pre-up ifconfig enp2s0 0.0.0.0 promisc up pre-up brctl addbr br0 pre-up brctl addif br0 enp2s0 pre-up ifconfig enp2s0 up post-down ifconfig enp2s0 down post-down brctl delif br0 enp2s0 dns-nameservers 172.18.21.1
ホストを起動するとブリッジが有効になっていることが「ifconfig」で確認できます。
仮想ディスクイメージの作成
仮想マシンのハードディスクは仮想ディスクイメージというファイルとして準備する必要があります。仮想ディスクイメージは「qemu-img」コマンドを使って作成します。次の例は 8GB のディスクイメージを qcow2 フォーマットを使って、u1604.qcow2 というファイル名で作成します。ディスクイメージファイルもインストール用の ubuntu-16.04-server-amd64.iso もホストマシンの kvm1604 というフォルダに置いて作業をしています。
jun@xerus:~/kvm1604$ qemu-img create -f qcow2 u1604.qcow2 8G
Formatting 'u1604.qcow2', fmt=qcow2 size=8589934592 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16
qcow2 フォーマットは、使っている部分だけがファイルに記録されます。したがって実際に作成されるイメージは 8GB ではなく、次のように200KB程度のイメージファイルとなります。仮想ディスクに書き込むと徐々に大きくなり、ディスクイメージの作成時に指定したサイズまで大きくなります。
jun@xerus:~/kvm1604$ ls -lt
-rw-r--r-- 1 jun jun 197120 May 3 13:54 u1604.qcow2
ゲストOSとして64ビット Ubuntu 16.04LTS サーバ版のインストール
次のようにイメージファイルと同じフォルダに ubuntu-16.04-server-amd64.iso を置いて仮想マシンを起動してインストールを開始します。スクリーンショットが大きすぎますが、サイズの修正が大変なのでこのまま行きます m(_@_)m。
jun@xerus:~/kvm1604$ ls -lt
-rw-rw-r-- 1 jun jun 686817280 May 3 14:10 ubuntu-16.04-server-amd64.iso
-rw-r--r-- 1 jun jun 197120 May 3 13:54 u1604.qcow2
ゲストマシンの起動
MacOSXのVNCクライアントはパスワードを聞いてくるので、QEMUのVNCをパスワード付きで起動してQEMUモニタからパスワードを設定します。QEMUモニタを使うためにはオプションに「-monitor stdio」を付けて、QEMUモニタの入出力を標準入出力に設定して起動します。 次のように実行すると、QEMUモニタのプロンプト「 (qemu)」が表示されるので、VNC用のパスワードを「change vnc password」コマンドで設定します。
jun@xerus:~/kvm1604$ sudo kvm -hda u1604.qcow2 -cdrom ubuntu-16.04-server-amd64.iso -boot d -m 512 -vnc :0,password -monitor stdio sudo: unable to resolve host xerus QEMU 2.5.0 monitor - type 'help' for more information (qemu) change vnc password Password: ******** (qemu)
Mac OS X 標準のVNCクライアントで接続
Macの Finderのメニューから [移動]->[サーバへ接続...(⌘K)]で起動できます。 ポート番号は kvm の起動時にVNCサーバとして指定したオプションの番号に5900を加えた値を指定します。「 -vnc :0」の場合は5900になります。
先ほど設定したVNC用のパスワードを入力します。
ゲストマシンの起動画面が表示されます。 最初にインストールに使用する言語の指定です。ここではデフォルトのEnglishのままでいきます。
Ubuntuを仮想ハードディスクにインストールするため、「Install Ubuntu Server」を選択します。
使う言語の指定です。サーバとして利用するのでコンソールが日本語を表示できない場合を考えてEnglishにしました。
国の指定です。日本を指定する場合は other / Asia / Japan とたどります。
言語と国の指定が一致していないので、locale を聞いてきます。ここでは「en_US.UTF-8」を選択します。
キーボードのレイアウトの指定です。日本語のキーボードは検出されないので、ここでは <No> を選択します。
Japaneseを選択します。
普通は「Japanese (OADG 109A)」です。
ホストの名前を設定します。適当に名前を決めてください。/etc/hostname と /etc/hosts というテキストファイルの内容を書き換えれば後から変更できます。
ユーザの名前を入力します。
アカウントに使うユーザ名を入力します。
パスワードを入力します。
確認のため、もう一度パスワードを入力します。
ホームディレクトリを暗号化する場合は <Yes> を選択します。普通は <No> で問題ありません。
タイムゾーンの確認です。 「Asia/Tokyo」で合っているので「Yes」を選択します。
Ubuntuをインストールするハードディスクの構成を選択します。仮想マシンの仮想ディスクイメージにインストールする場合は「use entire disk」としてディスク全体を使ってインストールしても問題ありません。
表示されたハードディスクが消去されるという警告です。間違いがなければエンターキーで次に進みます。
フォーマットされるパーティションの情報が表示されます。
インターネットへの接続がプロキシサーバを経由する場合はここで設定します。認証が必要な場合もユーザ名、パスワードをここで設定します。自宅で使う場合は何も設定しなくても大丈夫です。ここで設定しない場合でも、あとから以下の内容のテキストファイルを /etc/apt/apt.conf として置けば同じです。
Acquire::https::Proxy"https://ユーザ名:パスワード@プロキシIPアドレス:ポート番号";
システムのアップデートを自動で行うかどうかを指定します。
サーバをどういった目的で使うかが決まっていれば、ここでインストールするソフトウェアを指定できます。下の例は「データベースとしてPostgreSQLを使って、PHPでプログラムを作成、ApacheでWebサーバを動作させる。SSHで接続する。Windows機とファイルのやり取りもしたい。」といった場合の選択です。「LAMP Server」を選択すると MySQL もインストールされますが、不要ならば後から「apt-get remove mysql-common」を実行します。
インストールの終了です。
インストール後のディスクイメージのサイズを確認します。
jun@xerus:~/kvm1604$ ls -lt
-rw-r--r-- 1 jun jun 2170028032 May 3 15:35 u1604.qcow2
仮想ハードディスクからゲストOSの起動
仮想環境の場合は自動的に再起動されないので、「kvm -hda ディスクイメージ -boot c」として仮想ディスクイメージから起動します。ゲスト用のメモリは512MB(-m 512)、ゲストの出力が vnc の場合のコマンドです。
jun@xerus:~/kvm1604$ sudo kvm -hda u1604.qcow2 -boot c -m 512 -vnc :0,password -monitor stdio sudo: unable to resolve host xerus QEMU 2.5.0 monitor - type 'help' for more information (qemu) change inc password Password: ******** (qemu)
ネットワークカードの設定(-net)を省略するとホストがdhcpサーバ兼ルータとして働き、 ゲストのIPアドレスは以下の例のように 10.0.2.15 といったIPアドレスが自動的に設定されます。
ここでは起動の確認だけにします。各種の設定は後述します。
ゲストの動作確認とパッケージのインストール
ゲストの起動確認
jun@xerus:~/kvm1604$ sudo kvm -hda u1604.qcow2 -boot c -m 512 -nographic
Ubuntu 16.04 LTS u1604 ttyS0
u1604 login: jun
Password:
Last login: Wed May 4 17:01:36 JST 2016 on tty1
Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64)
* Documentation: https://help.ubuntu.com/
17 packages can be updated.
3 updates are security updates.
サーバ版は NetworkManager がインストールされていないことを確認します。
jun@u1604:~$ nmcli status The program 'nmcli' is currently not installed. You can install it by typing: sudo apt install network-manager
プログラミング用パッケージの追加
dhcp が存在するネットワークではこのままインターネットに接続できるので追加するパッケージをインストールしました。 プログラミングの教育用に使えるように設定しています。
jun@u1604:~$ sudo apt-get update
[sudo] password for jun:
Hit:1 https://jp.archive.ubuntu.com/ubuntu/xenial InRelease
Get:2 https://jp.archive.ubuntu.com/ubuntu/xenial-updates InRelease [93.3 kB]
Hit:3 https://jp.archive.ubuntu.com/ubuntu/xenial-backports InRelease
Get:4 https://security.ubuntu.com/ubuntu/xenial-security InRelease [92.2 kB]
Get:5 https://jp.archive.ubuntu.com/ubuntu/xenial-updates/main amd64 Packages [36.9 kB]
Get:6 https://jp.archive.ubuntu.com/ubuntu/xenial-updates/main i386 Packages [36.8 kB]
Get:7 https://jp.archive.ubuntu.com/ubuntu/xenial-updates/main Translation-en [14.0 kB]
Get:8 https://jp.archive.ubuntu.com/ubuntu/xenial-updates/universe amd64 Packages [9,012 B]
Get:9 https://jp.archive.ubuntu.com/ubuntu/xenial-updates/universe i386 Packages [9,012 B]
Get:10 https://security.ubuntu.com/ubuntu/xenial-security/main amd64 Packages [27.7 kB]
Get:11 https://security.ubuntu.com/ubuntu/xenial-security/main i386 Packages [27.7 kB]
Get:12 https://security.ubuntu.com/ubuntu/xenial-security/main Translation-en [9,264 B]
Fetched 356 kB in 2s (148 kB/s)
Reading package lists... Done
jun@u1604:~$ sudo apt-get upgrade Reading package lists... Done Building dependency tree Reading state information... Done Calculating upgrade... Done The following packages will be upgraded: bind9-host distro-info-data dnsutils language-selector-common libbind9-140 libdns-export162 libdns162 libisc-export160 libisc160 libisccc140 libisccfg140 liblwres141 libssl1.0.0 libtasn1-6 lxcfs openssl python3-distupgrade ubuntu-core-launcher ubuntu-release-upgrader-core 19 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Need to get 4,204 kB of archives. After this operation, 3,072 B of additional disk space will be used. Do you want to continue? [Y/n]y 略
gcc, g++, binutils
jun@u1604:~$ sudo apt-get install build-essential Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: binutils cpp cpp-5 dpkg-dev fakeroot g++ g++-5 gcc gcc-5 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan2 libatomic1 libc-dev-bin libc6-dev libcc1-0 libcilkrts5 libdpkg-perl libfakeroot libfile-fcntllock-perl libgcc-5-dev libgomp1 libisl15 libitm1 liblsan0 libmpc3 libmpx0 libquadmath0 libstdc++-5-dev libtsan0 libubsan0 linux-libc-dev make manpages-dev Suggested packages: binutils-doc cpp-doc gcc-5-locales debian-keyring g++-multilib g++-5-multilib gcc-5-doc libstdc++6-5-dbg gcc-multilib autoconf automake libtool flex bison gdb gcc-doc gcc-5-multilib libgcc1-dbg libgomp1-dbg libitm1-dbg libatomic1-dbg libasan2-dbg liblsan0-dbg libtsan0-dbg libubsan0-dbg libcilkrts5-dbg libmpx0-dbg libquadmath0-dbg glibc-doc libstdc++-5-doc make-doc The following NEW packages will be installed: binutils build-essential cpp cpp-5 dpkg-dev fakeroot g++ g++-5 gcc gcc-5 libalgorithm-diff-perl libalgorithm-diff-xs-perl libalgorithm-merge-perl libasan2 libatomic1 libc-dev-bin libc6-dev libcc1-0 libcilkrts5 libdpkg-perl libfakeroot libfile-fcntllock-perl libgcc-5-dev libgomp1 libisl15 libitm1 liblsan0 libmpc3 libmpx0 libquadmath0 libstdc++-5-dev libtsan0 libubsan0 linux-libc-dev make manpages-dev 0 upgraded, 36 newly installed, 0 to remove and 0 not upgraded. Need to get 38.5 MB of archives. After this operation, 143 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
Java8
jun@u1604:~$ sudo apt-get install openjdk-8-jdk Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: ca-certificates-java dbus-x11 fontconfig fontconfig-config fonts-dejavu-core fonts-dejavu-extra gconf-service gconf-service-backend gconf2 gconf2-common hicolor-icon-theme java-common libasound2 libasound2-data libasyncns0 libatk1.0-0 libatk1.0-data libavahi-glib1 libbonobo2-0 libbonobo2-common libcairo2 libcanberra0 libdatrie1 libdrm-amdgpu1 libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libflac8 libfontconfig1 libgconf-2-4 libgdk-pixbuf2.0-0 libgdk-pixbuf2.0-common libgif7 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libgnome-2-0 libgnome2-common libgnomevfs2-0 libgnomevfs2-common libgraphite2-3 libgtk2.0-0 libgtk2.0-bin libgtk2.0-common libharfbuzz0b libice-dev libice6 libjbig0 libjpeg-turbo8 libjpeg8 liblcms2-2 libllvm3.8 libltdl7 libnspr4 libnss3 libnss3-nssdb libogg0 liborbit-2-0 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpciaccess0 libpcsclite1 libpixman-1-0 libpthread-stubs0-dev libpulse0 libsm-dev libsm6 libsndfile1 libthai-data libthai0 libtiff5 libtxc-dxtn-s2tc0 libvorbis0a libvorbisenc2 libvorbisfile3 libx11-dev libx11-doc libx11-xcb1 libxau-dev libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-render0 libxcb-shm0 libxcb-sync1 libxcb1-dev libxcomposite1 libxcursor1 libxdamage1 libxdmcp-dev libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1 libxshmfence1 libxt-dev libxt6 libxtst6 libxxf86vm1 openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless sound-theme-freedesktop x11-common x11proto-core-dev x11proto-input-dev x11proto-kb-dev xorg-sgml-doctools xtrans-dev Suggested packages: gconf-defaults-service default-jre libasound2-plugins alsa-utils libbonobo2-bin libcanberra-gtk0 libcanberra-pulse desktop-base libgnomevfs2-bin libgnomevfs2-extra gamin | fam gnome-mime-data librsvg2-common gvfs libice-doc liblcms2-utils pcscd pulseaudio libsm-doc libxcb-doc libxt-doc openjdk-8-demo openjdk-8-source visualvm icedtea-8-plugin openjdk-8-jre-jamvm libnss-mdns fonts-ipafont-gothic fonts-ipafont-mincho ttf-wqy-microhei | ttf-wqy-zenhei fonts-indic The following NEW packages will be installed: ca-certificates-java dbus-x11 fontconfig fontconfig-config fonts-dejavu-core fonts-dejavu-extra gconf-service gconf-service-backend gconf2 gconf2-common hicolor-icon-theme java-common libasound2 libasound2-data libasyncns0 libatk1.0-0 libatk1.0-data libavahi-glib1 libbonobo2-0 libbonobo2-common libcairo2 libcanberra0 libdatrie1 libdrm-amdgpu1 libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libflac8 libfontconfig1 libgconf-2-4 libgdk-pixbuf2.0-0 libgdk-pixbuf2.0-common libgif7 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libgnome-2-0 libgnome2-common libgnomevfs2-0 libgnomevfs2-common libgraphite2-3 libgtk2.0-0 libgtk2.0-bin libgtk2.0-common libharfbuzz0b libice-dev libice6 libjbig0 libjpeg-turbo8 libjpeg8 liblcms2-2 libllvm3.8 libltdl7 libnspr4 libnss3 libnss3-nssdb libogg0 liborbit-2-0 libpango-1.0-0 libpangocairo-1.0-0 libpangoft2-1.0-0 libpciaccess0 libpcsclite1 libpixman-1-0 libpthread-stubs0-dev libpulse0 libsm-dev libsm6 libsndfile1 libthai-data libthai0 libtiff5 libtxc-dxtn-s2tc0 libvorbis0a libvorbisenc2 libvorbisfile3 libx11-dev libx11-doc libx11-xcb1 libxau-dev libxcb-dri2-0 libxcb-dri3-0 libxcb-glx0 libxcb-present0 libxcb-render0 libxcb-shm0 libxcb-sync1 libxcb1-dev libxcomposite1 libxcursor1 libxdamage1 libxdmcp-dev libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1 libxshmfence1 libxt-dev libxt6 libxtst6 libxxf86vm1 openjdk-8-jdk openjdk-8-jdk-headless openjdk-8-jre openjdk-8-jre-headless sound-theme-freedesktop x11-common x11proto-core-dev x11proto-input-dev x11proto-kb-dev xorg-sgml-doctools xtrans-dev 0 upgraded, 113 newly installed, 0 to remove and 0 not upgraded. Need to get 65.6 MB of archives. After this operation, 357 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
apache2
jun@u1604:~$ sudo apt-get install apache2 Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.1-0 Suggested packages: www-browser apache2-doc apache2-suexec-pristine | apache2-suexec-custom The following NEW packages will be installed: apache2 apache2-bin apache2-data apache2-utils libapr1 libaprutil1 libaprutil1-dbd-sqlite3 libaprutil1-ldap liblua5.1-0 0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded. Need to get 1,532 kB of archives. After this operation, 6,350 kB of additional disk space will be used. Do you want to continue? [Y/n] y 略
ユーザホームディレクトリ/public_html にページを置くことができるように userdir モジュールを有効にします。cgi や SSI の準備もしておきます。
jun@u1604:~$ sudo a2enmod userdir Enabling module userdir. To activate the new configuration, you need to run: service apache2 restart jun@u1604:~$ sudo a2enmod cgid Enabling module cgid. To activate the new configuration, you need to run: service apache2 restart jun@u1604:~$ sudo a2enmod include Considering dependency mime for include: Module mime already enabled Enabling module include. To activate the new configuration, you need to run: service apache2 restart jun@u1604:~$ sudo service apache2 restart
/etc/apache2/mods-available/userdir.conf も編集しておきます。
<IfModule mod_userdir.c> UserDir public_html UserDir disabled root <Directory /home/*/public_html> AllowOverride FileInfo AuthConfig Limit Indexes Options Options MultiViews Indexes SymLinksIfOwnerMatch Includes <Limit GET POST OPTIONS> Require all granted </Limit> <LimitExcept GET POST OPTIONS> Require all denied </LimitExcept> </Directory> </IfModule>
php
jun@u1604:~$ sudo apt-get install php Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: php-common php7.0 php7.0-cli php7.0-common php7.0-fpm php7.0-json php7.0-opcache php7.0-readline Suggested packages: php-pear The following NEW packages will be installed: php php-common php7.0 php7.0-cli php7.0-common php7.0-fpm php7.0-json php7.0-opcache php7.0-readline 0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded. Need to get 3,164 kB of archives. After this operation, 13.7 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
Node.js
jun@u1604:~$ sudo apt-get install nodejs Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libuv1 The following NEW packages will be installed: libuv1 nodejs 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 3,219 kB of archives. After this operation, 13.4 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
Lua
jun@u1604:~$ sudo apt-get install luajit Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libluajit-5.1-common The following NEW packages will be installed: libluajit-5.1-common luajit 0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded. Need to get 241 kB of archives. After this operation, 632 kB of additional disk space will be used. Do you want to continue? [Y/n] y 略
Gauche (scheme)
jun@u1604:~$ sudo apt-get install gauche Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: libgauche-0.9-0 slib Suggested packages: r5rs-doc gauche-doc gauche-zlib gauche-gdbm The following NEW packages will be installed: gauche libgauche-0.9-0 slib 0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded. Need to get 2,325 kB of archives. After this operation, 16.7 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
Ruby
jun@u1604:~$ sudo apt-get install ruby Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: fonts-lato javascript-common libjs-jquery libruby2.3 libyaml-0-2 rake ruby-did-you-mean ruby-minitest ruby-net-telnet ruby-power-assert ruby-test-unit ruby2.3 rubygems-integration unzip zip Suggested packages: ri ruby-dev bundler The following NEW packages will be installed: fonts-lato javascript-common libjs-jquery libruby2.3 libyaml-0-2 rake ruby ruby-did-you-mean ruby-minitest ruby-net-telnet ruby-power-assert ruby-test-unit ruby2.3 rubygems-integration unzip zip 0 upgraded, 16 newly installed, 0 to remove and 0 not upgraded. Need to get 6,413 kB of archives. After this operation, 28.8 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
Emacs (NoX)
jun@u1604:~$ sudo apt-get install emacs-nox Reading package lists... Done Building dependency tree Reading state information... Done The following additional packages will be installed: emacs24-bin-common emacs24-common emacs24-common-non-dfsg emacs24-el emacs24-nox emacsen-common liblockfile-bin liblockfile1 The following NEW packages will be installed: emacs-nox emacs24-bin-common emacs24-common emacs24-common-non-dfsg emacs24-el emacs24-nox emacsen-common liblockfile-bin liblockfile1 0 upgraded, 9 newly installed, 0 to remove and 0 not upgraded. Need to get 35.7 MB of archives. After this operation, 103 MB of additional disk space will be used. Do you want to continue? [Y/n] y 略
samba の設定
Windows からファイルを共有できるようにします。
jun@u1604:~$ sudo vi /etc/samba/smb.conf
各行の先頭の数値は行番号です。入力の必要はありません。
193 [homes] 194 comment = Home Directories 195 browseable = yes 196 197 # By default, the home directories are exported read-only. Change the 198 # next parameter to 'no' if you want to be able to write to them. 199 read only = no 200 201 # File creation mask is set to 0700 for security reasons. If you want to 202 # create files with group=rw permissions, set next parameter to 0775. 203 create mask = 0755 204 205 # Directory creation mask is set to 0700 for security reasons. If you want to 206 # create dirs. with group=rw permissions, set next parameter to 0775. 207 directory mask = 0755
Ubuntu のユーザを追加します。ここではアカウント名を「user_name」とした例です。
jun@u1604:~$ sudo adduser user_name
新しいアカウントに管理者権限を追加するには以下のコマンドを実行して、アカウントを sudo グループに追加します。
jun@u1604:~$ sudo gpasswd -a user_name sudo
samba にアカウントを追加します。
jun@u1604:~$ sudo pdbedit -a user_name new password:xxxxxxxx retype new password:xxxxxxxx
RvtlWiki のインストール
rvtl64 と RvtlWiki をインストールしてWikiを使えるようにします。最初に rvtl64をダウンロードしてインストールします。
jun@u1604:~$ curl -O https://www.mztn.org/rvtl/rvtl-amd64_4.01.tar.gz % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 197k 100 197k 0 0 1640k 0 --:--:-- --:--:-- --:--:-- 1642k jun@u1604:~$ tar zxf rvtl-amd64_4.01.tar.gz jun@u1604:~$ cd rvtl-amd64/ jun@u1604:~/rvtl-amd64$ sudo cp rvtl64 /usr/bin jun@u1604:~/rvtl-amd64$ cd /usr/bin jun@u1604:/usr/bin$ sudo ln -s rvtl64 rvtlw
RvtlWiki は github の最新版を持ってきます。
jun@u1604:~$ git clone https://github.com/jun-mizutani/rvtlwiki.git
Cloning into 'rvtlwiki'...
remote: Counting objects: 54, done.
remote: Total 54 (delta 0), reused 0 (delta 0), pack-reused 54
Unpacking objects: 100% (54/54), done.
Checking connectivity... done.
ここでは /home/jun/public_html/rvtlwiki というフォルダにインストールします。フォルダを作って、コピーして、パーミッションを調整しているだけです。
jun@u1604:~$ mkdir public_html jun@u1604:~$ cd public_html jun@u1604:~/public_html$ mkdir rvtlwiki
git clone で持ってきたファイルのうち、rvtlwiki64 以下のファイルをコピーします。
jun@u1604:~/public_html$ cp -a ../rvtlwiki/rvtlwiki64/* rvtlwiki jun@u1604:~/public_html$ cp -a ../rvtlwiki/rvtlwiki64/.htaccess rvtlwiki
httpd から rvtlwiki/pages へ書き込めるようにパーミッションを変更します。
jun@u1604:~/public_html$ chmod 777 rvtlwiki/pages jun@u1604:~/public_html$ chmod 666 rvtlwiki/pages/*
日本語 man ページ
日本語のマニュアルが利用できるように日本語のロケールをインストールします。
jun@u1604:~$ sudo apt-get install language-pack-ja
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following additional packages will be installed:
language-pack-ja-base
The following NEW packages will be installed:
language-pack-ja language-pack-ja-base
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 1,768 kB of archives.
After this operation, 8,278 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
略
マニュアルページの日本語版をインストールします。
jun@u1604:~$ sudo apt-get install manpages-ja manpages-ja-dev
[sudo] password for jun:
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following NEW packages will be installed:
manpages-ja manpages-ja-dev
0 upgraded, 2 newly installed, 0 to remove and 0 not upgraded.
Need to get 5,840 kB of archives.
After this operation, 7,932 kB of additional disk space will be used.
略
システムのロケールを英語のまま変更しないで、日本語のman ページを表示するには、次のように LANG を一時的に変更して、man コマンドを実行します。
jun@u1604:~$ LANG=ja_JP.UTF-8 man grep
GREP(1) General Commands Manual GREP(1) 名前 grep, egrep, fgrep - パターンにマッチする行を表示する 書式 grep [OPTIONS] PATTERN [FILE...] grep [OPTIONS] [-e PATTERN | -f FILE] [FILE...] 説明 grep は FILE で名前を指定されたファイル (ファイルが指定されていない場合 や、 ファイル名の代わりに 1 個のマイナス記号 (-) が指定されている場合は 標準入力) を検索して、与えられた PATTERN にマッチする部分を含む行を探し ます。 デフォルトでは、 grep はマッチした行を表示します。 さらに、2 つの兄弟プログラム egrep と fgrep が利用可能です。 egrep は grep -E と同じです。 fgrep は grep -F と同じです。 egrep や fgrep を直 接その名前で呼び出すのは、お勧めできません。 それが可能になっているの は、こうしたコマンドの存在を前提とする 昔のアプリケーションが、プログラ ムを修正しないでも 動くようにするためなのです。
ディスクイメージの縮小
qcow2形式のディスクイメージは使っている部分だけを記録する形式ですが、使っているうちに大きくなってきます。イメージ中の未使用の部分を削除するには qemu-img の件肝機能を使います。以下のように qcow2 から qcow2 への変換を行うことで、イメージが再構築されて小さくすることができます。
jun@xerus:~/kvm1604$ qemu-img convert -O qcow2 u1604.qcow2 u1604.qcow2.new jun@xerus:~/kvm1604$ ls -lt -rw-r--r-- 1 jun jun 3354722304 5月 5 18:03 u1604.qcow2 -rw-r--r-- 1 jun jun 3238920192 5月 5 18:07 u1604.qcow2.new
カーネルのシリアル出力設定
カーネルのコンソール出力をシリアルに出力するように変更するため、grub を修正します。/etc/default/grub を変更した後、「update-grub」を実行します。
jun@u91064s:/etc/init$ sudo vi /etc/default/grub # If you change this file, run 'update-grub' afterwards to update # /boot/grub/grub.cfg. GRUB_DEFAULT=0 GRUB_HIDDEN_TIMEOUT=0 GRUB_HIDDEN_TIMEOUT_QUIET=true GRUB_TIMEOUT="10" GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian` GRUB_CMDLINE_LINUX_DEFAULT="quiet splash" GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8" # Uncomment to disable graphical terminal (grub-pc only) #GRUB_TERMINAL=console # The resolution used on graphical terminal # note that you can use only modes which your graphic card supports via VBE # you can see them in real GRUB with the command `vbeinfo' #GRUB_GFXMODE=640x480 # Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux #GRUB_DISABLE_LINUX_UUID=true # Uncomment to disable generation of recovery mode menu entrys #GRUB_DISABLE_LINUX_RECOVERY="true"
Ubuntu 16.04LTS は Systemd を使っているため、inittab がありません。/etc/systemd/system/serial-getty@ttyS0.service を作成して、シリアル回線でログインできるようにします。
/lib/systemd/system/serial-getty@.service を /etc/systemd/system/serial-getty@ttyS0.service としてコピーします。
# cp /lib/systemd/system/serial-getty@.service /etc/systemd/system/serial-getty@ttyS0.service
/etc/systemd/system/serial-getty@ttyS0.service を編集します。
以下のように1行を変更します。
jun@u1604:~$ sudo vi /etc/systemd/system/serial-getty@ttyS0.service # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Serial Getty on %I Documentation=man:agetty(8) man:systemd-getty-generator(8) Documentation=https://0pointer.de/blog/projects/serial-console.html BindsTo=dev-%i.device After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service After=rc-local.service # If additional gettys are spawned during boot then we should make # sure that this is synchronized before getty.target, even though # getty.target didn't actually pull it in. Before=getty.target IgnoreOnIsolate=yes [Service] #ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 %I $TERM ExecStart=-/sbin/agetty -L ttyS0 115200 vt100 Type=idle Restart=always UtmpIdentifier=%I TTYPath=/dev/%I TTYReset=yes TTYVHangup=yes KillMode=process IgnoreSIGPIPE=no SendSIGHUP=yes [Install] WantedBy=getty.target
serial-getty@ttyS0.service のシンボリックリンクを /etc/systemd/system/getty.target.wants/ に作成します。
$ sudo ln -s /etc/systemd/system/serial-getty@ttyS0.service /etc/systemd/system/getty.target.wants/
$ sudo systemctl daemon-reload $ sudo systemctl start serial-getty@ttyS0.service
以上で、kvm を起動した端末上でゲストにログインできるようになります。
複数のゲストマシンの同時起動
ゲストOSを複数起動するためには、ゲストのディスクイメージを別々に用意して起動します。1つのディスクイメージを複数の仮想マシンで共有することはできません。同じ環境のゲストを使う場合でもイメージをコピーする必要があります。今回はサーバとして使用するのでゲストマシンごとにMACアドレス、IPアドレス、ホスト名を別の値を設定する必要があります。
ゲストのネットワークの設定は、ゲストOS側の /etc/rc.local で設定するようにしています。ネットワークカードのデバイス名とMACアドレスを ifconfig から取得して、MACアドレスの最終オクテットをIPアドレスの第4オクテットとして設定し、ホスト名もその値を使うようなスクリプトにしています。 ゲストを起動するためのKVMコマンドのオプションでMACアドレスを指定することで、IPアドレスとホスト名を自動で設定します。
例えば 172.18.21.90 を設定する場合は90の16進数である「5A」をMACアドレスの最終桁に設定します。 ホスト名は「Guest90」のように設定されます。IPアドレスの 172.18.21 の部分は /etc/rc.local の IP24 の行を変更して下さい。ゲイトウェイアドレスは 172.18.21.1 に設定されますが、変更する場合は GW の行を変更して下さい。
まず、/etc/network/interfaces のDHCP の設定を変更します。
jun@u1604:~$ cat /etc/network/interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). source /etc/network/interfaces.d/* # The loopback network interface auto lo iface lo inet loopback # The primary network interface #auto ens3 #iface ens3 inet dhcp dns-nameservers 172.18.21.1
/etc/rc.local のスクリプトを修正します。
jun@u1604:~$ cat /etc/rc.local #!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. IP24=172.18.21 GW=.1 NIC=`ifconfig -a|awk '$1 ~ /^ens/ {print $1,$5}'` HW=`echo $NIC | awk 'BEGIN{FS=":"} {print $6}'` DEV=`echo $NIC | awk '{print $1}'` IP=$IP24.$((0x$HW)) echo $DEV echo "ip address :" $IP echo "broadcast :" $IP24.255 echo "gateway :" $IP24$GW ifconfig $DEV $IP netmask 255.255.255.0 broadcast $IP24.255 route add default gw $IP24$GW hostname Guest$((0x$HW)) echo 127.0.0.1 localhost >/etc/hosts echo $IP $(hostname) >> /etc/hosts exit 0
/etc/rc.local を以上のように書き換えて、「sudo chmod +x /etc/rc.local」を実行して実行可能に設定します。
ゲスト1の起動
ゲストを起動するためのKVMコマンドのオプションはMACアドレス(macaddr=52:54:00:12:34:90)とTAPデバイスの名称の指定(ifname=tap0)を行います。MACアドレスの最終オクテットはIPアドレスの第4オクテットとして設定されます。
sudo kvm -m 512 -boot c -nographic \ -drive file=u1604.qcow2,if=virtio,boot=on \ -net nic,macaddr=52:54:00:12:34:5A,model=virtio \ -net tap,ifname=tap0,script=/etc/qemu-ifup
Ubuntu 16.04 LTS Guest90 ttyS0 Guest90 login: jun Password: Last login: Thu May 5 18:00:18 JST 2016 on ttyS0 Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64) * Documentation: https://help.ubuntu.com/ 0 packages can be updated. 0 updates are security updates. jun@Guest90:~$ ifconfig ens3 Link encap:Ethernet HWaddr 52:54:00:12:34:5a inet addr:172.18.21.90 Bcast:172.18.21.255 Mask:255.255.255.0 inet6 addr: fe80::5054:ff:fe12:345a/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:130 errors:0 dropped:0 overruns:0 frame:0 TX packets:31 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:11803 (11.8 KB) TX bytes:3255 (3.2 KB) 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:549 errors:0 dropped:0 overruns:0 frame:0 TX packets:549 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:58629 (58.6 KB) TX bytes:58629 (58.6 KB) jun@Guest90:~$
ゲスト2の起動
ゲスト2を起動するにはゲスト1の仮想ディスクイメージファイル(u1604.qcow2)をコピーしてファイル名を変更します。ここでは u1604.qcow2 としました。MACアドレス(macaddr=52:54:00:12:34:5B)とTAPデバイスの名称(ifname=tap1)の指定がゲスト1 と別の値を指定しています。
sudo kvm -m 512 -boot c -nographic \ -drive file=u1604B.qcow2,if=virtio \ -net nic,macaddr=52:54:00:12:34:5B,model=virtio \ -net tap,ifname=tap1,script=/etc/qemu-ifup
次のようにコピーしただけの仮想ディスクイメージファイルを使って、ゲスト1と別のIPアドレス、別のホスト名、別のMACアドレスでゲスト2が起動することを確認できます。
Ubuntu 16.04 LTS Guest91 ttyS0 Guest91 login: jun Password: Last login: Thu May 5 18:00:18 JST 2016 on ttyS0 Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64) * Documentation: https://help.ubuntu.com/ 0 packages can be updated. 0 updates are security updates. jun@Guest91:~$ ifconfig ens3 Link encap:Ethernet HWaddr 52:54:00:12:34:5b inet addr:172.18.21.91 Bcast:172.18.21.255 Mask:255.255.255.0 inet6 addr: fe80::5054:ff:fe12:345b/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:81 errors:0 dropped:0 overruns:0 frame:0 TX packets:26 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:8152 (8.1 KB) TX bytes:2705 (2.7 KB) 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:381 errors:0 dropped:0 overruns:0 frame:0 TX packets:381 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1 RX bytes:44341 (44.3 KB) TX bytes:44341 (44.3 KB) jun@Guest91:~$
ホスト側で確認
ゲストを2台起動する前後のホスト側のネットワークの状態です。eth0 以外にも br0、tap0、tap1 が動作していることがわかります。
jun@xerus:~$ ifconfig
br0 Link encap:Ethernet HWaddr 00:1d:60:6d:ae:b4
inet addr:172.18.21.80 Bcast:172.18.21.255 Mask:255.255.255.0
inet6 addr: fe80::21d:60ff:fe6d:aeb4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:21558 errors:0 dropped:0 overruns:0 frame:0
TX packets:16150 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1581526 (1.5 MB) TX bytes:7807608 (7.8 MB)
enp2s0 Link encap:Ethernet HWaddr 00:1d:60:6d:ae:b4
inet6 addr: fe80::21d:60ff:fe6d:aeb4/64 Scope:Link
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:53864 errors:0 dropped:0 overruns:0 frame:0
TX packets:32897 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:48977992 (48.9 MB) TX bytes:8960455 (8.9 MB)
Interrupt:17
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:170 errors:0 dropped:0 overruns:0 frame:0
TX packets:170 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:12438 (12.4 KB) TX bytes:12438 (12.4 KB)
2台起動後。
jun@xerus:~$ ifconfig
br0 Link encap:Ethernet HWaddr 00:1d:60:6d:ae:b4
inet addr:172.18.21.80 Bcast:172.18.21.255 Mask:255.255.255.0
inet6 addr: fe80::21d:60ff:fe6d:aeb4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:24484 errors:0 dropped:0 overruns:0 frame:0
TX packets:16491 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:1885016 (1.8 MB) TX bytes:7953235 (7.9 MB)
enp2s0 Link encap:Ethernet HWaddr 00:1d:60:6d:ae:b4
inet6 addr: fe80::21d:60ff:fe6d:aeb4/64 Scope:Link
UP BROADCAST RUNNING PROMISC MULTICAST MTU:1500 Metric:1
RX packets:56726 errors:0 dropped:0 overruns:0 frame:0
TX packets:33345 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:49312628 (49.3 MB) TX bytes:9118943 (9.1 MB)
Interrupt:17
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:170 errors:0 dropped:0 overruns:0 frame:0
TX packets:170 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1
RX bytes:12438 (12.4 KB) TX bytes:12438 (12.4 KB)
tap0 Link encap:Ethernet HWaddr 36:18:21:a3:96:c4
inet6 addr: fe80::3418:21ff:fea3:96c4/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:53 errors:0 dropped:0 overruns:0 frame:0
TX packets:2517 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:6377 (6.3 KB) TX bytes:306963 (306.9 KB)
tap1 Link encap:Ethernet HWaddr fa:49:a0:ef:67:79
inet6 addr: fe80::f849:a0ff:feef:6779/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:53 errors:0 dropped:0 overruns:0 frame:0
TX packets:2423 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:6377 (6.3 KB) TX bytes:296429 (296.4 KB)
ゲストOSをサーバとして使う
ここまでコンソールで kvm コマンドを実行することでゲストOSを起動し、そのまま端末上でゲストにログインできるようになりました。 ゲストで実行する Linux をサーバとして使用する場合は、常にコンソール出力を表示する必要はなく、ホストのバックグラウンドプロセス(デーモン)として動作すれば十分です。
ここでは仮想マシン上のゲストOSをホストと独立してサーバとして利用します。デスクトップでLinuxを使う場合と異なり、ネットワークさえつながっていればキーボードも画面もほとんど必要ありません。ホストの起動時に自動的にゲストもサーバとして起動し、メンテナンス等で必要なときだけコンソール経由でアクセスできれば理想的です。「ゲストOSはホストのバックグラウンドプロセスとして黙ってサーバとしての動作を続け、必要なときだけコンソールを表示する。」という動作をカーネルのコンソール出力をシリアル端末に切り替えて、コンソールの接続、切断を screen コマンドを利用して実現します。
- ゲストのLinuxのネットワークを設定、
- ゲストの Linux のコンソール出力をシリアル回線に出力、
- シリアルの出力を kvm を起動したホストのコンソールに表示、
- screen コマンドを利用してホストのコンソールを実端末(実画面)と分離、必要に応じてゲストのコンソールを表示。
以上の機能が実現できます。
screen のインストール
screen はホスト側で使うので、ホストマシン上でインストールします。
jun@xerus:~/kvm1604$ sudo apt install screen
sudo: ホスト xerus の名前解決ができません
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
提案パッケージ:
iselect | screenie | byobu
以下のパッケージが新たにインストールされます:
screen
アップグレード: 0 個、新規インストール: 1 個、削除: 0 個、保留: 0 個。
560 kB のアーカイブを取得する必要があります。
この操作後に追加で 972 kB のディスク容量が消費されます。
略
screenから使う
screen コマンドは端末の出力を物理的な端末と切り離したり、再接続したりすることができるコマンドです。 以下のコマンドを入力して1番目のゲストを起動します。「screen -S Guest90」の行は、screen のセッション(ウィンドウの集合)にGuest90という名前を付けるオプションです。ゲストOSで動作させるサーバの名前などをセッション名として指定すると再接続する場合に識別しやすくなります。
jun@xerus:~/kvm1604$ screen -S Guest90 jun@xerus:~/kvm1604$ sudo kvm -m 512 -boot c -nographic \ -drive file=u1604.qcow2,if=virtio \ -net nic,macaddr=52:54:00:12:34:5A,model=virtio \ -net tap,ifname=tap0,script=/etc/qemu-ifup
ゲストのLinuxが起動して、ログインプロンプトが表示されるまで私の環境で 10 秒程度の時間がかかります。kvmコマンドの応答と考えるとちょっと長く感じますが、サーバが10秒で起動すると考えると非常に速いです。
Ubuntu 16.04 LTS Guest90 ttyS0 Guest90 login: jun Password: Last login: Thu May 5 18:16:14 JST 2016 on ttyS0 Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64) * Documentation: https://help.ubuntu.com/ 0 packages can be updated. 0 updates are security updates. jun@Guest90:~$
screenの機能で切断(デタッチ)、接続(アタッチ)ができることを確認するため、Guest90で「top」を起動しておきます。
top - 23:50:46 up 2 min, 1 user, load average: 0.01, 0.14, 0.14 Tasks: 130 total, 1 running, 129 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 0.3 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 500192 total, 211920 free, 53092 used, 235180 buff/cache KiB Swap: 522236 total, 522236 free, 0 used. 396236 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1237 jun 20 0 41788 3748 3160 R 0.3 0.7 0:02.94 top 1 root 20 0 38004 5988 3912 S 0.0 1.2 0:02.17 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 6 root 20 0 0 0 0 S 0.0 0.0 0:00.04 kworker/u2:0 7 root 20 0 0 0 0 S 0.0 0.0 0:00.07 rcu_sched 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 10 root rt 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0 11 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs 12 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns 13 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 perf 14 root 20 0 0 0 0 S 0.0 0.0 0:00.00 khungtaskd 15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 writeback 16 root 25 5 0 0 0 S 0.0 0.0 0:00.00 ksmd 17 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 crypto
ctrl-A d を入力してホストに戻ります。次に以下のコマンドを入力して2番目のゲストを起動します。セッション名は「Guest91」と指定します。イメージファイル、MACアドレス、tap1 の部分が前のGuest90と異なっていることに注意して下さい。
jun@xerus:~/kvm1604$ screen -S Guest91 jun@xerus:~/kvm1604$ sudo kvm -m 512 -boot c -nographic \ -drive file=u1604B.qcow2,if=virtio \ -net nic,macaddr=52:54:00:12:34:5B,model=virtio \ -net tap,ifname=tap1,script=/etc/qemu-ifup
2つ目の仮想マシンも10秒程度で起動します。
Ubuntu 16.04 LTS Guest91 ttyS0 Guest91 login: jun Password: Last login: Thu May 5 18:16:32 JST 2016 on ttyS0 Welcome to Ubuntu 16.04 LTS (GNU/Linux 4.4.0-21-generic x86_64) * Documentation: https://help.ubuntu.com/ 0 packages can be updated. 0 updates are security updates. jun@Guest91:~$
Guest90と同様にGuest91でも「top」を起動しておきます。
top - 23:55:22 up 3 min, 1 user, load average: 0.15, 0.37, 0.19 Tasks: 136 total, 1 running, 135 sleeping, 0 stopped, 0 zombie %Cpu(s): 0.0 us, 1.0 sy, 0.0 ni, 97.0 id, 2.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 500192 total, 212128 free, 53096 used, 234968 buff/cache KiB Swap: 522236 total, 522236 free, 0 used. 396288 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 1249 jun 20 0 41788 3700 3108 R 1.0 0.7 0:00.07 top 1 root 20 0 38144 6132 3920 S 0.0 1.2 0:02.38 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0 4 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 6 root 20 0 0 0 0 S 0.0 0.0 0:00.02 kworker/u2:0 7 root 20 0 0 0 0 S 0.0 0.0 0:00.05 rcu_sched 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root rt 0 0 0 0 S 0.0 0.0 0:00.00 migration/0 10 root rt 0 0 0 0 S 0.0 0.0 0:00.00 watchdog/0 11 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs 12 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns 13 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 perf 14 root 20 0 0 0 0 S 0.0 0.0 0:00.00 khungtaskd 15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 writeback 16 root 25 5 0 0 0 S 0.0 0.0 0:00.00 ksmd
ctrl-A d を入力してGuest91の画面を切り離し、端末をホストのシェルに切り替えます。ネットワーク越しにSSHで端末を使っている場合に「exit」でシェルを終了して切断しても、ゲストは動作したまま残ります。後日「screen -r セッション名」で元の画面に戻ることができます。
必要な作業が終われば、ctrl-A d を入力してホストに戻ります。ここでログオフして端末を閉じても、screen で動作しているセッションの一覧は「screen -ls」で次のように表示されます。
jun@xerus:~$ screen -ls There are screens on: 7302.Guest91 (2016年05月05日 23時51分40秒) (Detached) 7166.Guest90 (2016年05月05日 23時47分43秒) (Detached) 2 Sockets in /var/run/screen/S-jun.
「screen -r Guest90」で最初のゲストの画面を、「screen -r Guest91」で2番目に起動したLinuxのコンソール画面を表示して通常に操作することができます。
+-----------------+ | ゲスト 0 | +---------+ | | +-----------------+ | screen | | コンソール画面 | | ホスト端末画面 | | session +------+ | | | <---| Guest90 | | | | | +---------+ +-----------------+ | | | | +-----------------+ | | +---------+ | ゲスト 1 | | | <---| screen | | | +-----------------+ | session +------+ コンソール画面 | | Guest91 | | | +---------+ | | +-----------------+
このようにゲストのコンソールは screen コマンドのセッションとして残すことができ、必要なときにはいつでも、どこからでもゲストのコンソールを操作することができるようになります。
jun@host:~$ cat start-g0.sh #!/bin/sh kvm -m 512 -boot c -nographic -serial stdio -localtime \ -drive file=u91064s.qcow2,if=virtio,boot=on \ -net nic,macaddr=52:54:00:12:34:00,model=virtio \ -net tap,ifname=tap0,script=/etc/qemu-ifup
jun@host:~$ cat start-g1.sh #!/bin/sh kvm -m 512 -boot c -nographic -serial stdio -localtime \ -drive file=u91064sB.qcow2,if=virtio,boot=on \ -net nic,macaddr=52:54:00:12:34:01,model=virtio \ -net tap,ifname=tap1,script=/etc/qemu-ifup
screenをスクリプト内で使用
Guest90を screen 内で起動してデタッチするスクリプトです。
jun@xerus:~/kvm1604$ cat start90.sh #!/bin/sh screen -S Guest90 -d -m kvm -m 512 -boot c -nographic \ -localtime -drive file=u1604.qcow2,if=virtio \ -net nic,macaddr=52:54:00:12:34:5A,model=virtio \ -net tap,ifname=tap0,script=/etc/qemu-ifup
Guest91を screen 内で起動してデタッチするスクリプトです。
jun@xerus:~/kvm1604$ cat start91.sh #!/bin/sh screen -S Guest91 -d -m kvm -m 512 -boot c -nographic \ -localtime -drive file=u1604B.qcow2,if=virtio \ -net nic,macaddr=52:54:00:12:34:5B,model=virtio \ -net tap,ifname=tap1,script=/etc/qemu-ifup
実行権限を与えておきます。
jun@xerus:~/kvm1604$ chmod +x start90.sh jun@xerus:~/kvm1604$ chmod +x start91.sh
実行結果
ホスト側から上記のスクリプトを実行します。
jun@xerus:~/kvm1604$ sudo ./start90.sh jun@xerus:~/kvm1604$ sudo ./start91.sh
Guest90とGuest91というセッション名でscreenからkvmが起動していることが確認できます。
jun@xerus:~/kvm1604$ screen -ls There are screens on: 7302.Guest91 (05/05/16 23:51:40) (Detached) 7166.Guest90 (05/05/16 23:47:43) (Detached) 2 Sockets in /var/run/screen/S-jun.
接続する場合は 「sudo screen -r Guest90」とします。
jun@xerus:~$ sudo screen -r Guest90
Ubuntu 16.04 LTS Guest90 ttyS0 Guest90 login:
jun@xerus:~$ sudo screen -r Guest90
Ubuntu 16.04 LTS Guest90 ttyS0 Guest90 login: