2014年11月30日日曜日

AWS KMS が使えるのに気付いたので、早速試してみたメモ

re:invent で発表された、AWS Key Management Service が使えるようになっているのに気付いたので、早速使ってみることにしました。
このサービスは管理的には非常に重要でキーを安全に共有したいとか、キーがどれだっけ?とか、緊急の対処が必要なのにキーが見つからないとか、そういう状況に陥らないようにするために、こう言ったサービスが非常に重要だったりします。
サポートされているリージョンは以下の通りです。東京でも使えますね。

http://docs.aws.amazon.com/kms/latest/developerguide/regions.html

Region NameRegionEndpointProtocolSupport Date
US East (Northern Virginia) Regionus-east-1kms.us-east-1.amazonaws.comHTTPS11/12/2014
US West (Northern California) Regionus-west-1kms.us-west-1.amazonaws.comHTTPS11/12/2014
US West (Oregon) Regionus-west-2kms.us-west-2.amazonaws.comHTTPS11/12/2014
EU (Ireland) Regioneu-west-1kms.eu-west-1.amazonaws.comHTTPS11/12/2014
EU (Frankfurt) Regioneu-central-1kms.eu-central-1.amazonaws.comHTTPS11/12/2014
Asia Pacific (Singapore) Regionap-southeast-1kms.ap-southeast-1.amazonaws.comHTTPS11/12/2014
Asia Pacific (Sydney) Regionap-southeast-2kms.ap-southeast-2.amazonaws.comHTTPS11/12/2014
Asia Pacific (Tokyo) Regionap-northeast-1kms.ap-northeast-1.amazonaws.comHTTPS11/12/2014
South America (Sao Paulo) Regionsa-east-1kms.sa-east-1.amazonaws.comHTTPS11/12/2014

対応しているサービスは以下の通りです。

  • Amazon Redshift
  • Amazon Simple Storage Service
  • Amazon Elastic Block Store

データストアとして使うサービスで暗号化がサポートされているサービスは全て使えるようです。個人的な趣味としては、RDSのEBSでつかえるのかなぁというのが気になります。

それでは、早速、使ってみたいと思います。単独のサービスとしては、management console には表示されません。 IAM のメニューの一つとして、あります。
早速 Getting Started Now してみましょう。
なんだかわからないキーがポツンと一つだけあります。クリックしてみると、”Default master key that protects my EBS volumes when no other key is defined” とあるので、EBSを暗号化するときに利用する、デフォルトのキーのようです。EBS暗号化をすでに利用している人はうっかり消さないようにしましょう。実際 management console 上では消せないようにガードされているようです。


よく考えずに、Create Key してみます。


エイリアスを入力しなければいけないようなので、とりあえず適当な名前を入力します。


IAMユーザーの選択を求められたので、汎用に使っている adminitorator 権限(ようするに制限なし)のユーザーを選択しました。


もう一回 IAM ユーザーの選択を求められます。よく読むと、キーの管理者とキーの利用者を別に設定できるようです。これはセキュリティ的によく考えられた設計だと思います。でもここでは同じユーザーを選択しました。よろしくないですね。

こんな感じでキーのポリシーが作成されました。キーの管理者権限と、使用者権限が別に設定されています。
次に進むとこんな感じで、キーが作成されています。初期で作成されたキーは洗濯できなくて、新しく作成されたキーば選択可能になっています。キーの削除も可能なようです。


クリックするとこんな感じの画面になって、キーの管理者と使用者を指定できるようになっています。


キー自体をアップロードしたり、ダウンロードしたりはできないようです。

実際どのようなユースケースが想定されるでしょうか。

例えば、研究開発部門で極秘のプロジェクトが進行していて、同社内でも他部門には知られたくない研究データがあったとします。もちろ他社の産業スパイなどにも注意が必要です。そのデータはEBSに格納されています。KMSを利用して、権限を限定して、かつEBS暗号化を利用することで、同社内でもデータを利用することを制限することが可能です。
人事データや給与データなども該当するかもしれません。

もっと簡単なユースケースでは、例えば18禁ビデオと、それ以外でアクセス可能な権限を分けるとかw

何れにしてもセキュリティ管理的には重要な機能が追加されたと思います。

2014年11月20日木曜日

クラウド運用について気づいた6つのこと

きょう、日本MSP協会の記念すべき第1回の会合に参加させていただき、たくさんの議論のなかで、気付き(というか思いつき)が幾つかあったのでメモしておきます。

運用は Managed それとも Operation

"運用でカバー" という言葉が示す通りとかく運用担当は雑用係になりがちです。そもそも運用とは何か?という問いかけに明確に答えられないのが実情だと思います。手順書をもらって作業するのが運用ということになりがちです。
これはただの operation だと思います。
operation を超えて Managed になるには何が必要なのだろうか? という問いかけに答える必要があります。

サービスカタログの必要性

Managed として認めていただくためには、 Managed Service として何が提供されるのかを明確にする必要があると感じました。そのためには Service Catalogue の充実が必要になると思いました。では Service Catalogue の内容として何が必要なのでしょうか? 幾つか思いつきですが並べてみます。

コスト最適化

MSP という業種は Managed 業務のアウトソーシングだと思います。アウトソーシングである以上、自社でやるよりもコストメリットがあることを訴求しなければいけないと思います。そのためにはサービス内容を貨幣価値で評価する必要があり、管理会計的な手法や、オペレーショナルリサーチ的な手法が必要になるように思います。同一コストであれば、デリバリーされる内容が自社運用するよりもレベルが高いとか、同じサービス内容であればコストが安いことなどをお客様や経営層に訴求する必要があると思います。

IT 統制の重要性

Managed Service の重要な課題となるのは IT 統制、特にセキュリティへのコミットメントではないでしょうか。本当に IT 統制を適用するとシステムの規模によりますが、それだけで莫大なコストがかかります。MSP に任せれば セキュリティを含めて IT 統制、コンプライアンスは万全だと言われるような Service Catalogue の整備が必要だと思います。

運用設計の重要性

DevOps ではないですが、クラウド時代の運用は自動化手法が重要になってくると思います。そのためには、システム設計の段階から運用、コンプライアンスに関して重要なアーキテクチャを提案する必要があると思います。例えば、Immutable infrastructure 化する手法の提案などがあると思います。とりあえず作っちゃったから、あと運用よろしくでは IT 統制のコンプライアンスを取得するのは難しくなると感じました。

職業的ディシプリン(規律)の確立

IT 統制の中で最もリスクが高いのは、某通信教育会社の事例を引き合いに出すまでもなく、Human Factor だと思います。MSP に任せて安心だと思っていただくためには、マックス・ヴェーバーのプロテスタンティズムの倫理と資本主義の精神」ではないですが、やはり倫理的な規範を示す必要があると思います。その規範の表明としてMSPチャーター(憲章)のようなものを制定する必要があるように思います。MSPチャーターに従うことが運用プロフェッショナルとして表明することなるようになったらいいなぁと思いました。

以上、とりとめもなく書いていますが多くの方のご意見を賜りたいと思います。

2014年9月16日火曜日

iproute2 の ss コマンドのバグと、Red Hat Enterprise Linux と CentOS と OSS

