前回の更新から半年以上たってしまったところで、久しぶりの書き込み。
連休を使って、KVM の構築を行ってみた。

インストール方法の大まかな手順は以下のサイトが詳しい。

Linux Memo
http://www.asahi-net.or.jp/~aa4t-nngk/kvm.html
逆噴射式
http://www.juna.net/diary/2008/05/kvm.html


構築のおおまかな流れは以下
1. HOST OS (今回は CentOS 5.4) をインストールする
2. kvm, qemu-img, bridge-utils をインストールする
(qemu-img は HDD イメージの作成、bridge-utils は仮想ネットワーク作成に使用)
3. ゲスト OS 用の HDD イメージを作成
4. ゲスト OS のインストール、シャットダウン
5. HOST OS で仮想ブリッジを作成、nic をつなぐ
6. Guest OS 用の tap を作成し、5 で作成した仮想ブリッジにつなぐスクリプト作成
7. 6 のスクリプトをキックしてゲスト OS を起動させる


私の場合、手順5 をスクリプトとし、手順6 のスクリプト内でキックするようにした。
つまり、ゲスト OS 起動時の処理の流れは以下のようになる
ゲストOS の起動 -> tap 作成スクリプトをキック -> 仮想ブリッジ作成スクリプトをキック

また、私の PC には nic が2個あるため、仮想ブリッジには eth1 のみつなぎ、
HOST OS をルータにした。

Guest OS インストール時に GUI 画面を使用する必要があるが、
あいにく HOST OS に X-Window を入れなかったため多少てこずった。
しかし、それ以外は qemu-kvm と qemu-img の man を見るだけで問題なかった。
導入自体は非常に簡単で、使いやすいと思う。
ちなみに、こういう時は、vnc を使用するらしい。
余談だが、そのためには HOST OS で vnc のポートを空ける必要がある
ポートは qemu-kvm の引数、
-vnc :d
d で指定した番号 + 5900 を使用する
例えば、-vnc :0 と指定した場合、5900 ポートを空ける
ex) iptables -I INPUT -p tcp --dport 5900 -j ACCEPT


使用してみた感想だが、全ゲスト OS を一元管理している HOST OS があるので、
ゲストの管理が簡便だと感じた。
ここは vmware vsphere と異なるところだ。
(むしろ、Xen に近いかもしれない)

無償で使用できることを考えると、自分の作業 PC に動作確認用として
導入する分には申し分ない。

ただ、私の勉強不足かもしれないが、KVM 固有の冗長化システムが見つからなかった事を思うと、
まだ実運用には耐えないと思う。
(まあ、Heart Beat のようなフリーの冗長化ソフトもあるが。)

また、CentOS 5.4 の標準カーネルでは、仮想マシンと HDD イメージをつなぐ bus に virtio を
使用できなかった。
(今回は、おとなしく ide を用いた)
virtio は KVM のために作成されたモジュールで、使用すると仮想マシンのディスク IO 速度が上がるらしい。

その他、仮想マシンを立ち上げる際の qemu-kvm の引数に -no-acpi を指定すると
仮想マシンをシャットダウンしても qemu-kvm がそれを探知できずに
プロセスが自動終了しない。
HDD イメージのキャッシュを write-back にすると、少し心配だ。

総括すると、
HOST OS が存在するので、管理が楽。
ただ、実運用に必要な物がまだ全て揃っているわけではないので、今後に期待

というところ。
あと、久しぶりに新しい技術に触ったので面白かった。

