« 2007年09月 | メイン | 2007年11月 »

2007年10月19日

Xen CPU割り当て設定がクリアされる?

これはまだ解決できていない問題なのですが。。。

xm vcpu-set コマンドでゲストOS Domain-UへのCPU割り当てを変更できる、というのは前回書きました。
また、ずっとその設定を保持したい場合は、Domain-UのConfigファイルに記述します。

-- /etc/xen/domain1
...
cpus="0" # ←使用する物理CPUの番号
vcpus=1 # ←使用する仮想CPUの数
--

ですがこの設定、僕が構築した環境 CentOS5, kernel-xen-2.6.18-8, xen-3.0.3-25.0.3 では、ゲストOS Domain-Uや管理OS Domain-0を再起動するとクリアされて、デフォルトの設定である「全CPUのうち1つを使用」に戻ってしまうのです。
Domain-0 /etc/xen/auto/ 以下にDomain-UのConfigファイルをコピーし、xendを起動したときに自動的にDomain-Uも起動するよう設定した場合、Domain-0を起動、再起動したときも同様にクリアされてしまいます。
いろいろ試してみたのですが、唯一設定が効くのは、xm create コマンドでDomain-Uを起動したときのみでした。

しょうがないので、xendの起動スクリプト /etc/init.d/xend を修正して、起動時に xm vcpu-set, xm vcpu-pin コマンドを実行するようにしてみたのですが、これでもダメ。

この問題を解決するにはどうすればよいのやら。
今のところ、Domain-0やDomain-Uの再起動時に、xm vcpu-set, xm vcpu-pinコマンドを手動で実行する必要があります。
これでは自動運転はキツいので、引き続き調査中。

2007年10月15日

Xen DomainへのCPU割り当てはどうする?

Xenは管理OS Domain-0や、ゲストOS Domain-Uに物理CPUを動的に割り当てるができます。

・ドメインが使用するCPUの数をセット


# xm vcpu-set <ドメインID>

・ドメインが使用するCPUをセット - ドメインの仮想CPUを物理CPUにマッピング


# xm vcpu-pin <ドメインID> <ドメインの仮想CPU ID> <物理CPU ID>

このようなCPUの割り当てコマンドについては、いろいろなところで紹介されているのですが、実際に稼働させるインターネットサービスにおいて、具体的にどのように割り当てると効率がよいのかについては、実例の情報が少ないように思います。

ユーザマニュアルには下記のように記述されています。
Xen 3.0 User's Manual 「7. CPU Management」
http://tx.downloads.xensource.com/downloads/docs/user/

Having multiple vcpus belonging to the same domain mapped
to the same physical CPU is very likely to lead to poor performance.
It's better to use `vcpus-set' to hot-unplug one of the vcpus
and ensure the others are pinned on different CPUs.

If you are running IO intensive tasks, its typically better
to dedicate either a hyperthread or whole core to running domain 0,
and hence pin other domains so that they can't use CPU 0.
If your workload is mostly compute intensive, you may want
to pin vcpus such that all physical CPU threads are available
for guest domains.

・I/Oが激しい用途ならば、Domain-0に物理CPUを1つ占用させるとよい。
・演算処理が激しい用途ならば、すべてのDomain-Uがすべての物理CPUを使用できるようにするとよい。
といったところですかね。

I/OやゲストOS同士の影響を考慮すると、Domain-0および各Domain-Uにそれぞれ異なる物理CPUを割り当てるのがよさそうです。
僕が実験したPCは物理CPUが2個しかなかったため、比較調査はできなかったのですが、QuadCore搭載サーバなどでベンチマークテストをしてみたいと思っています。

2007年10月12日

Xen Domain-U環境の複製

Xenでは、ゲストOS Domain-Uの仮想ディスクイメージファイルとConfigファイルをコピーして少し編集するだけで、簡単にゲストOSの複製を作ることができます。
同じような環境を複数用意するときはとても便利ですね。