「 ssコマンドはバグと地雷の塊なのでnetstatの代わりにならない 」(ここから)というブログのエントリを読んでいて、物事にはいろいろな見方があるのだなぁ。と思ったので感想。

上記ブログエントリでは、「netstat の代わりに ss コマンドが RHEL7.0 で推奨になっているけれど、ss コマンドに "-a" コマンドを付与した場合、UDP のソケットを TCP として報告してしまうバグがあるから使い物にならないよ、みんな注意してね。」という内容。

このバグはRed Hat 社的には 、2014年2月11日に "Bug 1063927 - ss reports udp sockets as tcp" として報告されていて、現在のステータスは "assigned"になっている。 コメントから、現在の7.0では取り込みが間に合わなかったことになっているが、ステータスとしては、"assigned" のままなので、今後のリリースで取り込まれる可能性が十分にある。

コミュニティーには、2014年2月10日にコミットされているので、Red Hat 社としてもコミュニティーをウォッチしていて、可能であればバグフィックスを取り込もうとしている姿勢が見受けられるがいろいろな大人の事情で取り込みまでに時間がかかるのは仕方がない。

というよりは多分、Red Hat 社的には取り込まざるを得ないだろうと思っている。なぜなら、Bug 1063927 は Bug #1039625 -> Bug #1049459 -> Bug #1055607 という三つのバグをブロックしていて、この三つの Bug はいずれも非公開になっている。

オープンなはずの Bugzilla で非公開の Bug があるのは奇異な感じがするが、実際は Red Hat 社の特定顧客から、Customer Portal を通じて報告された Bug は、非公開として Bugzilla に登録される。Red Hat 社は 顧客から依頼された修正は、基本的には取り込まなければいけないので、おそらく 7.1 以降で取り込まれるのだろう。

ただバグも仕様になってしまう、つまりバグ修正をすることによってむしろ非互換が発生すると判断された場合はその限りではないので、難しいところだ。

Cent OS を利用している人は 何も言えないが、お金で解決してしまう Enterprise な世界である。

お金を払って、問題のある製品を提供するのか?という方もいるかもしれないが、Red Hat 社の提供しているのは、QA と 保守なので、QAで対応できなかった問題は保守で対応する。

