nkjmkzk.net

powered by Kazuki Nakajima

Archive for 2月, 2011

OCFS2 1.6の新機能

Oracle Linux 5.6とOracle Linux 6.0が相次いでリリースされました。いずれもE-Deliveryからどなたでもフリーでダウンロードできます。
http://edelivery.oracle.com/linux

そしてこれら2つのディストリビューションから、デフォルトのkernelがUEK(Unbreakable Enterprise Kernel)となりました。

*デュアルkernel構成としてインストールされています。つまり、起動時にUEKか、RHEL互換kernelかを選択できます。

以前の記事でもご紹介しましたが、UEKでは性能面のチューニングが施されている他、OCFS2の1.6という最新バージョンが使えるようになっています。OCFS2 1.6は多くの機能追加が行われており、とても魅力的なファイルシステムとなっています。今回はその主要な新機能をご紹介します。

拡張属性

タグのようなものです。ディレクトリ、ファイルに対してNAME:VALUEという形式で情報を付加できるようになっています。

POSIX アクセス制御

通常、ファイルは所有ユーザ:グループ:その他という分類でそれぞれにrwx(読み取り、書き込み、実行)のパーミッションが付与されます。POSIXアクセス制御ではよりきめ細かな制御が可能になります。tanakaはr、yoshidaはrw、yamadaはrwみたいな。

Indexed Directories

Unix/Linuxのディレクトリは配下にファイルを配置することによって階層構造を表現していますが、このディレクトリエントリ(つまりディレクトリ配下のファイル)がめちゃくちゃ多くなったときに、そのリストの取得や更新を高速化させるための仕組みです。

メタデータ・チェックサム

メタデータ(つまりinode等)の整合性をチェックするためのチェックサムを導入。さらに1 bitのエラーであれば修復する機能も追加。

Reflink

OCFS2 1.6の目玉機能。ファイルベースで瞬間複製/スナップショットが取れる。詳しくはこちらの記事を。「Unbreakable Enterprise Kernelを使おう – OCFS2 1.6 Reflink編」

User / Groupベースの容量制限(クォータ)

userまたはgroupベースで容量制限をかけられる機能。

割り当て予約

特に徐々にデータの書き込みが行われたりする大容量ファイルでシーケンシャルなI/Oを可能にして読み書きを高速化するための機構。あらかじめ連続したブロックを予約しておくことで1ファイルが実際にはディスクのあちこちにデータが保存されて長いseek時間要するような挙動を回避する。さらにブロックの予約は「消費」ではないので予約されていても未使用領域であれば必要に応じて譲ることが可能。

JBD2

16TBまでのファイルシステムサイズを実現するジャーナル機構JBD2を採用。

Discontiguous Block Group

OCFS2はinodeをファイルシステム フォーマット時ではなく、動的に作成します。なのでフォーマットが早く、事前に不要かもしれないinodeのための容量をガッツリ消費することがありません。ただし動的に作成する際に固定長の連続領域を必要とするため、空き領域がひどく断片化していると問題になります。この機構はそのようなケースで固定長連続領域の確保要求に対して不連続領域をうまく当てがうためのものです。内部的な機構のための機構なのでユーザにはあまり関係ないかも。

より詳細を求める方はOCFS2 1.6のリリースノートを参照ください。

OCFS2 user’s GUID for release 1.6

with one comment

Written by 中嶋 一樹

2月 16th, 2011 at 4:05 pm

Posted in Uncategorized

Tagged with

glusterfsで仮想化サーバの余っているローカルハードディスクを分散共有ストレージにする

仮想化サーバが数台あると共有ストレージをつないで仮想マシンを全仮想化サーバで共有したくなります。

そうすることによって仮想マシンはリソースが空いていればどの仮想化サーバ上で起動させることができ、起動後もLive Migrationで別の仮想化サーバ上に移動させることさえできます。なのである程度の規模になると仮想化サーバ数台 + 共有ストレージという構成が一般的となります。

