2014年2月12日水曜日

ZFS on AWS LINUX (2) ファイルシステムの作成

前回でモジュールの導入が完了したので、今回はファイルシステムを作成します。 今回のエントリの作成に当たっては以下の文書を参考にしています。 https://pthree.org/2012/12/05/zfs-administration-part-ii-raidz/
マネージメントコンソールとコンソールを行ったり来たりするのは面倒なので、 可能な限りコンソールコマンドだけで処理しようと思います。
今回せっかくなので RAID z3 ボリュームを作成してみようと思います。 RAID z3 はトリプルパリティーを持つ非常に頑丈なファイルシステムで、 最低5台の HDD を必要とします。

事前準備

マネジメントコンソールにてIAMユーザーを作成ます。
作成時に出力されるアクセスキーとシークレットキーを取得して、 aws cli に登録します。
自分で .aws/config ファイルを編集してもいいですが、 "aws configure" コマンドが便利です。
[ec2-user@ip-10-160-162-8 ~]$ aws configure
AWS Access Key ID [None]: AKIxxxxxxxxxxxxxxxxx
AWS Secret Access Key [None]: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Default region name [None]: ap-northeast-1
Default output format [None]:
※ IAM ロールを指定してもいいですが、つけ忘れたのでwww

EBSボリュームの作成

"aws ec2 create-volume" コマンドで、EBSボリュームを作成します。 今回は、RAID Z3 ボリュームを作成するので、5つの EBS ボリュームを確保する必要があります。 同じ要領でコマンドを5回繰替えしてください。
コマンド実行時に出力される項目のうち "VolumeId" は控えておいてください。
以下の出力例では、"vol-5b4bb851" となります。
今回指定した "aws ec2 create-volume" コマンドのオプションの意味は以下の通りです。
  • "--availability-zone"
    アタッチするインスタンスと同じ、AZを指定してください。
  • "--size"
    GB 単位で必要なサイズを指定してください。
[ec2-user@ip-10-160-162-8 ~]$ aws ec2 create-volume --availability-zone ap-northeast-1a --size 10
{
"AvailabilityZone": "ap-northeast-1a",
"Attachments": [],
"Tags": [],
"VolumeType": "standard",
"VolumeId": "vol-5b4bb851",
"State": "creating",
"SnapshotId": null,
"CreateTime": "2014-02-06T07:21:27.214Z",
"Size": 10
}
続いて、"aws ec2 describe-volumes" で作成したボリュームのステータスが "available" になっていることを確認してください。
[ec2-user@ip-10-160-162-8 ~]$ aws ec2 describe-volumes
{
"Volumes": [
...............(snip)...............
{
"AvailabilityZone": "ap-northeast-1a",
"Attachments": [],
"VolumeType": "standard",
"VolumeId": "vol-5b4bb851",
"State": "available",★ここ
"SnapshotId": null,
"CreateTime": "2014-02-06T07:21:27.214Z",
"Size": 10
}
...............(snip)...............
]
}

EBSボリュームのアタッチ

インスタンスにアタッチする際にインスタンスid が必要となりますが、 不明な場合(控え忘れたともいう)はインスタンスメタデータを参照することで確認できます。
コマンドラインは以下の通りです。
[ec2-user@ip-10-160-162-8 ~]$ GET http://169.254.169.254/latest/meta-data/instance-id
i-27cc6720 ★
"aws ec2 attach-volume" コマンドを利用して EBS ボリュームをインスタンスにアタッチします。
作成した5つのEBSボリュームに対して実行してください。
今回使用した "aws ec2 attach-volume" コマンドのオプションは以下の通りです。
  • "--instance-id"
    EBSボリュームが アタッチされるインスタンスのIDです。先ほど取得した値を指定してください。
  • "--volume-id"
    アタッチするボリュームのIDです。ボリューム作成時に控えた値を指定してください。
  • "--device"
    アタッチするデバイス名です。AWS EC2 上のEBSでは、sdfからsdpを指定することが推奨されています。
    今回はsdf,sdg,sdh,sdi,sdj の5つのデバイスとして接続しました。