LinuxゲストOSの複製手順をまとめます。

複製元のドメイン名:domain1 - OSはCentOS4.5
複製後のドメイン名:domain2
とします。以下、とくに指定がない限り、管理用OS Domain-0にてrootユーザでコマンドを実行するものとします。

・複製元Domain-Uの設定
複製後の設定変更が最小限になるよう、パッケージのインストール、設定などを行っておきます。
また、複製元、複製後のサーバでIPアドレスが重複しないよう、DHCPで取得するよう設定しておきます。

・複製元Domain-Uを停止


# xm shutdown <ドメイン名>
# xm list

・複製元Domain-Uの仮想ディスクイメージファイルをコピー


# cd /var/lib/xen/images/
# cp -p domain1.img domain2.img

・新しいConfigファイルを作成
domain1 のConfigファイルを基に domain2 を作成します。

# cd /etc/xen/
# cp -p domain1 domain2

viなどのエディタでConfigファイルを開き、ドメイン名、仮想ディスクイメージファイル名、MACアドレス、uuidを変更します。

MACアドレスは、前半の'00:16:3e'は、Xenで共通で使用するものです。
後半の3つを同じセグメントで重複しないよう適当に変更します。
ここでは、末尾よりひとつ前を+1しています。
uuidも、末尾のひとつ前を+1しています。
以下、Configファイルの変更箇所のみ記述します。

-- 変更前
...
name = "domain1"
disk = [ 'tap:aio:/var/lib/xen/images/domain1.img,xvda,w', ]
vif = [ 'mac=00:16:3e:63:94:e3, bridge=xenbr0', ]
uuid = "079e8369-f9ad-0e06-0b95-9b360be8ee0a"
...
--

-- 変更後
...
name = "domain2"
disk = [ 'tap:aio:/var/lib/xen/images/domain2.img,xvda,w', ]
vif = [ 'mac=00:16:3e:63:95:e3, bridge=xenbr0', ]
uuid = "079e8369-f9ad-0e06-0b95-9b360be8ee1a"
...
--

・コピー元のDomain-Uを起動


# xm create domain1

・新しいDomain-Uを起動


# xm create domain2

・ドメインが2つ見えることを確認


# xm list

Name ID Mem(MiB) VCPUs State Time(s)
Domain-0 0 254 1 r----- 3225.5
domain1 1 255 1 -b---- 3160.1
domain2 2 255 1 -b---- 3076.9

・新しいDomain-U環境の設定変更を行う
ホスト名、IPアドレス、MACアドレスを変更します。
Domain-0から複製後のDomain-U domain2にコンソールログインします。

# xm console domain2

ホスト名を変更します。

-- /etc/sysconfig/network
HOSTNAME=domain2
--

IPアドレス、MACアドレスを変更します。

-- /etc/sysconfig/network-scripts/ifcfg-eth0
DEVICE=eth0
BOOTPROTO=none
HWADDR=00:16:3E:63:95:E3 →Xenコンフィグファイルのvifで指定したアドレス
IPADDR=192.168.10.3 →IPアドレスを指定します
NETMASK=255.255.255.0
ONBOOT=yes
TYPE=Ethernet
USERCTL=no
IPV6INIT=no
PEERDNS=yes
GATEWAY=192.168.10.1
--

複製元OS rootユーザのbash履歴ファイルを削除します。

# rm /root/.bash_history

複製元OS SSHサーバのホスト鍵を削除します。


# rm /etc/ssh/ssh_host*

sshdを再起動し、ホスト鍵を再作成します。

# /etc/init.d/sshd restart

いったんコンソールからログアウトして、Domain-Uを再起動します。

# xm reboot domain2

これで、複製後のDomain-Uは、ホスト名やネットワークも問題なく、1つの新しいサーバとして見えるようになります。

・Domain-0が起動する際に、自動的にDomain-Uも起動するよう設定


# ln -s /etc/xen/domain2 /etc/xen/auto/domain2