こうなってくると仮想化サーバのローカルハードディスクはほとんど使われません。サーバの故障率を下げるためにSANブートにしたりするとさらにローカルハードディスクは全く使わないことになります。それはそれですっきりしいると言えばそうなのですが、せっかくのローカルハードディスクが無駄になっている気もします。もし、共有ストレージを別途用意しなくても、個々の仮想化サーバのローカルハードディスクが元気玉のようにあつまって共有ストレージにようにつかえたら便利でエコですよね。

それを可能にするのがglusterfsです。glusterfsはいろいろな構成がありますが、その内の一構成として複数台のI/Aサーバのローカルハードディスクをつなげて一つの大きなストレージにすることができます。言葉にするとややこしいですが、図にするとこんな感じ。

今まで必要だった外付けの共有ストレージが不要になり、かつて使われることのなかったローカルハードディスクが息を吹き返して共有ストレージの代わりとなる、しかも分散共有ストレージ、というエグい構成となります。なんということでしょう。

それでは早速インストールしてみましょう。

今回はvmserver1, vmserver2, vmserver3という3台の仮想化サーバでglusterfsを構成します。以下では仮想化サーバにはOracle VM Server for x86 2.2.1を使用していますが、Linuxベースの仮想化サーバであれば利用できるものが多いでしょう。RHEL, CentOS, Fedora, Debian, UbuntuはglusterfsのRPMが用意されているのでインストールも楽でしょう。今回はOracle VM Serverで話を進めます。

Oracle VM Server for x86 2.2.1はベースがOracle Linux 5の32bitなのですが、残念ながらglusterfsの32bit版RPMは見当たりません。なのでソースからビルドしていきますが、Oracle VM Serverにはgcc等の開発系ツールはデフォルトではインストールされていません。追加インストールしてもよいのですが、出来る限りdom0はシンプルにしておきたいので別途ビルド専用の環境を作ります。作るといってもOracle VM Server 2.2.1 SDKというVM Templateが提供されているので、それをedeliveryからダウンロードして起動するだけです。下記からたどってOracle VM Template 32 bitからOracle VM Server 2.2.1 SDK Template Media Packをダウンロードしてください。

E-Delivery

SDK VM Templateを起動したらビルドに必要なfuseのパッケージをインストールしておきます。

[root@sdk]# rpm -Uvh http://public-yum.oracle.com/repo/OracleLinux/OL5/6/base/i386/fuse-2.7.4-8.el5.i386.rpm
[root@sdk]# rpm -Uvh http://public-yum.oracle.com/repo/OracleLinux/OL5/6/base/i386/fuse-devel-2.7.4-8.el5.i386.rpm

次にglusterfsの最新ソースをダウンロードしてSDK VMの任意のディレクトリに保存し、下記のようにビルドを進めます。

2011年2月10日現在最新のglusterfsのダウンロード:glusterfs-3.1.2.tar.gz

[root@sdk]# tar xvfz glusterfs-3.1.2.tar.gz
[root@sdk]# cd glusterfs-3.1.2/
[root@sdk]# ./configure --prefix=/srv/glusterfs
[root@sdk]# make
[root@sdk]# make install

これをVM Serverにコピーします。

[root@sdk]# scp -r /srv/glusterfs vmserver1:/srv/
[root@sdk]# scp -r /srv/glusterfs vmserver2:/srv/
[root@sdk]# scp -r /srv/glusterfs vmserver3:/srv/
[root@sdk]# scp /etc/init.d/glusterd vmserver1:/etc/init.d/
[root@sdk]# scp /etc/init.d/glusterd vmserver2:/etc/init.d/
[root@sdk]# scp /etc/init.d/glusterd vmserver3:/etc/init.d/

VM Serverでパスを通しておきます。全てのVM Server上で下記の作業を行います。

[root@vmserver1]# vi /root/.bash_profile
--省略--
PATH=/srv/glusterfs/bin:/srv/glusterfs/sbin:$PATH:$HOME/bin
--省略--