私の環境における手順書は、続きを参照
(インデントが崩れて見にくい事は仕様です)
~~ Agenda ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Install host OS and virtual machines.The host OS is CentOS 5.4.The physical machine has two nics.We make virtual bridge in host OS, whose network address is 192.168.3.0/24.We add 192.168.3.0 ip addresses to vms and 192.168.3.254/24 to host eth1 while eth0 is dhcp.Next, we make virtual bridge at host OS and add eth1 to the bridge.Finally, we set up the host OS and make it router.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~-- Symbols --------------------------------------------------------------------->>> : comment$ : host os user prompt# : host os root user prompt% : gest os root user prompt--------------------------------------------------------------------------------== Operations ==================================================================>>> Prepare host OS >>> install CentOS 5.4 Base, Editor( vim, emacs ), SELinux off >>> login as root and add user # useradd quattro # passwd quattro # exit >>> login as quattro $ pwd => /home/quattro $ echo $USER => quattro >>> install kvm, qemu-img and bridge-utils $ su # pwd => /home/quattro # echo $USER => root # yum install kvm qemu-img bridge-utils >>> System reboot # /sbin/shutdown -r now >>> login as quattro $ su # pwd => /home/quattro # echo $USER => root >>> confirm kernel module # lsmod |grep kvm => kvm_intel 86248 0 kvm 223264 2 ksm,kvm_intel>>> Install guest OS >>> create guest qcow2 HDD image (qcow2: Qemu growable image format supporting multiple snapshots.) # mkdir -p /var/kvm/test # qemu-img create -f qcow2 /var/kvm/test/test.img 8GB # qemu-img info /var/kvm/test/test.img => image: /var/kvm/test/test.img file format: qcow2 virtual size: 8.0G (8589934592 bytes) disk size: 44K cluster_size: 4096 >>> Insert CentOS 5.4 install disk and install Guest OS # /sbin/iptables -I ACCEPT -p tcp --dport 5900 -j ACCEPT # /usr/libexec/qemu-kvm \ -cdrom /dev/cdrom \ -boot d \ >>> boot from cdrom -drive file=/var/kvm/test/test.img,if=ide,media=disk,cache=writeback \ -m 1G \ >>> Allocate memory -smp 2 \ >>> Allocate 2 cpu cores -cpu qemu64 \ >>> Specify cpu type. \ -cpu ? for list and additional feature selec-tion -daemonize \ >>> Daemonize the Qemu process. -vnc :0 >>> Specify vnc (Remote Desktop). We can connect to new machine through vnc. (We must use GUI to install the OS.) :0 means 'use 5900 + 0 port' >>> Install the OS using vnc. >>> The System is forced to be reboot while install OS. Remember press `F12' to boot from HDD when booting the bios.>>> Initialize guest OS >>> Set up guest OS default IP address % vi /etc/sysconfig/network-scripts/ifcfg-eth0 >>> describe as follows -------------------------------------------------------------------------------- DEVICE=eth0 BOOTPROTO=static ONBOOT=yes IPADDR=192.168.3.1 NETMASK=255.255.255.0 BROADCAST=192.168.3.255 GATEWAY=192.168.3.254 -------------------------------------------------------------------------------- >>> Shutdown guest OS % shutdown -h now>>> Construct vlan >>> make kvm scripts directory # mkdir /etc/kvm >>> make vlan constructing script (We execute this in guest OS start script) 1. bring up eth1 and create virtual bridge br0 2. add eth1 to br0 # vim /etc/ivm/host-ifup >>> Describe as follows -------------------------------------------------------------------------------- #! /bin/bash # kvm initialize network script # Construct virtual bridge br0 and add eth1 to it # br0 IP address is 192.168.3.254/24 # Check if br0 has already up BR0=down i=`/sbin/ifconfig |grep -c "^br0"` if [ $i -ge 1 ]; then BR0=up fi # Check if eth1 has already up ETH1=down i=`/sbin/ifconfig |grep -c "^eth1"` if [ $i -ge 1 ]; then ETH1=up fi # Bring up eth1 as promiscuous mode if eth1 is down. if [ $ETH1 == down ]; then /sbin/ifconfig eth1 0.0.0.0 promisc up if [ $? -ne 0 ]; then echo 'Failed to bring up eth1' exit 1 fi fi # Bring up br0 and add eth1 to br0 if br0 is down if [ $BR0 == down ]; then /usr/sbin/brctl addbr br0 if [ $? -ne 0 ]; then echo 'Failed to bring up br0' exit 1 fi /usr/sbin/brctl addif br0 eth1 if [ $? -ne 0 ]; then echo 'Failed to add eth1 to br0' exit 1 fi /sbin/ifconfig br0 192.168.3.254 netmask 255.255.255.0 if [ $? -ne 0 ]; then echo 'Failed to add ipaddress to br0' exit 1 fi fi -------------------------------------------------------------------------------- >>> make guest OS network script (We specify this script when guest OS start) 1. bring up br0 using /etc/kvm/host-ifup 2. create new tap and add it to br0 # vim /etc/kvm/qemu-ifup >>> Describe as follows -------------------------------------------------------------------------------- #! /bin/bash # $1 is specified at qemu-kvm arguments (ifname=) /etc/kvm/host-ifup /sbin/ifconfig $1 0.0.0.0 up if [ $? -ne 0 ]; then echo "Failed to bring up $1" exit 1 fi /usr/sbin/brctl addif br0 $1 if [ $? -ne 0 ]; then echo "Failed to add $1 to br0" exit 1 fi exit 0 -------------------------------------------------------------------------------->>> start guest OS# /usr/libexec/qemu-kvm \ -drive file=/var/kvm/test/test.img,if=ide,media=disk,cache=writeback,boot=on -m 1G \ -smp 2 \ -cpu qemu64 \ -daemonize \ -vnc :0 \ -net nic,macaddr=52:54:00:12:34:56 \ -net tap,ifname=tap0,script=/etc/kvm/qemu-ifup>>> Configure host OS network and make it router. >>> Allow forwarding # vim /etc/sysctl.conf >>> change as follows -------------------------------------------------------------------------------- net.ipv4.ip_forward = 0 => net.ipv4.ip_forward = 1 -------------------------------------------------------------------------------- # /etc/init.d/network restart >>> Add new rule to iptables >>> initialize iptables # /etc/init.d/iptables restart >>> Open 5900 and 5901 port in order to use vnc # /sbin/iptables -I INPUT -p tcp --dport 5900 -j ACCEPT # /sbin/iptables -I INPUT -p tcp --dport 5901 -j ACCEPT >>> make host os router # /sbin/iptables -I FORWARD -i eth1 -o eth0 -s 192.168.3.0/24 -j ACCEPT # /sbin/iptables -t nat -A POSTROUTING -o eth0 -s 192.168.3.0/24 -j MASQUERADE >>> Drop 192.168.3.0/24 packet # /sbin/iptables -I OUTPUT -o eth0 -d 192.168.3.0/24 -j DROP >>> Save these settings # /etc/init.d/iptables save
昼休み、新入社員がプログラマーの前で「不具合」という言葉を不用意に使っているのを見かけたので、後でこっそりと注意した。