[ec2-user@ip-10-160-162-8 ~]$ aws ec2 attach-volume --instance-id i-27cc6720 --volume-id vol-5b4bb851 --device sdf { "AttachTime": "2014-02-06T07:31:01.035Z", "InstanceId": "i-27cc6720", "VolumeId": "vol-5b4bb851", "State": "attaching", "Device": "sdf" }
EBSボリュームのアタッチに成功すると、以下のようなログがシスログ(/var/log/messages)に出力されます。
Feb 6 07:31:04 ip-10-160-162-8 kernel: [ 1570.630510] blkfront: xvdf: barrier or flush: disabled; persistent grants: disabled; indirect descriptors: disabled;
Feb 6 07:31:04 ip-10-160-162-8 kernel: [ 1570.653521] xvdf: unknown partition table
※デバイス名がxvdf に変わってしまうことに注意してください。

ZFSボリュームの作成

ここまで、EBS作成とアタッチの手順だけですねwww。本命のzfs ボリュームの作成です。
zpool コマンドを利用して、ボリューム(正確にはストレージプール)を作成します。
以下の例では、"zpool create" コマンドで "tank" という名前のストレージプールを raidz3 で作成し、ディスク xvdf,xvdg,xvdh,xvdi,xvdj(sdf,sdg,sdh,sdi,sdj) を登録しています。
[ec2-user@ip-10-160-162-8 ~]$ sudo zpool create tank raidz3 xvd{f..j}
確認は、"zpool status" コマンド実施します。
[ec2-user@ip-10-160-162-8 ~]$ sudo zpool status tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz3-0 ONLINE 0 0 0
xvdf ONLINE 0 0 0
xvdg ONLINE 0 0 0
xvdh ONLINE 0 0 0
xvdi ONLINE 0 0 0
xvdj ONLINE 0 0 0

errors: No known data errors
この状態で、"/tank" に zfs ボリュームがマウントされています。 このほかのzfsの便利機能は、また改めて。

補足

以下のようなエラーがでてコマンドが失敗する場合があります。
[ec2-user@ip-10-160-162-8 ~]$ sudo zpool create tank raidze xvd{f..j}
Failed to load ZFS module stack.
Load the module manually by running 'insmod /zfs.ko' as root.
Failed to load ZFS module stack.
上記のエラーが出力された場合 dkms によるモジュール作成が失敗している場合があります。
モジュール作成が失敗する原因としては、"kernel-devel" および "kernel-headers" パッケージと "kernel" パッケージとの間でバージョンが一致していないことが考えられます。
バージョン不一致の原因は、yum で導入した場合に、"kernel-devel" および "kernel-headers"の 最新版が導入され、"kernel" パッケージがアップデートされていないことに起因します。
確認方法は "rpm" コマンドを例えば以下のように実行して、"kernel-devel" および "kernel-headers"と "kernel" パッケージのバージョンを確認してください。
[ec2-user@ip-10-160-162-8 ~]$ rpm -qa | grep kernel kernel-devel-3.4.76-65.111.amzn1.x86_64 kernel-headers-3.4.76-65.111.amzn1.x86_64 kernel-3.4.73-64.112.amzn1.x86_64
上記実行例では、"kernel" パッケージのバージョン は "3.4.73-64.112"で、"kernel-devel" および "kernel-headers" のパッケージバージョンは "3.4.76-65.111" なので、dkms によるパッケージ作成が失敗します。。 素直に"yum update" して、再起動で対処できます。
なお、dkms を利用している場合は、kernel アップデート後最初の一回目の再起動で、モジュールの再コンパイルが必要となるため起動に通常時よりも多くの時間がかかります。

2014年1月29日水曜日

ZFS on AWS LINUX (1) モジュールの作成と導入

ZFS というファイルシステムがある。Oracle Soralis で利用されているファイルシステムなのだが、気づいたら LINUX で Native Driver が提供されていたのと AWS 上で大きなサイズでファイルシステムを利用したいというお話があったので試してみた。

ZFS については、Oracle の文書でもいいけれど、以下のblog を参照してほしい。
特にファイルシステムについていろいろなうんちくが書かれていて興味深い。