次にVM Serverにもfuseパッケージをインストールしておきます。全てのVM Server上で下記の作業を行います。

[root@vmserver1]# rpm -Uvh http://public-yum.oracle.com/repo/OracleLinux/OL5/6/base/i386/fuse-2.7.4-8.el5.i386.rpm
[root@vmserver1]# rpm -Uvh http://public-yum.oracle.com/repo/OracleLinux/OL5/6/base/i386/fuse-devel-2.7.4-8.el5.i386.rpm

これでインストールは完了です。
次に初期設定を行います。glusterfsのデーモンを起動し、次回以降OS起動時に自動起動するように設定します。全てのVM Server上で下記の作業を行います。

[root@vmserver1]# service glusterd start
[root@vmserver1]# chkconfig glusterd on

また、iptablesを停止しておきます。全てのVM Server上で下記の作業を行います。

[root@vmserver1]# service iptables off

次にglusterfsを構成するVM ServerでTrusted Storage Poolを構成します。これは複数台のVM Serverで信頼関係を構築するという作業です。この操作は任意の一台のVM Serverで行います。

[root@vmserver1]# gluster peer probe vmserver2
Probe successful

[root@vmserver1]# gluster peer probe vmserver3
Probe successful

その後gluster peer statusコマンドを実行するとpeerの登録状況を確認できます。自身以外のpeerが表示されています。

[root@vmserver1]# gluster peer status

Number of Peers: 2

Hostname: vmserver2
Uuid: 07048247-90dc-4148-9ba9-b7e90dfd23e5
State: Peer in Cluster (Connected)

Hostname: vmserver3
Uuid: b3ce7bc6-2a5e-43fa-b6e9-2d2ec74bb530
State: Peer in Cluster (Connected)

次にいよいよglusterfsを構成します。任意の一台のVM Serverからgluster volume createコマンドを発行します。glusterfsでは自身がマウントしているいずれかのファイルシステムの全てまたは一部の領域をglusterfs用に指定し、それをTrusted Storage Poolで合体させて一つのボリュームを構成します。このファイルシステムは新しいものを作成しても構いませんし、既存のファイルシステムのあるディレクトリを指定しても構いません。下記ではそれぞれのVM Serverの既存ファイルシステム上に/var/gluster_brickというディレクトリを作成し、そのディレクトリ以下を新しいボリューム「gluster_vol」を構成するための領域として指定しています。

[root@vmserver1]# mkdir /var/gluster_brick
[root@vmserver2]# mkdir /var/gluster_brick
[root@vmserver3]# mkdir /var/gluster_brick
[root@vmserver1]# gluster volume create gluster_vol vmserver1:/var/gluster_brick vmserver2:/var/gluster_brick vmserver3:/var/gluster_brick
Creation of volume gluster_vol has been successful. Please start the volume to access data.

これで新しいglusterfsのボリュームが作成されました。
このボリュームをgluster volume startコマンドでスタートさせることでクライアントからマウントできるようになります。

[root@vmserver1]# gluster volume start gluster_vol
Starting volume gluster_vol has been successful

ここで焦ってはいけません。というのも、感覚的には/var/gluster_brickが共有ストレージとして使えるようになっているのかな、と思ってしまうのですが、実際はそうではなく、このボリュームを一度NFSマウントしなければなりません。
*CIFS等他のプロトコルもサポートされてますが今回はNFSに話を絞ります。
ごく一般的なglusterfsの構成は、Trusted Storage Pool、つまり分散共有ストレージを構成するglusterfsのノード群(今回でいうとVM Server)と、それをネットワーク越しにマウントするクライアントという2層に分かれます。

しかし今回はglusterfsノードがNFSクライアントも兼ねる構成になります。つまり各VM Serverが自身のglusterfsボリュームをNFSマウントすることになります。

マウントするのは[VM_SERVER]:/var/gluster_brickではなく[VM_SERVER]:gluster_volであることに注意してください。