すると、1回は「分かりました」と素直な答えが返ってきたが、しばらくしてから質問がきた。

「ごめんなさい、何が悪かったのか良く分かりませんでした。
話題に上がっていたのは会社で不具合として認めた物だし、SEの方も業務中の会話で使ってますよね。」

確かに、私の所属しているSE部では、OJT で
「不具合は、いつか改修しなければいけない。
独自の判断をせず、会社の方針を確認するように。
ベンダーの人間として、使いかたに気をつけなさい。」
と、教えていた。
(それ以上の事は、教えなかった。)

IT業界で仕事をする者にとって、「不具合」という言葉は禁句ではない。
でも、使い方を間違えると相手の心を逆撫でる言葉である。
この違いは何だろう。

以下、「不具合」という言葉に対する私の考え方。「不具合」という言葉は、ユーザーが不愉快に感じた現象の発生原因の分類 1 つだ。発生原因としては、その他にも ・仕様 ・環境依存 ・使用方法の間違いなど、数多くある。また、不具合の発生原因も、さらに分解できる。(ユーザーが不愉快に感じる現象の、原因の原因になる。)例えば、以下のような物だ。 ・プログラマーの過失 ・仕様バグ ・コミュニケーションミス ・工数不足そして、ユーザーが快適に使用できるよう、今後の方針決定や発生原因の究明の際などには「不具合」という言葉を用いる事もある。このように、前向きな意味で「不具合」という言葉を用いる分には、問題は少ないと考えている。しかし、自分に不都合な事が起こると、ろくな調査もせずに(または、調査に必要な技術力が不足している事を自覚せずに)「不具合」という言葉を使う人がいる。ソフトウェアベンダーで働く者の被害妄想かもしれないが、上記のような人が「不具合」という言葉を用いる時は、相手の意見を聞く前から「今回、私が不愉快に感じた原因はお前のせいだ」と決めつける態度が見え隠れする事がある。また、正当な理由もなく「不具合」と言われると、プログラマーは自分の技術力不足を指摘されたと考えるだろう。「事情も知らないくせに」と考えてもしかたがない。昨今、「フリーソフトの開発者が、ユーザーの態度に辟易してモチベーションを失う」という事例を良く聞く。同様の事はどこでも発生しているのかもしれない。
私は大学や専門学校で情報系の技術を専攻して学んだことは無い。
興味を持って勉強したり、必要に迫られて調べたことはあるが、体系的にまとまった
知識は無かったりする。

今回、「このままでは、いけない」と思い心気一転、「計算機プログラムの構造と解釈」
という本を Amazon で注文した。


この本は Scheme というプログラム言語を用いて解説がされているらしい。
そこで、Amazon から本が届くのを待つ間、scheme の動作環境を整えようと、
以下で MIT Scheme のダウンロードを行おうと思った矢先に事件はおきた。


ダウンロードページには x86系の各種 OS 環境のバイナリと、ソースファイルが
アップされている。
そして、ソースファイルの README を見ると、
「コンパイルには Scheme のバイナリが必要」と書いてある。

つまり、
「Scheme をコンパイルする際は、最初に一応、Scheme が動作する環境を作れ」
ということらしい。

鶏が先か卵が先か分からないが、とりあえず 64bit OS を使っていると
手も足も出ない。
しかし、最後の望みをかけてダウンロードページの "how to build" を読むと
状況が一変した。

以下の手順で行えば、Scheme がなくとも gcc でコンパイルできるらしい。
$ tar xfz mit-scheme-c-20090107.tar.gz
$ cd mit-scheme-c-20090107/src
$ etc/make-liarc.sh
$ su
# make install

README と "how to build" の整合性がとれていない気がすることが
気がかりだが、とりあえず動作した。

ちなみに、コンパイルオプションを設定したい時は、
$ etc/make-liarc.sh --help
を参照すると良い。

参考までに、私は
$ % etc/make-liarc.sh --prefix=/usr/local --libdir=/usr/local/lib --enable-FEATURE
と打った