・必要に応じて、CPUの割り当てを変更


# xm vcpu-pin <ドメインID> <ドメインの仮想CPU ID> <実CPU ID>
# xm vcpu-list

大まかにはこれで完了です。とっても簡単ですね。


(参考)
ゲストOSを複製する方法
http://tomo.ac/goodstream/xen/tips/imgcopy.html

ThinkIT 実践!仮想化技術「Xen」の活用方法
第1回:仮想化、その使い道
http://www.thinkit.co.jp/free/article/0606/4/1/

2007年10月10日

Xen MySQLサーバが起動しない

XenでCentOS4.5のゲストOS Domain-U環境を構築し、MySQLサーバ4.1.20を起動しようとしたところ、下記のメッセージが表示され起動に失敗するという現象がありました。

-- /var/log/mysqld.log
070925 16:50:50 [ERROR] bdb: unable to initialize mutex:
Function not implemented
070925 16:50:50 [ERROR] bdb: process-private:
unable to initialize environment
lock: Function not implemented
--

Xen環境では、/lib/tls(Thread Local Storage)ライブラリが有効になっていると性能が悪くなるため、これを無効にすることが推奨されています。
ですが、MySQLでは、bdb(Berkeley DB)まわりのライブラリがTLSを使用しているようで、mysqldの起動時に必要なライブラリを読み込めずにエラーしていました。

この問題を解決するために、bdbまわりのライブラリを使用しないよう、/etc/my.cnf に下記の1行を追加します。

-- /etc/my.cnf
[mysqld]
...
skip-bdb
--

これで、MySQLサーバが正しく起動するようになりました。
なお、skip-bdb オプションを指定することによる違いが、リファレンスマニュアルに記述されています。
http://dev.mysql.com/doc/refman/4.1/ja/bdb-start.html



MySQL は Berkeley DB ライブラリを初期化しなくなるため、大量のメモリを

節約できます。このオプションを使用しているときは BDB テーブルを

使用できません。BDB テーブルを作成しようとすると、代わりに

MyISAM テーブルが作成されます。


通常はストレージエンジンとして、MyISAMまたはInnoDBを使用するでしょうから、問題ありませんね。
「大量のメモリを節約できます」については、mysqldプロセスの使用メモリが約3MBほど少なくなることを確認しました。
Apacheにおける「不要なmod_xxxを読み込まない」と同じく、Xen環境以外でも、skip-bdbをデフォルトで設定してもよいですね。

2007年10月09日

Xen xm consoleでコンソールログインできない

Xenの環境構築で最初に行き詰まったこと。
管理用OS Domain-0としてCentOS5を使用し、ゲストOS Domain-UとしてCentOS4.5をインストールしてみました。
早速コンソールログインを試してみようと思って、Domain-0でxm consoleコマンドを実行したところ、下記のエラーメッセージが出てログインプロンプトが表示されませんでした。

IRQ8 is not free.
xm console no controller found.

キャラクターベースのコンソールを使用できないのは痛いですね。
調べたところ、これは仮想コンソールの設定不足によるもので、Domain-Uにて下記の設定を行う必要がありました。
(CentOSのみの問題かどうかはわかりませんが)

-- /etc/inittab に追記
co:2345:respawn:/sbin/agetty xvc0 9600 vt100-nav
--

-- /etc/securetty に追記
xvc0
--

この設定を行った後、Domain-Uを再起動すると、無事Domain-0からxm consoleコマンドでコンソールログインできるようになりました。

(参考)
CentOS Tips And Tricks:
http://wiki.centos.org/TipsAndTricks/Xen?highlight=%28Console%20handling%29

2007年10月04日

サーバ仮想化