[root@vmserver1]# mount vmserver1:gluster_vol /mnt
[root@vmserver2]# mount vmserver2:gluster_vol /mnt
[root@vmserver3]# mount vmserver3:gluster_vol /mnt

dfコマンド等でマウントした領域を確認してみてください。3つのVM Serverの容量を合わせた容量が/mntにマウントされているはずです。しかもファイルシステムの中身は3ノードで共有されています。
gluster volume createで作成したボリュームはデフォルトではデータをランダムに各VM Serverに分散させて保存します。ただしオプションがあり、replicaあるいはstripeを指定することでネットワークRAIDを行うことができます。詳しくは下記のglusterfsの管理者ガイドを参照ください。

このようにサーバと分散共有ストレージを同一筐体内におさめる構成は各モージュルの結合度が高くなるのでその設計と運用には工夫が必要となります。例えばVM Serverだけリブートしたい、と思ってもVM Serverをリブートすると必然的にストレージノードもリブートされるので相互の依存関係にオペレーションが足を引っ張られます。

デフォルトの分散モードで構成しているとストレージノードが一台ダウンするとそこそこエラいことになりますが、前述のreplica等をうまくつかってストレージがダウンしても運用を続けられるような構成を組めば今回ご紹介した環境も夢ではありません。

僕も職場のデータベースエンジニアが共有して使っているVM Server 3台に勝手にこっそりglusterfsをインストールして余っていたローカルハードディスクで分散共有ストレージを作ってみましたがなかなかどうして便利です。一度お試しあれ。

with 2 comments

Written by 中嶋 一樹

2月 11th, 2011 at 12:31 pm

Posted in Uncategorized

Tagged with

XenとZFSで仮想マシンの高速Thin-Provisioning、スナップショット/ロールバックを可能にする

一年ほど前にOracle VMとZFSを連携させて高速Thin-Provisioning、スナップショット/ロールバックを実現するovmzfsを作成&紹介しました。

しばらく放置しておりましたがSolaris 11 Expressがリリースされ、COMSTARがグッと身近になったということもありovmzfsをvirtzfsとして書き直しました。virtzfsとはXenの仮想マシンイメージをZFSに格納することによって下図のようなこと実現しその作業を自動化するツールです。