https://blogs.oracle.com/bonwick/en_US/

AWS では通常ブロックデバイス(HDD)を利用したい場合は EBS という仮想デバイスを利用する。
EBSは単体で 1TB までの容量をサポートしているけれど、それよりも大きな容量たとえば 4TB を一つのディスクでほしい場合がある。

その場合 RAID-0 でストライピングするなどの方法があるけれどやはり信頼性という意味では不安が残る。EBS自身は高い信頼性を持っているけれど、とはいえ全く障害が無いわけではないのでより高い信頼性がほしくなる。
EBS の耐久性については以下の記載がある。

Amazon EBS 製品の詳細 - Amazon EBS ボリュームの耐久性
http://aws.amazon.com/jp/ebs/details/
Amazon EBS の最新スナップショット以降に変更されたデータの量が 20 GB 以下であるボリュームでは、年間故障率(AFR)は 0.1%~0.5% であることが期待できます。
それでは、実際に構成してみよう。
  1. AMI から AWS Linux を起動
    今回は検証ということもあり、t1.micro で起動した。特にオプション等は指定しない。
    AMIは"Amazon Linux AMI 2013.09.2 - ami-0d13700c (64-bit)" を使用した。

  2. ツールとカーネルモジュールの導入
    以下のURLにある手順に従って導入した
    Building Generic RPM Packages http://zfsonlinux.org/generic-rpm.html
    必要なパッケージのインストール [ec2-user@ip-10-133-144-5 ~]$ sudo yum groupinstall "Development Tools"
    ...
    [ec2-user@ip-10-133-144-5 ~]$ sudo yum install kernel-devel zlib-devel libuuid-devel libblkid-devel libselinux-devel parted lsscsi wget
    ...

    ZFS ソースのダウンロード。現在(2014年1月29日)最新のパッケージは、0.6.2なので以下のようにダウンロード
    [ec2-user@ip-10-133-144-5 ~]$ wget http://archive.zfsonlinux.org/downloads/zfsonlinux/spl/spl-0.6.2.tar.gz
    ...
    [ec2-user@ip-10-133-144-5 ~]$ wget http://archive.zfsonlinux.org/downloads/zfsonlinux/zfs/zfs-0.6.2.tar.gz
    ...

    ダウンロードしたパッケージの展開
      [ec2-user@ip-10-133-144-5 ~]$ tar zxf spl-0.6.2.tar.gz
    [ec2-user@ip-10-133-144-5 ~]$ tar zxf zfs-0.6.2.tar.gz

    ツールのコンパイル。以下の例で "user" となっている部分は、そういう指示なのでユーザー名とかで置き換えなくていい。 ちょっとエラーが出ていたけれど無視してよさそう。
    [ec2-user@ip-10-133-144-5 ~]$ cd spl-0.6.2
    [ec2-user@ip-10-133-144-5 spl-0.6.2]$ ./configure --with-config=user
    ..............
    [ec2-user@ip-10-133-144-5 spl-0.6.2]$ make rpm-utils rpm-dkms
    ..............

    同じく、モジュールのコンパイル。
    [ec2-user@ip-10-133-144-5 spl-0.6.2]$ cd ../zfs-0.6.2
    ..............
    [ec2-user@ip-10-133-144-5 zfs-0.6.2]$ ./configure --with-config=user
    [ec2-user@ip-10-133-144-5 zfs-0.6.2]$ make rpm-utils rpm-dkms

    出来上がったパッケージの確認
    [ec2-user@ip-10-133-144-5 zfs-0.6.2]$ cd ..
    [ec2-user@ip-10-133-144-5 ~]$ ls -lR spl-0.6.2/*.rpm zfs-0.6.2/*.rpm
    -rw-rw-r-- 1 ec2-user ec2-user  571071 Jan 29 06:02 spl-0.6.2/spl-0.6.2-1.amzn1.src.rpm
    -rw-rw-r-- 1 ec2-user ec2-user   22408 Jan 29 06:02 spl-0.6.2/spl-0.6.2-1.amzn1.x86_64.rpm
    -rw-rw-r-- 1 ec2-user ec2-user   32146 Jan 29 06:02 spl-0.6.2/spl-debuginfo-0.6.2-1.amzn1.x86_64.rpm
    -rw-rw-r-- 1 ec2-user ec2-user  586092 Jan 29 06:02 spl-0.6.2/spl-dkms-0.6.2-1.amzn1.noarch.rpm
    -rw-rw-r-- 1 ec2-user ec2-user  571890 Jan 29 06:02 spl-0.6.2/spl-dkms-0.6.2-1.amzn1.src.rpm
    -rw-rw-r-- 1 ec2-user ec2-user 2150197 Jan 29 06:08 zfs-0.6.2/zfs-0.6.2-1.amzn1.src.rpm
    -rw-rw-r-- 1 ec2-user ec2-user  884058 Jan 29 06:10 zfs-0.6.2/zfs-0.6.2-1.amzn1.x86_64.rpm
    -rw-rw-r-- 1 ec2-user ec2-user 2937091 Jan 29 06:10 zfs-0.6.2/zfs-debuginfo-0.6.2-1.amzn1.x86_64.rpm
    -rw-rw-r-- 1 ec2-user ec2-user  295009 Jan 29 06:10 zfs-0.6.2/zfs-devel-0.6.2-1.amzn1.x86_64.rpm
    -rw-rw-r-- 1 ec2-user ec2-user 2202506 Jan 29 06:10 zfs-0.6.2/zfs-dkms-0.6.2-1.amzn1.noarch.rpm
    -rw-rw-r-- 1 ec2-user ec2-user 2147951 Jan 29 06:10 zfs-0.6.2/zfs-dkms-0.6.2-1.amzn1.src.rpm
    -rw-rw-r-- 1 ec2-user ec2-user    8084 Jan 29 06:10 zfs-0.6.2/zfs-dracut-0.6.2-1.amzn1.x86_64.rpm
    -rw-rw-r-- 1 ec2-user ec2-user   39214 Jan 29 06:10 zfs-0.6.2/zfs-test-0.6.2-1.amzn1.x86_64.rpm

    パッケージのインストール。
    ドキュメントでは debuginfo はいらないと書いてあるけれど、趣味の問題とまだ比較的新しいモジュールなので入れている。
    後で念のためkernel の debuginfo とcrash も入れておいた方がいいだろう。 ただ AWS だと init でダンプとれないから意味がないかも。
    [ec2-user@ip-10-133-144-5 ~]$ sudo yum localinstall \
    >     spl-0.6.2/spl-0.6.2-1.amzn1.x86_64.rpm \
    >     spl-0.6.2/spl-debuginfo-0.6.2-1.amzn1.x86_64.rpm \
    >     spl-0.6.2/spl-dkms-0.6.2-1.amzn1.noarch.rpm \
    >     zfs-0.6.2/zfs-0.6.2-1.amzn1.x86_64.rpm \
    >     zfs-0.6.2/zfs-debuginfo-0.6.2-1.amzn1.x86_64.rpm \
    >     zfs-0.6.2/zfs-devel-0.6.2-1.amzn1.x86_64.rpm \
    >     zfs-0.6.2/zfs-dkms-0.6.2-1.amzn1.noarch.rpm \
    >     zfs-0.6.2/zfs-dracut-0.6.2-1.amzn1.x86_64.rpm \
    >     zfs-0.6.2/zfs-test-0.6.2-1.amzn1.x86_64.rpm

実際のファイルシステムの作成はのちほど改めて。とりあえずツールとモジュールの導入で大きな問題はなさそう。
またパッケージしてインストールする手順になっているので横展開も問題ない感じです。

2014年1月23日木曜日

AWS EC2のインスタンスタイプの選び方

AWS EC2のインスタンスタイプの選び方

AWS EC2のインスタンスタイプをどれを使っていいかわからないという話を聞いたので、個人的な判断基準。
たしかにいろいろなタイプがあってわかりにくいだろうと思うし、歴史的な紆余曲折もあって一見体系的でないように見える。
詳細は以下のリンクを確認してほしいが大体以下のように覚えておけばほぼ間違いないと思う。
http://aws.amazon.com/jp/ec2/instance-types/

インスタンスのファミリー

"M" で始まるのが一般用途。
        ※ 例外は M2 インスタンスでメモリが値段の割にたくさん搭載されている。
"C" で始まるのは値段の割に CPU 性能が良いバージョン。
"I"で始まるのはネットワークやストレージ性能が値段の割に良いバージョン。
他にも特殊用途のファミリーがいろいろあるけれど、それは用途が明確なので特に説明しない。

インスタンスの世代

"M3" の3 ようにアルファベットの後ろについている数字は、大体世代を表している。
なので、数字が大きいものを選んでおけばいい。
おおむね同じインスタンスサイズなら数字が大きい方が値段が安くて、性能がいい。

インスタンスのサイズ

"medium"、"large"など。事前に検証などでわからなければ、small か mediumを選んでおけばいい。実際にアプリケーションを実行してみて、性能が足りなければ再起動一回でより上位のインスタンスに変更できるのでそれほど気にしなくても大丈夫。

CloudWatch などで監視して、運用時に大きくしたり、小さくしたりするがクラウドっぽい使い方。
なかなかめんどくさいけど。

検証する時間もなくて、何とか予算を取らなければいけないとか場合はしょうがないので、大きいインスタンスを選択しておく。

それでも迷うなら、少しお金を払ってプロの方に相談するのも一つの手段。

HVM とPV 

インスタンスタイプとは別に、ちょっと注意した方がいいのが、AMI のタイプ。これは AWS というより、AWS で利用している XEN ハイパーバイザの特性なのだけれど、HVM 、PV という二つのタイプがある。

もともと XEN は、全部仮想化するのではなくてゲストのカーネルを改造して、大体仮想化するという手法で完全仮想化するよりも高速化を実現するというだった。 Paravirtualization (PV:準仮想化)という名前はここからきている。カーネルに手を入れることができない windows などを利用できるように 完全仮想化も提供されていたが、速度的には遅いといわれていた。

しかし、Intel VT-x や AMD-V など、プロセッサが仮想化を支援する機能を搭載したり、デバイスでも SR-IOV  などの仮想化を支援する仕組みを導入するなどして、カーネルを改造しなくてもハードウェア的に仮想化することで十分な性能を達成できるようなってきた。

HVM(hardware virtual machine )と言われているのがこちら。

AWS では当初、LINUX は PV、Windows は HVM というすみ分けだったけれど、比較的新しいインスタンスタイプでは、LINUX でも HVM が利用できる。また、PVHVM ドライバという PV だか、HVMだかよくわからないドライバが導入されたおかげで、場合によってはHVMの方がより早い動作を期待できる場合が出てきた。

たとえば、AWS上で HVM を利用した場合 SR-IOV がネットワークカードで有効になる拡張ネットワーキングを有効にできる。ネットワークのトラフィックが多くて割り込みが多発する場合には有効だろう。

まとめ

とりあえず迷ったら、m3.medium で HVM AMIを選択して、インスタンスストレージを付けて起動しておけばいいのではないだろうか。

2014年1月20日月曜日

オンプレ環境からクラウドストレージ(S3)へバックアップをとる方法のメモ

AWSの標準機能でバックアップ

AWS CLI を使う

http://aws.amazon.com/jp/cli/

簡易的に扱うのであれば、aws cli の "aws s3 sync" コマンドで対応できる。
特に難しい説明は不要だろう。

上記ページにある実行例
$ aws s3 sync myfolder s3://mybucket/myfolder --exclude *.tmp
upload: myfolder/newfile.txt to s3://mybucket/myfolder/newfile.txt
.....

AWS Storage Gateway を使う

http://aws.amazon.com/jp/storagegateway/

これの VTL 機能を使えば、tar,cpio,dump などのLinux標準機能で使えるコマンドでバックアップがとれる。
実はS3単体で利用するよりも割安だが、別途 GATEWAY の料金がかかる。