そもそも Enterprise なシステムは、RHEL 7.0 をいきなり本番適用したりは絶対にない。それがよいかどうかの是非はおいておいて、Enterprise なシステムでは、設計からカットオーバーまで数年近い時間をかけてシステムを構築する。運用期間を含めたら10年以上に及ぶこともあるので RHEL のサポート期間は今や10年以上になっている。(参考:Red Hat Enterprise Linux のライフサイクル

RHEL 7.0 から検証を始めて、自社に必要な修正を Red Hat 社に取り込ませ、実際に運用開始は 7.3 から開始みたいなことを普通に行う。 本当に Enterprise なことをやっている人たちにはこれは単に課題管理であって、Red Hat がダメだとはならない。むしろ修正してもらえるかどうかわからないことの方が大問題なのである。そのために大金を払っている。

そもそも、バグ自体はメインストリームで修正されているので、自分でパッチを当てたバージョンを作って、とりあえず急場をしのぐというアプローチも考えられる。ただ本当に、Enterprise な環境だと、パッチの管理をどうするかとか、そのパッチ自体に問題があった場合の責任はとか、いろいろ問題が生じるので、そのあたりをお金を払って、Red Hat にやってもらっているのである。

普通の感覚だと、Red Hat 社 のサポート料は高額に見えるが、自社で SE を雇って、QAを行い、場合によっては調査を実施して等などの諸費用を考えると、多くの場合 Red Hat 社にサポート料を払ってやってもらった方が安くなる。

一方で Red Hat 社では、世界中から寄せられる無理難題に対して応え続けた結果、今では結構なナレッジが蓄積されている。そう考えると、サポート料は情報に対する対価という意味合いも含まれている。

じゃあこういった情報を無料で使う方法が無いかというと、そうでもない。 Fedora を使うという方法がある。 Fedora は RHEL の先行リリースという側面があるので、Red Hat の Bugzilla に報告すると回答がもらえる場合がある。場合によっては修正が提供される場合もある。

ただし、新機能の積極的な取り込みが行われるので、人柱になってしまうリスクというかコストが発生するが自分で全部テストしたり、パッチを管理したりするよりははるかにましだ。

ところで、この BUG を追いかけていて、いろいろおもしろかったのは、"-a" オプションの取り扱いがいろいろ紆余曲折を経いていることだ。 (Bug 829632Bug 829630Bug 811219 など)

もともと "ss" コマンドの仕様としては、"-a" で tcp しか表示しなかったようだ。(Bug 829630)
これは "-a" の仕様が "Listening" と "non-Listening" を表示するとなっていたのと、ソケットのタイプのデフォルトが、"tcp" になっていたからと説明している。がnetstat との互換性を考慮して修正されている。これが正しいのかどうかはやはり議論が必要だが、少なくとも netstat の出力に慣れた人にはよかったのだろう。

また、ここで新たな問題が発生する。両方表示するようにしたものの、そもそも tcp を表示する前提だったので、"tcp" と "udp" の区別を表示しなかったのだ。(Bug 829632)

これはさすがにまずいので、機能追加されている。そして今回の問題。つまり Bug 829632 の機能追加漏れになる。なかなか一度にすべての機能がそろわないという実例。

まさに Bug 1063927 のコメント 1 にある通り、"The `ss' utility needs a lot of love"  な状態である。net-tools じゃなくて、iproute2 じゃないと、機能不足なことも多々あるので、今後の進展に期待したい。

OSS なので、様々な考え方や実装があっていいと思う。明確な仕様書が無い世界なので、一般的に合意された動作になるのが正しいと思う。 ”一般的に合意された” 動作になるためには公の議論が必要で、そのためにはMLや公開の bugzilla 等で意見を表明していくのが良いのではないだろうか。

そうでないと "RHEL" やそのクローンである "CentOS" の呪縛から逃れることができない。

2014年8月13日水曜日

SELinux モジュールの中身を確認する

Serverfault 経由

How do I view the contents of a SELinux policy package
http://serverfault.com/questions/321301/how-do-i-view-the-contents-of-a-selinux-policy-package


postgreylocal.mod から、postgreylocal.pp を取り出す。

semodule_unpackage postgreylocal.pp postgreylocal.mod

semodule_unpackage はここにある。

postgreylocal.pp から ルールを取り出す。

dismod postgreylocal.pp

dismod はここにある。

本来は、checkpolicy 等のテスト用らしい。

2014年7月30日水曜日

Amazon zocalo の public preview が登録できたので使ってみた。

Amazon Web Service (AWS) から、新しいサービス Amazon Zocalo (ソカロと読むらしい)が登場しました。zocalo は台座の基底部という意味らしいです。現在 Public preview となっており、使用に当たっては事前に登録が必要です。

基本的には、BOXや、DropBox などと同じファイル共有の仕組みです。他のアカウントとは全く関係ない、任意のアカウントを登録して使うことができます。

何となく申し込んでおいたら、OKが来たので実際に使ってみました。

登録完了のメールのリンクをクリックしていつものマネジメントコンソールからログインすると、以下のような画面が表示されます。

特に迷わず "Get Started Now" をクリックします。するとQuick Start と Standard Setup が選べますが、この手のツールは難しいことしたら負けなので、"Quick Start" を選びます。


次にURLと管理者の登録画面になります。特に難しい入力項目もないので、適当にURLとメールアドレス、名前を入力して"complete setup" をクリックします。URLは後で共有するときに利用します。
画面が変わって "Initializing" となります。10分ほど待ちます。
ちょっとまってリロードすると、"Active" になりました。

先ほど登録したメールアドレスにパスワード変更用のURLが届きます。



Get Started をクリックして、パスワードを設定します。
パスワード以外は登録時の情報が入力されています。パスワードの制限は以下の通り。

少し待つとWelcome の画面が表示されて利用可能になります。
とりあえず ×してWelcome 画面を閉じると利用可能になります。 Review 機能等がありお仕事で利用する文書を管理するときには便利そうです。

Administration をクリックして管理画面を表示します。
Invite Users をクリックして共有するユーザーを指定します。ユーザーは一度に複数指定できるようです。
追加したユーザーに先ほどと同じパスワード変更依頼のメールが届くので、パスワードなどを登録してもらいます。以上で準備は完了です。

既にApp Store や Google Play に モバイル用のアプリも登録されているようですが、Apple 用は iPad にしか対応しておらず、私の スマフォ は未対応となってインストールできませんでした。
基本的にタブレットしか対応していないようです。

気になるお値段ですが、月200Gで$5 です。ファイル共有だけならば、S3よりもずっと簡単です。l
今後スマフォ等の対応が広がれば個人的にはファイルサーバを構築する必要はないように思います。AD連携ができれば、もっといいかもしれません。

2014年7月2日水曜日

Amazon Web Service (AWS) EC2 に新しく T2 インスタンスファミリーが加わりました。

Amazon Web Service (AWS)  のコンピュートサービスであるEC2 に T2 インスタンスファミリーが加わりました。これまでの m1.small や t1.micro を置き換えるものです。

正直 t1.micro は無料利用枠が利用できることもあり、よく利用していましたが若干力不足があったのは確かです。ちょっと大きなビルドを通そうとすると、すぐにメモリ不足でビルドが失敗していました。

新しい t2 インスタンスファミリーは以下の3つのインスタンスタイプです。

インスタンスタイプ vCPUs メモリー (GiB)
t2.micro 1 1
t2.small 1 2
t2.medium 2 4

うれしいのは、搭載メモリが増えたことと、CPU クロックの上限が上がったことでしょうか?

東京リージョンでの時間当たりの価格は以下の感じです。
インスタンスタイプ一時間の料金
t2.micro$0.020
t1.micro$0.026
t2.small$0.040
m1.small$0.061
t2.medium$0.080
t2.small と 同じ1 vCPU の m3.medium が $0.101 ですからぐっとお安い感じです。 また m1.small や t1.micro と比較して、お値段がぐっと安くなっています。 t2.micro は 無料利用枠で利用できるようになっています。

t2 インスタンスファミリーの興味深いところは CPU 性能がバーストすることです。 EBS gp2 と同じく CPU クレジットを受け取り、一定以上のCPU利用率でクレジットを消費します。

インスタンスタイプイニシャルクレジット一時間当たりの補充量ベースパフォーマンス最大クレジット残高
t2.micro30610%144
t2.small301220%288
t2.medium602440%576

1 CPU クレジットは、おおよそ1分間 100 % の使用率に相当します。
これまでの t1.micro でのバーストの仕方とずいぶん変わりました。 クレジットの残量は CloudWatch で確認できます。
  • CPUCreditUsage
    期間中に消費されたクレジットの量。5分間隔で更新される。
  • CPUCreditBalance
    クレジットの残高。5分間隔で更新される。
その他の主な制限事項は以下の通りです。。
  • HVM タイプの AMI しか利用できない。
    この制限があるので、現在 VPC NAT インスタンスとして利用できない。
    でもいつの間にか VPC NAT インスタンスで t1.micro が使えるようになっていた。
  • VPC 内でしか起動できない。
  • インスタンスタイプ毎に起動できるのは20インスタンスまで
  • 24時間で起動できるのは100インスタンスまで
  • もちろん spot instance もダメ
利用シーンとしては、それほどアクセスの内WEBサイトや、短時間で終了するバッチジョブのような用途でしょうか。
クラウドウォッチでクレジット残高を監視しながら残高不足になるようであれば、他のインスタンスサイズへの変更を検討することになると思います。

Amazon Elastic Compute Cloud User Guide (API Version 2014-06-15) T2 Instances
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/t2-instances.html

 Amazon EC2 Pricing
http://aws.amazon.com/ec2/pricing/

Amazon Web Service ブログ
【AWS発表】バースト可能な性能を持つ新しい低コストEC2インスタンス
http://aws.typepad.com/aws_japan/2014/07/low-cost-burstable-ec2-instances.html

2014年6月30日月曜日

OSv を AWS EC2 からアップロードしたメモ

先日どこかのもくもく会で取り上げられていましたが、OSvという OS があります。 designed for cloud と銘打っておりクラウド向けに最適化されたOSを目指しています。
OSv is designed from the ground up to execute a single application on top of a hypervisor, resulting in superior performance and effortless management
現代のOSは Linux を含めて、非常に高機能で複雑になっています。
これはオンプレミス上で多様な機器をサポートしたり、さまざまなワークロードに単体で対応する必要があるからです。

一方でクラウドをはじめとする仮想化環境ではハードウェア自体は仮想化され、もともとOSが担っていた多くの機能に関してはクラウドベンダやハイパーバイザが担っているため、ゲストOS側ではミドルウェアで必要とする最低限のインターフェイスだけを残しておけばいいという考え方でOSvは設計されています。

というわけで、実際にためしてみたいと思います。今回はまずOSのイメージを AWS 上に転送するところから始めて見たいと思います。

手順はここを参考にしました。

AMI の起動

AWS Linux では、いくつかのパッケージが不足しているので、Red Hat (Cent OS) もしくは、Fedora の AMI がお勧めだそうです。今回は私は、RHEL-6.5_GA-x86_64-7-Hourly2 (ami-aa8bfe9a)を利用しました。 普通に起動して、SSH 接続します。RHEL も時間課金で利用できるので、気楽に利用できます。

必要なパッケージ、ツールのインストール

パッケージのインストールから、github からのダウンロードまでやってしまいます。
sudo yum install git
sudo yum install ant autoconf automake boost-static gcc-c++ genromfs libvirt libtool flex bison
sudo yum install qemu-system-x86 qemu-img maven maven-shade-plugin python-dpkt tcpdump gdb
git clone https://github.com/cloudius-systems/osv.git
cd osv
git submodule update --init --recursive


AWS CLIのインストール

wget https://s3.amazonaws.com/aws-cli/awscli-bundle.zip
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws


同じく AMI ツールのインストール

wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip
sudo mkdir /usr/local/ec2
sudo unzip ec2-api-tools.zip -d /usr/local/ec2


環境変数の設定 

export AWS_ACCESS_KEY_ID=AKI.........................
export AWS_SECRET_ACCESS_KEY=XXX........................
export EC2_HOME=/usr/local/ec2/ec2-api-tools-1.7.1.0/
export JAVA_HOME="/usr/lib/jvm/jre-1.7.0-openjdk.x86_64/"

EC2_HOME のバージョンは各自確認してください。
AMI ツールは IAM ロール未対応 なので、IAMロールを設定した場合でもアクセスキー、シークレットキーの設定は必要なようです。


実行

ここまでで、環境の準備は終わりです。時間は30分もかからないでしょう。
vim 等のテキストエディタで以下の内容でテキストファイルを作成します。
ファイル名は例えば、"images_0.09.txt" などとします。

v0.09-small
http://downloads.osv.io.s3.amazonaws.com/cloudius/osv/osv-v0.09.qemu.qcow2
small

一行目が作成されるイメージの名前、2行目が元イメージがおいてある URL 3 行目がインスタンスサイズのようですが、内容は未確認です。

cd osv
./scripts/upload-ec2.sh < ~/images_0.09.txt

これでほおっておくと勝手に AMI が出来上がります。時間は結構かかります。
やっていることはおおよそ以下の通りです。
  1. イメージをダウンロード
  2. qcow2 のイメージを raw イメージに変換
  3. イメージを S3 にアップロード
  4. S3 上のイメージを EBS に変換
  5. 新しいインスタンスを作成して stop する
  6. インスタンスの EBS を差し替え
  7. AMI を作成する。
  8. インスタンスのTerminate

この手順を実施すると、N.Virginia (us-east-1) に public な AMI が作成されます。
きっとリリース手順をそのまま書いたのでしょう。紛らわしいので、私のAMIは削除しておきます。

OSv designed for cloud
http://osv.io/

Upload OSv AMI from EC2 instance
https://github.com/cloudius-systems/osv/wiki/Upload-OSv-AMI-from-EC2-instance

2014年6月25日水曜日

Amazon Elastic Block Store (EBS) General Purpose (SSD) volumes (gp2) の バースト特性

先週リリースされた EBS gp2 タイプですが、これまでのスタンダードタイプよりバースト性能が改善されています。 バーストの仕様についてはマニュアルや公式ブログにかなり詳しく記載されていますが、実際に動作確認を行ってみました。

まずはおさらい

この前の記事にも記載しましたがEBS gp2 のバースト仕様を簡単におさらいしておきます。
  • バースト時の最大出力は 3000 IOPS
  • バーストの制御方法は、Token Bucket 方式
  • Token は容量1GBあたり毎秒3個づつ補給される。
  • Token 一個は 1 I/Oに相当
  • Token はEBS 1 個あたり最大 5,400,000 個 保存できる。
  • EBS作成時は、5,400,000 個 Token が補充される。

今回のテスト環境

今回使用した環境は、m3.xlarge を使用しました。OS側の影響を少なくするために少し大きめのインスタンスを利用しています。I/O 処理する分と、dd が動作する分と、sar と ssh が動く分でCPU 4つぐらいあれば大丈夫かな? という程度の考え方です。

EBS は gp2 タイプ 100 GB 確保して、ブートディスクとは別にインスタンスにアタッチしました。

単純に IOPS がでればいいので、以下のコマンドラインで負荷をかけました。

while true ; do dd if=/dev/zero of=/dev/xvdb bs=4k ; done 

以前はIOPSでの課金があったので、ベンチマークを実施するときはお財布を気にしながらでしたが、EBS gp2 タイプでは従量課金がなくなったので安心して負荷をかけることができます。

プレウォームを実施

EBSは特性上、プレウォームを実施すると全体の特性が良くなります。
今回もプレウォームを実施しました。

実施結果

cloudwatch の VolumeWriteOps の結果です。
CloudWatch では、EBS の IO 数を 5 分間隔で取得できます。
5分間のIO数合計が出力されます。

左から一つ目の山がプレウォーム時のものです。プレウォーム時で5分間に 約 600,000 IO 出ています。60s × 5 = 300 s で割ると、 2,000 IOPS ぐらいです。プレウォームしないと、3,000 IOPS は出ません。 

二つ目の山が、プレウォーム後少しおいて再度負荷をかけた時のものです。大体 800,000 IO 出てますので、およそ 2,666 IOPS です。 3,000 ぴったりにはなっていないですが、大体いい値ではないでしょうか。

その後は大体 300 IOPS で安定しています。
バーストしている時間はプレウォームの期間も含めておよそ30分強でした。これも仕様と大きく離れていません。

復活するか

その後2時間ほど負荷を停止して token がたまるのを待って見ました。満タンになるのに5時間ほどかかってしまうので、2時間ほどでどれだけ復活するか見てみました。
最後の山が復活した時のものです。たしかに停止するとバーストは復活します。ただためている時間が短いので、10分程度しか持ちませんでした。

Token はいつ補充されるのか

Token がどのタイミングで補充されるかはマニュアルに明確な記載がありません。ここからは完全な推測です。

上のグラフは sar で取得した await の出力をEXCEL でグラフにしたものです。
OS 側で取得したのでかなりばらつきが大きくなっています。

間隔は1秒間隔で取得しています。最初の塊がプレウォーム時のもので大体 70-80 ms で推移しています。これは実ブロックの割り当て処理のオーバーヘッドでしょう。

その後暫く休憩して次にバースト時のものです。大体 50-80 ms ぐらいです。

最後に値が大きくなっているのはバースト終了後のもので、大体 480 ms ぐらいです。
バースト時とバースト終了時の差分が大体 400ms ぐらいです。

この差分は、Token が補充されるまでの時間だと予測できます。
おそらく1秒間に3個補充されるのではなく、300数十ms に1個補充されているのではないでしょうか。
それで1秒あたり3個補充されていることになるかと思います。

まとめ

EBS gp2 タイプのバースト特性はおおよそ以下の通りだと思います。
  • token がある限り IO を払いだす。
  • 3000 IOPS が、おおよその性能上限
  • バースト時は結構ばらつきが大そう
  • token は、300 数十 ms 毎に補充される 
おまけ
私は個人的には実はIOPSはあんまり気にしていません。

IOが不足しているかどうかの判断は VolumeQueueLength を参考にしています。
もし IO が要求に追い付いていないならば、キューの値が増加して減らなくなります。
もしキューにIOが無いならば、そもそもIO要求が来ていないことになります。

またキューがたまっている状態では IOPS は最高値になっているはずで、それ以上にIOが必要なっていることを示すだけで、余りサイジングの参考になりません。長期的にみて増加傾向ならばその傾向からある程度、サイジングの参考にはなると思います。

2014年6月18日水曜日

Amazon Elastic Block Store (EBS) で SSD がデフォルトになりました。


既にあちこちで取り上げられていますが、Amazon Web Service (AWS) のブロックストレージサービスである、Amazon Elastic Block Store (EBS) で SSD がデフォルトで利用できるようになりました。

マニュアルや料金表、SIMPLE MONTHLY CALCULATORも改版されています。

オンプレ環境と比較して速度的に劣るといわれていたEBSも、これで汚名を挽回できるでしょうか?

もちろんインスタンスのルートボリュームとしても利用できます。
(突然マネジメントコンソール上での、インスタンスウィザードからインスタンスを起動しようとしたら、SSDも選べるけどどうする?みたいなポップアップがでて大騒ぎしてしましました。)

もちろん30GB までの無料使用権も付いています。

EBSのタイプ

これまで "standard" ボリュームと表記されていたEBSタイプは、"Magnetic" と表記されるようになりましたが一覧表示等では、これまで通り "standard" と表示されるようです。

このアップデートでEBSのボリュームタイプは以下の3種類になります。
ボリュームタイプAPIと CLIのボリューム名
General Purpose (SSD)gp2
Provisioned IOPS (SSD)io1
Magneticstandard

さらに従来の standard ボリュームではわずかですが、IO量に応じた従量課金がありましたが、今回から廃止されました。プロビジョンしたディスク容量だけの課金となります。

EBSの性能

性能に関してはこれまでの standard ボリュームから大きく改善されています。最大 3000 IOPS のバースト性能を持ちます。これまでは Provisioned IOPS (PIOPS) を利用しない場合バーストでも数百 IOPS でしたから10倍以上の改善となります。バーストなので利用できるIOPSに制限がありますが、最低でもおよそ30分程度は継続して利用できます。

もっとも今時のSSD製品では数万IOPSを掲げる製品も出てきているので、今後の改善を期待したいところです。

IOPSの帯域制御は IO Credits という非常にユニークな方法を採用しています。

利用可能なIOPSは1GB あたり 3 IOPS が毎秒追加されます。例えば300GBのEBSを用意したとすると、毎秒 900 IOPS が追加されます。IOPSは一秒間にIOした回数なので、最低でも 900 IOPS は利用できるわけです。

一方利用しなかったIOPSは、最大 5,400,000 IOPS分まで蓄積できます。蓄積されたIOPSは最大3000IOPSまで一度に消費できます。

300 GBの EBS ならば、900 IOPS は最低利用できるので、3000 - 900 = 2100 IOPS が消費されるます。5,400,000 ÷ 2,100 = 2571.4... なので、およそ42分ぐらいは、バーストを継続できます。もちろん最大 1 TB = 1000 GB を確保すると、毎秒 3000 IOPSをずっと利用できるわけです。

このバースト性能が向上しているのは LINUX で ext4 のようなファイルシステムを利用している場合は非常に有利です。

ext4 は、基本的にはIOPSを可能な限り押さえるように動作します。そのためメモリ上にたくさんバッファしておいてあるときにまとめて書き出すようになっています。

メモリが不足してバッファを解放するような処理を実施したときに大量のIOPSが一時的にそれも間欠的に発生する場合があります。

このときプロセスはメモリ獲得待ちになりIOが完了するまで待たされます。

これはプロセスが直接メモリ獲得要求を実施した場合だけでなくシステムコールの延長線上で一時的なメモリ確保が発生した場合でもメモリ獲得待ちになり処理遅延につながります。最悪 OOM Killer の餌食になってしまいます。

そのような場合に一時的にでも多くのIOPSが使えると非常にシステム上は有利になります。

コスト

コスト的には、東京リージョンで 1GB あたり 1ヵ月 $0.12です。
100GB利用して月1000円ぐらいです。

120GBのSSDが8000円台で入手できることを考えると少し高い気がしますが、自分で設置したり、故障交換したりデータセンターに置いたりのコストを考慮すると、まぁ妥当な値段かと思います。

ただ注意しなければいけないのは PIOPS (io1) との使い分けです。

例えば、io1 で100GB で 1000 PIOPS プロビジョニングすると

容量  $0.142 × 100GB      = $14.2  
PIOPS $0.074 × 1000 PIOPS = $74 
合計                         $88.2 
(7月からの新料金で計算)

になります。一方で GP2 で 400 GB 相当確保した場合は容量課金だけなので

$0.12 × 400GB =$48 

です。これで 400GB × 3 IOPS/GB なので、1200 IOPS 確保できて、
容量も 4 倍なので非常にお得感があります。

もっとも PIOPSのようにIOPSを保証するとは言っていないのでその点は考慮する必要がありますが、3000 IOPS を超えるような IO 帯域が常時必要なユースケースは限られるので、名前の通り通常は GP2 を選択して問題ないのではないでしょうか。

また standard ボリュームからみると、値上がりしていますが 10 倍程度の性能差と 100 GB あたり $4 程度の差分なのでよほどコストにシビアでない限り GP2 を選択することになるとおもいます。

もしコスト重視ならば EBS ではなく S3 や Glacier の利用もできるので、standard ボリュームが選択される機会は減っていくのではないでしょうか。

また IOPS を重視するならば、いっそデータをファイルに置かずに、Dynamo DB に格納してしまうという方法もあります。

小さなデータを大量に読み書きする場合は、PIOPS を利用するよりも安くなるユースケースもあるとおもいます。何よりもストレージのサイズを気にしなくてよくなります。

Introducing the Amazon EBS General Purpose (SSD) volume type

【AWS発表】新しいSSDベースのElastic Block Storage

【超速報】Amazon EBSに「SSD」が追加されてるぞ!

Amazon Elastic Block Store (Amazon EBS) (マニュアル)

Amazon EBS Volume Types

Amazon EBS の価格

SIMPLE MONTHLY CALCULATOR

Intel SSD 320 Series (600GB, 2.5in SATA 3Gb/s, 25nm, MLC)

2014年5月30日金曜日

EBS で暗号化がサポートされたのでベンチマークしてみた。

Amazon Web Service (AWS) のブロックストレージサービスEBSで暗号化がサポートされました。
使い方はとても簡単 EBS を作成するときに Encryption チェックボックスにチェックを入れるだけ。


一覧表示でもEncrypt の項目が追加されています。


残念ながら、ルートボリュームでは利用できないようです。


気になるのは暗号化による性能劣化です。マニュアルにも以下の記載があります。

 you can expect the same provisioned IOPS performance on encrypted volumes as you would with unencrypted volumes with a minimal effect on latency.
暗号化ボリュームでも最小限のレイテンシで暗号化していないボリュームと同じプロビジョンドIOPS性能を期待できる。
実際に iozone で測定してみました。使用したインスタンスサイズは、m3.midium です。
まずは暗号化なしの場合。


こんな感じです。大きくへこんだところがあるのは多分の測定時に何か撹乱要因があったのでしょう。
次は暗号化ありの場合



ほとんど違いが分かりません。ちなみにこれは書き込みの場合をグラフ化したものです。
読み込みはほとんどIOPSが出ず、メモリに収まった感じだったので、省略します。

ファイルシステムを利用した場合は、ワークロードによっても影響度が変わってくると思いますが、暗号化のオーバーヘッドはほとんど無視できるようです。


2014年5月20日火曜日

Amazon Web Service (AWS) で一つの EC2 インスタンスにいくつ EBS がつけられるか試してみた。

EC2インスタンスに何個EBSがつけられるの?

Amazon Web Service (AWS) で 一つのEC2インスタンスに何個 EBS がくっつけられるのかマニュアルを探してみたけれど、以下の記載しかなくどうもはっきりしたことが分からないので、実際にためしてみた。

やってみる

Management Console から インスタンスウィザードを起動して、"Step 4: Add Storage"のところで、"Add New Volume" を連打した。"/dev/sdb" からはじまり、"/dev/sdz" を通り過ぎて "/dev/xvdz" が表示されたあたりで、このあたりで許してあげようと思い "Launch Instance"。

結果

一見インスタンス自体は問題なく起動しようとしているように見える。がいつまでたってもSSHログインできない。get system log をみると以下のように、Bug を踏んでいた。
4394230.182195] kernel BUG at fs/sysfs/group.c:65!
[4394230.182198] invalid opcode: 0000 [#1] SMP
[4394230.182203] Modules linked in:
[4394230.182207] CPU: 0 PID: 19 Comm: xenwatch Tainted: G        W    3.10.35-43.137.amzn1.x86_64 #1
[4394230.182215] task: ffff88002492c710 ti: ffff880024936000 task.ti: ffff880024936000
[4394230.182219] RIP: e030:[<ffffffff811eb772>]  [<ffffffff811eb772>] internal_create_group+0x202/0x230
[4394230.182228] RSP: e02b:ffff880024937c50  EFLAGS: 00010246
[4394230.182232] RAX: 0000000000000400 RBX: ffff880003544000 RCX: 0000000000000000
[4394230.182236] RDX: ffffffff8184dfc0 RSI: 0000000000000000 RDI: ffff880003544080
[4394230.182241] RBP: ffff880024937c88 R08: 00000000000163c0 R09: ffff8800260163c0
[4394230.182245] R10: ffffea0000927d00 R11: ffffffff81311bb2 R12: ffff880003590000
[4394230.182250] R13: ffffffff8184dfc0 R14: 0000000000000000 R15: ffff880003544070
[4394230.182259] FS:  0000000000000000(0000) GS:ffff880026000000(0000) knlGS:0000000000000000
[4394230.182264] CS:  e033 DS: 0000 ES: 0000 CR0: 000000008005003b
[4394230.182268] CR2: 0000000000000000 CR3: 000000000180c000 CR4: 0000000000002660
[4394230.182273] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[4394230.182277] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[4394230.182281] Stack:
[4394230.182284]  ffff880003544080 ffffffff81256951 ffff880003544000 ffff880003590000
[4394230.182291]  ffff880003544000 ffff880003544070 ffff880003544070 ffff880024937c98
[4394230.182298]  ffffffff811eb7b3 ffff880024937ca8 ffffffff810f84b4 ffff880024937ce8
[4394230.182305] Call Trace:
[4394230.182311]  [<ffffffff81256951>] ? kobj_kset_leave+0x51/0x60
[4394230.182316]  [<ffffffff811eb7b3>] sysfs_create_group+0x13/0x20
[4394230.182324]  [<ffffffff810f84b4>] blk_trace_init_sysfs+0x14/0x20
[4394230.182331]  [<ffffffff8123ecfd>] blk_register_queue+0x3d/0x110
[4394230.182336]  [<ffffffff81245a0d>] add_disk+0x1cd/0x4a0
[4394230.182341]  [<ffffffff81324a1d>] blkback_changed+0xd3d/0x1010
[4394230.294407]  [<ffffffff812da098>] xenbus_otherend_changed+0x98/0xa0
[4394230.294418]  [<ffffffff812dc083>] backend_changed+0x13/0x20
[4394230.294433]  [<ffffffff812d9436>] xenwatch_thread+0xb6/0x170
[4394230.294440]  [<ffffffff81070e10>] ? wake_up_bit+0x30/0x30
[4394230.294454]  [<ffffffff812d9380>] ? unregister_xenbus_watch+0x230/0x230
[4394230.294462]  [<ffffffff8106fee0>] kthread+0xc0/0xd0
[4394230.294477]  [<ffffffff8106fe20>] ? kthread_create_on_node+0x120/0x120
[4394230.294485]  [<ffffffff8144a12c>] ret_from_fork+0x7c/0xb0
[4394230.294498]  [<ffffffff8106fe20>] ? kthread_create_on_node+0x120/0x120
[4394230.294503] Code: 8b 7d d0 89 4d c8 e8 8e e7 ff ff 4c 8b 65 d0 8b 4d c8 e9 28 ff ff ff 4c 8b 65 d0 e9 1f ff ff ff 48 83 7f 30 00 0f 85 3e fe ff ff <0f> 0b b8 ea ff ff ff e9 29 ff ff ff be c3 00 00 00 48 c7 c7 ff


以下のようなログも出力していたので、多分デバイス名の付け方に問題があったのだろう。

[4394230.181916] WARNING: at fs/sysfs/dir.c:530 sysfs_add_one+0xa5/0xd0()
[4394230.181921] sysfs: cannot create duplicate filename '/class/block/xvdt'
[4394230.181925] Modules linked in:
[4394230.181931] CPU: 0 PID: 19 Comm: xenwatch Not tainted 3.10.35-43.137.amzn1.x86_64 #1
[4394230.181937]  0000000000000009 ffff880024937b50 ffffffff8143c559 ffff880024937b88
[4394230.181945]  ffffffff8104bac1 00000000ffffffef ffff88000358acb0 ffff880024937c38
[4394230.181961]  ffff880024aad000 0000000000000001 ffff880024937be8 ffffffff8104bb2c
[4394230.181969] Call Trace:
[4394230.181986]  [<ffffffff8143c559>] dump_stack+0x19/0x1b
[4394230.181995]  [<ffffffff8104bac1>] warn_slowpath_common+0x61/0x80
[4394230.182000]  [<ffffffff8104bb2c>] warn_slowpath_fmt+0x4c/0x50
[4394230.182015]  [<ffffffff811e9955>] sysfs_add_one+0xa5/0xd0
[4394230.182020]  [<ffffffff811ea5a5>] sysfs_do_create_link_sd+0x105/0x200
[4394230.182026]  [<ffffffff811ea6c1>] sysfs_create_link+0x21/0x40
[4394230.182041]  [<ffffffff81311de4>] device_add+0x3e4/0x6d0
[4394230.182047]  [<ffffffff81310517>] ? dev_set_name+0x47/0x50
[4394230.182061]  [<ffffffff812459fd>] add_disk+0x1bd/0x4a0
[4394230.182068]  [<ffffffff81324a1d>] blkback_changed+0xd3d/0x1010
[4394230.182084]  [<ffffffff812da098>] xenbus_otherend_changed+0x98/0xa0
[4394230.182091]  [<ffffffff812dc083>] backend_changed+0x13/0x20
[4394230.182097]  [<ffffffff812d9436>] xenwatch_thread+0xb6/0x170
[4394230.182110]  [<ffffffff81070e10>] ? wake_up_bit+0x30/0x30
[4394230.182117]  [<ffffffff812d9380>] ? unregister_xenbus_watch+0x230/0x230
[4394230.182124]  [<ffffffff8106fee0>] kthread+0xc0/0xd0
[4394230.182137]  [<ffffffff8106fe20>] ? kthread_create_on_node+0x120/0x120
[4394230.182145]  [<ffffffff8144a12c>] ret_from_fork+0x7c/0xb0
[4394230.182157]  [<ffffffff8106fe20>] ? kthread_create_on_node+0x120/0x120

まとめ

AWS 的には、EBSを何個つけても問題なさそうだが、実際にたくさんEBSを付ける場合にはいろいろ考慮が必要なようだ。

2014年5月12日月曜日

RDSのMySQL でリードレプリカを作成するときの3つのポイント

RDS-MySQL のリードレプリカ

MySQL には、多くの皆さんがご存じのとおり、リードレプリカという機能がある。
簡単に言うと DB のコピーを自動的にとってくれる機能なのだが、普通に設定すると結構煩雑でちょっと面倒臭い。

Amazon Web Service (以下AWS) で、提供している RDS というサービスで、MySQL を利用することができる。このサービスではリードレプリカも簡単に設定できるようになっている。
以下のようにメニューから選んで、必要項目を入力するだけでとっても簡単。



リードレプリカをたくさん作る

たくさんの参照があって書き込みが少ないデータベース、例えば Word Press のバックエンド等ではたくさん、リードレプリカを作って負荷分散することが効果的なケースがある。

このとき RDS を利用すると簡単にたくさんのリードレプリカを作成できて、非常に便利。だがいくつか制限がある。

一つのマスターに対して作成できるリードレプリカは5つまで

一つのマスターに対して作成できるリードレプリカは5つまで。この制限を超えると以下のようなエラーが出力される。

極端にリードレプリカをたくさん増やしても、マスターへのレプリケーションの負荷が増加するので、この制限もまぁ妥当なものだろう。

リードレプリカのリードレプリカ

ではもっとたくさん作りたい場合はどうすればいいかのか。答えはリードレプリカのリードレプリカを作成すればいい。

Automated Backups を Enabled にする

ただその場合、リードレプリカ側で Automated Backups が Enabled になっていなければいけない。


デフォルトでは Enabled になっていないので以下のようにレプリカを選択して右クリックから、 "modify" を選択して、"Backup Retention Period" を 1 以上に設定する。
これをしないとそもそも "Create Read Replica" をメニューから選択することもできない。


このときに "Apply Immediately" にチェックを入れておかないと次回のメンテナンスウィンドウか、手動で再起動されるまで、設定が反映されないので忘れずに。上の例では、ドロップダウンメニューの後ろに隠れている。

リードレプリカのリードレプリカは2段まで

ただし、リードレプリカは2段までしかできない。つまりリードレプリカのリードレプリカは作れるけれど、リードレプリカのリードレプリカのリードレプリカは作れない。作成しようとすると、以下のようなエラーが出力される。あんまり段数を増やしても今度はレプリケーションの遅延が大きくなるので、この制限はまぁ妥当なものだろう。




リードレプリカは全部で30個

マスターに対してリードレプリカは5個さらに5個のリードレプリカに対して5個ずつリードレプリカができるので2段目は 5 × 5 で、25 個。一つのマスターに対して合わせて30個のリードレプリカが作成できる。
ただし 30 個まで作れるものの実際のレプリケーションの負荷もばかにならないので、よっぽど書き込みが少ない場合も除いて実際の参照用として利用できるのは2段目の25個だけだと思っていい。
また2段目まで書き込みが反映されるまでのレイテンシーも2倍以上になるので、この点も考慮する必要がある。

まとめ

RDSのリードレプリカを作成する際は以下の3つに注意する必要がある。
  1. 一つのマスターに対して5個まで。
  2. 多段レプリカは2段まで。
  3. Automated Backups を有効にする。

最後に

便利に見えるリードレプリカですが、コスト面や読み取り専用としてしか使えないなど不便なところもあるので、実際の運用としては先に以下の方法も検討した方がよい。
  • インスタンスのサイズ変更で対応できないか。
  • PIOPS を利用で改善できないか。
上記二つの方が、リードレプリカを作成するよりも簡単で効果が高い場合もあります。

2014年3月25日火曜日

AWS VPC で VPC 間接続がサポートされたので試してみた。

AWS で VPC間の接続(Peering) がサポートされたので試してみました。
現在同一リージョン内のみで接続可能です。

今回不幸にも Management Console の更新が出ていたにも関わらず、うっかり NO とか 押してしまったためにコマンドライン(ec2-apitool)で実行してみました。
aws cli は、git 版も含めて現在サポートされていないようです。

まずec2-apitoolを最新化します。現在 1.6.13.0 でピアリング関係のコマンドが追加されています。
以下はAWS LINUXで標準でインストール されているコマンドを置き換える例です。
$ wget http://s3.amazonaws.com/ec2-downloads/ec2-api-tools.zip
$ cd /opt/aws/apitools
$ sudo unzip ~/ec2-api-tools.zip
$ sudo mv ec2-api-tools-1.6.13.0 ec2-1.6.13.0
$ sudo rm -f ec2
$ sudo ln -s ec2-1.6.13.0 ec2
$ cd ec2/bin
$ sudo rm -f *.cmd
$ cd /opt/aws/bin
$sudo find /opt/aws/apitools/ec2-1.6.13.0/ -iname "ec2-*" -exec ln -f -s {} . \;
VPC はマネージメントコンソールで適当に作成しておきます。 今回は異なるアカウント間で試してみました。
ピアリングのリクエストは以下のコマンドラインで設定します。 $ ec2-create-vpc-peering-connection --region us-west-2 -c vpc-526xxxxx -p vpc-576bxxxx -o 1xxxxxxxxxx0
VPCPEERINGCONNECTION pcx-e96xxxxx Tue Apr 01 11:42:46 UTC 2014 initiating-request: Initiating Request to 1xxxxxxxxxx0
REQUESTERVPCINFO vpc-526xxxxx 10.1.0.0/16 4xxxxxxxxxx6
ACCEPTERVPCINFO vpc-576bxxxx 1xxxxxxxxxx0
ec2-create-vpc-peering-connection
  • --region : リージョンを指定します。今回はoregon を使用しました。
  • -c : 接続元のvpc-id を指定します。
  • -r : 接続先のvpc-id を指定します。
  • -o : 接続先のアカウントIDを指定します。

VPC ピアリングコネクション ID ( pcx-e96xxxxx ) を控えて、接続先に連絡します。
ピアリングリクエストをアクセプトするためには、接続先のアカウントで以下の コマンドを実行します。 $ ec2-accept-vpc-peering-connection --region us-west-2 pcx-e96xxxxx
VPCPEERINGCONNECTION pcx-e96xxxxx provisioning: Provisioning
REQUESTERVPCINFO vpc-526xxxxx 10.1.0.0/16 4xxxxxxxxxx6
ACCEPTERVPCINFO vpc-576bxxxx 10.0.0.0/16 1xxxxxxxxxx0
ec2-create-vpc-peering-connection
  • --region : リージョンを指定します。
  • pcx-e96xxxxx : 先ほど控えた VPC ピアリングコネクション ID
さらに接続元、接続先でルーティングテーブルにエントリを追加します。
[接続元]
$ec2-create-route --region us-west-2 rtb-e67xxxxx -r 10.1.0.0/16 -p pcx-e96xxxxx
ROUTE 10.0.0.0/16 pcx-e96xxxxx
[接続先]
$ec2-create-route --region us-west-2 rtb-187xxxxx -r 10.1.0.0/16 -p pcx-e96xxxxx
ROUTE 10.1.0.0/16 pcx-e96xxxxx
ec2-create-vpc-peering-connection
  • --region : リージョンを指定します。
  • -r : 相手ネットワーク の CIDRブロックを指定します。 VPC 全体でも、サブネットでもかまいません。
  • -p : VPC ピアリングコネクション ID を指定します。
両方合わせてわずか、4コマンドで接続できました。詳細は現在英語版だけですが、マニュアルを参照してください。

2014年3月3日月曜日

電力効率がいいワークキューって?

 Linux Foundation の LTSI(Long Term Support Initiative) v3.10 公開 という記事のなかで、 "電力効率のよい workqueue" という機能がマージされたとのこと。
なぜ workqueue の変更で電力効率が変わるんだ? ということで調べたメモ。
※K.T. さん情報提供ありがとうございます。

workqueue

workqueue というのは、簡単にいうとLinux カーネルのなかで処理を遅延させる 仕組みのこと。
LINUX kernelに限らず、現代のOSは機能が豊富でたくさんの仕事をしなければいけない。

一方でOSは通常のプロセスとは違い特権モードで動作しているので、 あんまりお仕事をしすぎるとユーザープロセスの動作が遅れてしまう。

本来OSの利用者は、自分のプロセスが高速に動作することを期待しているので、 OSがお仕事しすぎてユーザープロセスが遅れては本末転倒である。

そこでOSのお仕事のうち、待ちが発生するものや、今すぐにやらなくてもいいこと を順番待ちに登録(queueing)して、後から適切な時に実行するのが workqueue という仕組み。

なんで仕事の順番を替えるだけで、電力消費が減るんだろう?というのが今回の 疑問。その前に少しだけ、MPUのお話。

big.LITTLE処理

最近のARMプロセッサでは「big.LITTLE処理」という機能が搭載されている。 これは簡単に言うと、高速で消費電力が大きい(big)プロセッサ(ARM Cortex™-A15プロセッサ) と、低速で消費電力が小さい(LITTLE)プロセッサ(Cortex™-A7)を両方搭載して、 処理の内容や、タイミングなどによって使い分けようという考え方。

電力効率のよい workqueue

この"big.LITTLE処理" を workqueue に適用して、できるだけLITTLE側に処理を 振ることで電力効率を改善するというのが今回マージされた機能ということに なる。わかってみればそれほど難しい話ではない。

一般のスケジューラでは?

処理をできるだけ LITTLE 側に振るだけで、電力消費が減るならば一般のプロセス スケジューラでも適用できるのでは?と思ってちょっと調べてみた。
現在、IKS と呼ばれる方式と、GTS(big.LITTLE MP)と呼ばれる2つの方式が 提案されているようだ。IKS は cpufreq という電力管理の延長線上で big と LITTLE の切り替えを行う方式。

GTS は、スケジューラ(sched) に変更を加えてbig と LITTLEにプロセスを 割り当てる方式。

さすがに sched に手を入れた場合は影響範囲が大きいのでメインストリーム には取り込まれておらず、特定の機器で取り込まれている模様。

SMP でない環境でのスケジューリングはいろいろ議論があって面白そう。

参考

workqueue については例えば、以下のIBM developerWorks の記事などを参照
「カーネル API: 第 2 回、遅延可能な関数、カーネルのタスクレット、およびワークキュー」
http://www.ibm.com/developerworks/jp/linux/library/l-tasklets/

big.LITTLE処理
http://www.arm.com/ja/products/processors/technologies/biglittleprocessing.php

後藤弘茂のWeekly海外ニュース
「 2014年のARMのSoCの中核技術となる「big.LITTLE MP」」
http://pc.watch.impress.co.jp/docs/column/kaigai/20131220_628480.html

Linaro Blog 「big.LITTLE Software Update」
http://www.linaro.org/linaro-blog/2013/07/10/big-little-software-update/

LWN.net「 Queue work on power efficient wq 」
http://lwn.net/Articles/548281/

2014年2月27日木曜日

/proc/diskstats のメモ

こんな簡単なメモでも誰かの役に立つかもしれない
RHEL 6 kernel-2.6.32-431.5.1.el6.src.rpm から。
Field No.変数簡単な説明タイプ単位関数
1MAJOR(part_devt(hd))メジャー番号
2MINOR(part_devt(hd)マイナー番号
3disk_name(gp, hd->partno, buf)ディスク名
4ios[0]完了済み読み込みIO数カウンターblk_account_io_done
5merges[0]マージ済み読み込みIO数カウンターdrive_stat_acct
6sectors[0]完了済み読み込みセクター数カウンターblk_account_io_completion
7ticks[0]読み込みで使用された秒数カウンターミリ秒blk_account_io_done
8ios[1]完了済み書き込みIO数カウンターblk_account_io_done
9merges[1]マージ済み書き込みIO数カウンターdrive_stat_acct
10sectors[1]完了済み書き込みセクター数カウンターblk_account_io_completion
11ticks[1])書き込みで使用された秒数カウンターミリ秒blk_account_io_done
12part_in_flight(hd)実行中のIO数ゲージdrive_stat_acct,blk_account_io_done
13io_ticksIOにかかった時間カウンターミリ秒drive_stat_acct
14time_in_queueキューにIOがあった合計時間 (in_flight x io_ticks の合計)カウンターミリ秒drive_stat_acct
blk_finish_request
->blk_account_io_done
─────────────────────
2003  unsigned long duration = jiffies - req->start_time;
2011  part_stat_inc(cpu, part, ios[rw]);
2012  part_stat_add(cpu, part, ticks[rw], duration);
2013  part_round_stats(cpu, part);
2014  part_dec_in_flight(part, rw);
2015
─────────────────────

blk_update_request
->blk_account_io_completion
──────────────────────────
1981static void blk_account_io_completion(struct request *req, unsigned int bytes)
1982{
1983 if (blk_do_io_stat(req)) {
1984  const int rw = rq_data_dir(req);
1985  struct hd_struct *part;
1986  int cpu;
1987
1988  cpu = part_stat_lock();
1989  part = disk_map_sector_rcu(req->rq_disk, blk_rq_pos(req));
1990  part_stat_add(cpu, part, sectors[rw], bytes >> 9);
1991  part_stat_unlock();
1992 }
1993}
──────────────────────────

blk_insert_request
blk_queue_bio
blk_insert_cloned_request
->drive_stat_acct
──────────────────────────
1199static void part_round_stats_single(int cpu, struct hd_struct *part,
1200        unsigned long now)
1201{
1202 if (now == part->stamp)
1203  return;
1204
1205 if (part_in_flight(part)) {
1206  __part_stat_add(cpu, part, time_in_queue,
1207    part_in_flight(part) * (now - part->stamp));
1208  __part_stat_add(cpu, part, io_ticks, (now - part->stamp));
1209 }
1210 part->stamp = now;
1211}
──────────────────────────

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

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