ovmzfsからの主な変更点は、下記の通り

  • Solaris 11 Express COMSTAR対応。
  • Oracle VM APIのサポートを廃止して(オイオイ)、よりシンプルに。VM Managerは不要になり、仮想サーバもOracle VM ServerではなくてもXenかつRedhat系OSなら多分動く。
  • Deduplicationを有効に。そもそもvirtzfsはVMの作成をSnapshot & Cloneで行うので容量効率は非常に良いわけですが、Deduplicationを有効にすること究極的に消費容量を圧縮します。(特に同じようなVM Templateを複数インポートしたときに効果を発揮。

それではインストール方法を。

必要なものは、NASとしてSolaris 11 Expressと、仮想サーバとしてOracle VM Server。Oracle VM Serverは別のXen環境でも代替可能だと思いますが、Oracle VM Serverがフリーでダウンロードできて実際テストもこれでやってるので一番手堅い。まずはこの2台をインストールしてネットワークをつなげてください。

次にSolaris 11 ExpressのrootからOracle VM ServerにパスワードなしでSSHログインできるように公開鍵設定をしておきます。Solaris 11 Express上でssh-keygen -t rsaなどとして/root/.ssh/id_rsa.pubを作成した上で、このファイルの中身をコピーしてOracle VM Server上の/root/.ssh/authorized_keysに張り付けます。

次にSolaris 11 ExpressにCOMSTARのパッケージをインストールしサービスを有効化します。

[root@nas]# pkg install storage-server
[root@nas]# svcadm enable stmf
[root@nas]# svcadm enable -r svc:/network/iscsi/target:default

次にGithubからモジュールをダウンロードしてSolaris 11 Express上に保存します。

ダウンロードはこちらから:https://github.com/nkjm/virtzfs

モジュールをSolaris 11 Express上で展開したらconfig.pyファイルを編集して設定を行います。設定を行うのは基本的に次の3つでOKです。

  • zfs_ip : Solaris 11 ExpressのIPアドレス。複数セグメントがある場合はOracle VM Serverから接続するIPを選択。
  • vmserver_list : Oracle VM ServerのIPアドレス。複数セグメントがある場合はSolaris 11 Expressから接続するIPを選択。また、複数のOracle VM Serverがある場合はコンマ区切りで設定 ex.["172.22.0.1","172.22.0.2"]
  • reposistory_name : 適当に。rpool/REPOSITORY_NAMEというファイルシステムをルートとしてレポジトリが形成されます。

次にvirtzfsを下記のように実行してレポジトリを初期化します。

[root@nas]# ./virtzfs init repository

成功したらインストールは完了です。

引き続きvirtzfsの利用に移ります。

virtzfs show nfsと打ってみてください。これで表示されるディレクトリをOracle VM ServerからNFSマウントするのです。例えばこんな感じ。

[root@nas]# ./virtzfs show nfs
        nas:/rpool/nkjm/nfs

[root@vmserver]# mount nas:/rpool/nkjm/nfs /srv

このディレクトリ中にはイメージファイルは作成されません。単にdomain定義ファイル(仮想マシンの設定ファイル)が作成されます。VM Server側からはこのファイルを指定してxm create [domain定義ファイル]とすることでVMを起動できます。

とはいうもののまだVMは作成されていないのでまずはVM Templateをインポートします。これも必ずしもそうである必要はありませんが、手堅いところでOracle VM Templateをダウンロードしてインポートします。VM TemplateをSolaris 11 Express上にダウロードして解凍し、下記のようにvirtzfsを実行します。

[root@nas]# ./virtzfs import template [解凍したTEMPLATEのディレクトリ]

Templateの名前を聞かれますのでそれを入力するとインポートが始まります。これにはしばらく時間がかかりますのでコーヒーでも淹れて待ちます。また、このインポートのロジックはかなり怪しいのですぐエラーになります(オイ。Templateディレクトリ中のvm.cfgのvifエントリが空だったらエラーになったりするのでその場合はvif = ['type=netfornt,bridge=xenbr0']とかを書いておくと突破できるはずです。まぁどちらにしてもdomain定義ファイルの生成ロジックは相当ヤバいので後から確認してみてください。

インポートが完了したらVMを作成できます。下記のようにvirtzfsを実行して対話的に作成を進めます。

[root@nas]# ./virtzfs create vm

複数VMを一気に作成することもできます。例え10個VMを作ったとしても作成時間はほんの数秒、必要となるディスクスペースは初期状態ではほぼゼロです。このあたりから楽しくなってきます。

VMが作成されたら起動してみます。Oracle VM Server側でxm createコマンドを発行します。

[root@vmserver]# xm create -c /srv/[VM名]/vm_cfg.py

成功すればVMが起動してコンソールが表示されるはずです。

あとはスナップショットとロールバック。スナップショットはVMが起動していても取得できます。また、VM作成時にも初期状態として勝手に一つスナップショットtが取られるようになっています。スナップショットを取るには下記のようにvirtzfsを実行して対話的に対象のVMとスナップショット名を入力します。

[root@nas]# ./virtzfs snapshot vm

取得したスナップショットtは下記のように確認できます。

[root@nas]# ./virtzfs list snapshot

ロールバックする場合はまずVMを停止します。停止した上で下記のようにvirtzfsを実行して対話的に対象のVMとロールバックしたスナップショットを選択します。

[root@nas]# ./virtzfs rollback vm

大体こんな感じです。かなりヘボいロジックも入ってますが、ハマれば中々便利です。

with one comment

Written by 中嶋 一樹

2月 1st, 2011 at 8:53 am

Posted in Uncategorized

Tagged with