9月の後半から、少し時間をもらってXenやVMware Serverといった、無償で使用できるサーバ仮想化ソフトの調査をしていました。
Xenの環境構築は大変かな〜と思っていたのですが、CentOS5にはXenのパッケージが含まれているため、比較的簡単にインストールすることができました。
VMware Serverについても、RPMパッケージがリリースされているので、簡単にインストールできました。
インストールやゲストOS環境の設定では、ITProやいろいろな方のサイトを参考にさせてもらったので、ここでも僕がハマった、オフィシャルのUser's Manualには書いていないことについてまとめます。

仮想サーバをうまく使ってサーバリソースを有効活用し、アンタスで、より安価なマネージドホスティング環境を提供できればと思っています。

2007年10月03日

MySQLが落ちる

これまた最近、僕が構築に関わったサービスで、まれにMySQLサーバが落ちる現象が発生していました。バージョンは、RedHat Enterprise Linux 4 Update 4に同梱されていたMySQL Server 4.1.12です。

RPMインストールしたためスタックトレースからの情報が採取できず、調査にも苦労していたのですが、なんとか社内の開発環境でも再現させることができ、情報をたどってひとつのバグにたどり着きました。

MySQL Bugs #11167
http://bugs.mysql.com/bug.php?id=11167

In 4.1 char/varchar fields are limited by 255 characters in length that
makes them longer than 255 bytes in size for such character sets as UTF8.
The functions store_record_in_cache and read_cached_records did not
take into account this Moreover the code did not take into account
that the size of the varchar fields in 5.0 can be up to 65535 bytes.

The fix will appear in 4.1.13 and 5.0.8.

つまり、
「MySQL4.1の仕様では、CHAR型やVARCHAR型は最大で255文字までとなっている。このため、UTF8のようにマルチバイト文字列を扱う場合、255バイトを超えることがある。ところが、MySQLの一部の内部関数では255バイトを超えることを考慮していなかったため、クラッシュすることがあった。ついでに、MySQL5.0ではVARCHAR型は65535バイトまで扱えるようになったのに、それも考慮していなかった。この障害は4.1.13および5.0.8で修正した。」
ということだったのです。

確かにこのサービスではいくつかの表において、VARCHAR(255)で定義した列で255バイトを超えるようなデータが入っていました。

対処として、RHEL4のMySQLの最新バージョン4.1.20-2にバージョンアップすることでこの問題は解決しました。

無事解決してよかったよかった、、、と言いたいところですが、そうではなく、このバージョンアップのために、お客様の一部サービスを一時停止しなければなりませんでした。
バージョンアップ後の検証も含め、けっこうなお時間を割いていただきました。
サービスイン直前のテスト期間中にも何度か発生していたので、その時点でもう少し原因を追っていれば、と悔やまれます。
インフラ構築担当としては、恥ずかしい話です。
やはりサービスイン前には、最新のアップデートをかけておくべきですね。

Apache ProxyTimeoutが効かない?

最近、僕が構築に関わったサービスで、ApacheのProxyTimeout設定が効かない、という問題がありました。

サーバの構成としては、DMZ上にWeb Proxyサーバがあり、そこからmod_rewriteでPrivateネットワーク上の複数台のアプリケーションサーバにHTTPリクエストを分散しています。
この環境で、ProxyTimeoutを900(=15分)と設定しても、5分=300秒で502エラー、Bad Gatewayが返ってきてしまうのです。
いろいろ調べた結果、これは「グローバルのTimeoutディレクティブの値がProxyTimeoutより優先されてしまう」というApache mod_proxyのバグであることがわかりました。

ASF Bugzilla Bug 11540
http://issues.apache.org/bugzilla/show_bug.cgi?id=11540

バージョン2.0.59および2.2.4にて修正されたようですが、サービス稼働中でApacheのバージョンアップがしにくい場合は、Timeoutディレクティブの値を変更して、reloadすると、設定どおりの秒数でタイムアウトするようになります。

-- httpd.conf
#Timeout 300
Timeout 900

<VirtualHost *:80>
...
ProxyTimeout 900
...
</VirtualHost>
--

Apacheぐらいメジャーなソフトでも、パラメータが効かないなんてバグがあるんですね。