24 Jan 2016, 00:19

クラウドは本当に性能不足なのか

このエントリは2016/1/24に書きました。使えるリソースはどんどん増えていくので、適宜その時点で情報をとってください。

具体的な数値で、正しい理解を

“クラウドは性能不足、企業システムが重すぎる”という記事が身の回りで話題になりました。公開から4日たっても「いま読まれている記事」の上位にあり、注目されているようです。

記事で訴えたかったことは、クラウドを過信しないように、そして、クラウドはクラウドらしい使い方をしよう、ということでしょう。ユーザの声は貴重ですし、同意できるところも多い。でも、「企業システム」とひとくくりにしてしまったこと。タイトルのバイアスが強いこと。そして、具体的な根拠に欠けることから、誤解を招いている印象です。

どんな技術、製品、サービスにも限界や制約はあります。具体的な数値や仕様で語らないと、そこから都市伝説が生まれます。

いい機会なので、わたしの主戦場であるAzureを例に、クラウドでどのくらいの性能を期待できるか、まとめてみようと思います。

シングルVMでどれだけ

話題となった記事でも触れられているように、クラウドはその生まれから、分散、スケールアウトな作りのアプリに向いています。ですが世の中には「そうできない」「そうするのが妥当ではない」システムもあります。記事ではそれを「企業システム」とくくっているようです。

わたしは原理主義者ではないので「クラウドに載せたかったら、そのシステムを作り直せ」とは思いません。作りを大きく変えなくても載せられる、それでクラウドの特徴を活かして幸せになれるのであれば、それでいいです。もちろん最適化するにこしたことはありませんが。

となると、クラウド活用の検討を進めるか、あきらめるか、判断材料のひとつは「スケールアウトできなくても、性能足りるか?」です。

この場合、1サーバ、VMあたりの性能上限が制約です。なので、AzureのシングルVM性能が鍵になります。

では、Azureの仮想マシンの提供リソースを確認しましょう。

“仮想マシンのサイズ”

ざっくりA、D、Gシリーズに分けられます。Aは初期からあるタイプ。DはSSDを採用した現行の主力。Gは昨年後半からUSリージョンで導入がはじまった、大物です。ガンダムだと後半、宇宙に出てから登場するモビルアーマー的な存在。現在、GシリーズがもっともVMあたり多くのリソースを提供できます。

企業システムではOLTPやIOバウンドなバッチ処理が多いと仮定します。では、Gシリーズ最大サイズ、Standard_GS5の主な仕様から、OLTPやバッチ処理性能の支配要素となるCPU、メモリ、IOPSを見てみましょう。

  • Standard_GS5の主な仕様
    • 32仮想CPUコア
    • 448GBメモリ
    • 80,000IOPS

メモリはクラウドだからといって特記事項はありません。クラウドの特徴が出るCPUとIOPSについて深掘りしていきます。

なお、現時点でまだ日本リージョンにはGシリーズが投入されていません。必要に応じ、公開スペックと後述のACUなどを使ってA、Dシリーズと相対評価してください。

32仮想CPUコアの規模感

クラウドのCPU性能表記は、なかなか悩ましいです。仮想化していますし、CPUは世代交代していきます。ちなみにAzureでは、ACU(Azure Compute Unit)という単位を使っています。

“パフォーマンスに関する考慮事項”

ACUはAzure内で相対評価をする場合にはいいのですが、「じゃあAzureの外からシステムもってきたとき、実際どのくらいさばけるのよ。いま持ってる/買えるサーバ製品でいうと、どのくらいよ」という問いには向きません。

クラウドや仮想化に関わらず、アプリの作りと処理するデータ、ハードの組み合わせで性能は変わります。動かしてみるのが一番です。せっかくイニシャルコストのかからないクラウドです。試しましょう。でもその前に、試す価値があるか判断しなければいけない。なにかしらの参考値が欲しい。予算と組織で動いてますから。わかります。

では例をあげましょう。俺のベンチマークを出したいところですが、「それじゃない」と突っ込まれそうです。ここはぐっと我慢して、企業でよく使われているERP、SAPのSAP SDベンチマークにしましょう。

“SAP Standard Application Benchmarks in Cloud Environments”

“SAP Standard Application Benchmarks”

SAPSという値が出てきます。販売管理アプリケーションがその基盤上でどれだけ仕事ができるかという指標です。

比較のため、3年ほど前の2ソケットマシン、現行2ソケットマシン、現行4ソケットマシンを選びました。単体サーバ性能をみるため、APとDBを1台のサーバにまとめた、2-Tierの値をとります。

DELL R720 Azure VM GS5 NEC R120f-2M FUJITSU RX4770 M2
Date 20124 20159 20157 20157
CPU Type Intel Xeon Processor E5-2690 Intel Xeon Processor E5-2698B v3 Intel Xeon Processor E5-2699 v3 Intel Xeon Processor E7-8890 v3
CPU Sockets 2 2 2 4
CPU Cores 16 32 (Virtual) 36 72
SD Benchmark Users 6,500 7,600 14,440 29,750
SAPS 35,970 41,670 79,880 162,500

3年前の2ソケットマシンより性能はいい。現行2ソケットマシンの半分程度が期待値でしょうか。ざっくりE5-2699 v3の物理18コアくらい。4ソケットは無理め。

なお補足ですが、もちろんSAPはAPサーバをスケールアウトする構成もとれます。その性能は3-Tierベンチマークで確認できます。Azure上で247,880SAPS出たそうです。

80,000IOPSの規模感

IOPS = IO Per Second、秒あたりどれだけIOできるかという指標です。Azure VM GS5ではPremium Storageを接続し、VMあたり最大80,000IOPSを提供します。

一般的に企業で使われているディスクアレイに載っているHDDのIOPSは、1本あたりおおよそ200です。IOPSに影響する要素は回転数で、よく回る15,000rpm FC/SAS HDDでだいたいこのくらい。

なので80,000 / 200 = 400。よって80,000IOPSを達成しようとすると、HDDを400本並べないといけません。小さくないです。

もちろんディスクアレイにはキャッシュがあるので、キャッシュヒット次第でIOPSは変わります。ベンダが胸を張って公開している値も、キャッシュに当てまくった数字であることが多いです。ですが誠実な技術者は「水物」なキャッシュヒットを前提にサイジングしません。アプリがアレイを占有できて、扱うデータの量や中身に変化がない場合は別ですが、それはまれでしょう。ヒットしない最悪の場合を考慮するはずです。

なお、数十万IOPSをこえるディスクアレイがあるのは事実です。でも「桁が違う。クラウドしょぼい」と思わないでください。ディスクアレイ全体の性能と、VMあたりどのくらい提供するかは、別の問題です。ひとつのVMがディスクアレイを占有するのでない限り、VMあたりのIOコントロールは必要です。そうでないと、暴れん坊VMの割を食うVMがでてきます。見えていないだけで、クラウドのバックエンドにはスケーラブルなストレージが鎮座しています。

結論

  • Intel x86 2ソケットモデルサーバで動いているようなシステムの移行であれば検討価値あり
  • メモリが448GB以上必要であれば難しい
  • サーバあたり80,000IOPS以上必要であれば難しい、でも本当にサーバあたりそれだけ必要か精査すべき

ちょっと前までオンプレ案件も担当していましたが、ここ数年は2ソケットサーバ案件中心、ときどき、4ソケット以上で興奮。という感覚です。みなさんはいかがでしょう。データはないのでご参考まで。

なにはともあれ、プロのみなさんは噂に流されず、制約を数値で把握して判断、設計しましょう。Azureではそのほかの制約条件も公開されていますので、ぜひご一読を。上限を緩和できるパラメータも、あります。

“Azure サブスクリプションとサービスの制限、クォータ、制約”

11 Jan 2016, 00:20

Azureでインフラデプロイツールを選ぶ時に考えていること

ケースバイケースだけど

Azureを生業にして、3か月たちます。ここまで、もっとも質問や議論が多いのが、デプロイメントの自動化についてです。進化が早いですし、選択肢も豊富。クラウド採用に合わせて自動化に挑戦するケースも増えてますので、自然なことと思います。

特に話題になるのが「どのツールを選べばいいか」。ツールというのは課題を解決する手段なので、まず課題を掘るべきです。ですが、まだ成熟していない領域で変化が激しいですし、ツールひとつで課題を解決できるとも限らない。複数のツールを組み合わせることも多く、依存関係もありそう。となると、考えるきっかけが欲しいのは、ごもっとも。

なので「ケースバイケース。以上」とは、言いにくい。

私見であっても、たたき台となる考え方なりパターンがWebに転がっていれば、参考になるかもしれない。それがこのエントリを書く動機です。わたしは他のプラットフォームからAzureに主戦場を移していますので、新鮮な意見が書けるかも、という背景も、あります。

書く前に前提など

対象はインフラレイヤのデプロイメントに絞ります。そして、インフラ = 物理/仮想ハードウェア(サーバ、ストレージ、ネットワーク) + OS + プラットフォームソフト(アプリじゃないもの、Webサーバ、ユーティリティ、etc)と定義します。

レイヤリングや用語は、 @gosukenator さんの“インフラ系技術の流れ”が参考になるので、合わせて読むと幸せになれるでしょう。このエントリで言うBootstrapping/Configurationレイヤが今回の焦点です。

では、わたしがツールを選ぶ時にどんなことを考えているのか、脳内をダンプしていきましょう。

そもそもツールで自動化すべきかを考える

いきなり萎えるそもそも論で恐縮ですが、重要です。たとえばあるソフトの試用目的で、同じ構成のサーバのデプロイは今後しなさそう、台数は1台、使うのは自分だけ、なんていう環境のデプロイまで、自動化する必要はないはずです。時短、工数削減、オペレーションミスリスクの軽減、そもそも自動化しないと運用がまわらない、など自動化によって得られる利益がその手間を上回るかを判断します。

なお「知っている/できる」人でないとその価値、利益はわかりません。やらないという判断は、腕があってはじめてできることです。

使い捨てられないかを考える

次は、ツールによって作った環境がどのように変化するか、変えられるかを検討します。ストレートに言うと、変化のタイミングで捨てられないか?新しいものに置き換えられないか?を考えます。もしこれができるのであれば、方式はとてもシンプルにできます。Immutable Infrastructure、Blue/Green Deploymentなどのやり口が注目されていますが、これらの根っこには「ちまちま変化を加えて複雑化するくらいなら、使い捨て/入れ替えてしまえ」という意識があります。

ですが、とは言ってもそんな大胆にできない事情もあると思います。Blue/Green Deploymentでは、入れ替えのタイミングでBlue、Green分のリソースが必要になりますし、切り替えにともなうリスクもあります。それを許容できない場合、同じインフラに変化を積んでいくことになります。ChefなどConfigurationレイヤで冪等なオペーレーションができるツールが注目されたのは、この変化を維持しやすいからです。

変化を積む場合にやるべきでないのは、中途半端に職人が真心こめて手作業してしまうことです。ツールでやると決めたら、少なくともそのカバー範囲はツールに任せましょう。でないといわゆる「手作業汚れ」「スノーフレークサーバ(雪の結晶のように、全部同じように見えて実はそれぞれ違う)」のダークサイドに堕ちます。

変化を積まないのであれば、インフラデプロイメント用途ではConfigurationレイヤのツールを導入しないという割り切りもできるでしょう。

優先事項や制約条件を洗い出す

アーキテクトが真っ白なキャンバスに画を描けることはほぼありません。きっと、先になんらかの優先事項や制約条件があるはずです。そして、ほとんどのシステムにおいて、インフラのデプロイは主役ではありません。ツールに合わせてもらえることはまれでしょう。様々な条件を選定にあたって洗い出す必要があります。

  • 社内/プロジェクト標準

 周知されていないだけで、推奨ツールが決まってたりします。あるある。そのツールの良し悪しは置いておいて、社内ノウハウの蓄積など、大きな目的がある場合には従うべきでしょう。

  • 他レイヤでの優先ツール

 インフラのデプロイに影響がありそうなツールがアプリ開発側で決まっていたりします。最近華やかなのがDockerです。Docker社が出してるツール群は上から下までカバー範囲も広く、デプロイツールと重複しがちです。組み合わせを検討しなければいけません。また、Apache Mesosもインフラとアプリのグレーゾーンに鎮座します。なかなか悩ましいですが、優先せざるをえません。

  • 規模

 いきなり1000台とか10000台規模を扱うユーザは多くないと思いますが、その規模になるとツールの性能限界にぶち当たったりします。念のため、意識はしましょう。ちなみに、1000台をひとつのツールの傘に入れずとも、たとえば10*100台にする設計ができないか、事前に考えておくと打ち手が増えます。

  • チーム or ひとり

 本番環境のデプロイ自動化はチームプレイになるので、ツールの導入はサーバ上になるでしょうし、構成ファイルの共有、バージョンコントロールなど考慮点は多いです。一方で、開発者が開発、検証用途で端末に導入し実行する使い方では、手軽さが求められます。誤解を恐れず例をあげると、前者にはChefが、後者にはAnsibleやTerraformがフィットしやすいです。

  • Windows or Linux

 Azure ARM Templateなど、はじめからマルチOS環境を前提に作られているツールはありますが、ほとんどのツールはその生まれがWindows、Linuxに寄っています。マルチOS対応が進んではいますが、活用にあたって、参考となる情報量には大きな差があります。たとえばマルチOS対応のツールであっても、DSCはWindowsの、ChefやAnsibleはLinuxの情報が圧倒的に多いです。これは意識せざるを得ません。使うOSでの十分な情報があるか確認します。

マネージドサービス、機能を活用する

マネージドサービス = プラットフォームが提供している機能です。Azureであれば、今回対象としているレイヤではARMがそれにあたります。デプロイツールは有用ですが、その導入や維持運用には本質的価値はありません。プラットフォームに任せられるのであれば、そうしたほうが楽です。

また、Azureのインフラは進化が早いため、それに対応するスピードも、本家ツールのほうが期待できます。

ですが、以前のエントリで触れたように、本家のツールであっても、すべてのレイヤをカバーできるほど万能ではありません。たとえばARM TemplateはインフラのBootstrappingには向いていますが冪等性が限定的であるため、ソフトウェアパッケージを足す/消す/入れ替えるを頻繁に繰り返す環境のConfiguration用途では、苦しいです。

よってARM Templateは、Immutableな環境で使う、もしくは、ChefなどのConfigurationツールと組み合わせて使うことを念頭に設計をします。

ARM Templateでは、ハード(VM、ストレージ、ネットワーク)の割り当て、OSの導入と設定、各種エージェントの導入が基本。それに加え、Immutableな環境ではプラットフォームソフトを導入してしまっていいでしょう。ARM TemplateにはDSCやシェルを実行するエクステンションが使えるので、活用します。

また、Bootstrapping時点で、Configurationツールを導入できてしまうのであれば、せっかくなので入れてしまいましょう。たとえばChefサーバのインストールは、ここで。

以上、ちょっとまとまりに欠けますが、ざっとわたしが意識していることを、挙げてみました。

汎用的 リファレンスアーキテクチャ

具体例があったほうが分かりやすいので、最後に汎用的な組み合わせを紹介します。

“Automating Deployment with Azure & Chef”

  • ARM TemplateでBootstrapping

    • VMを4つ作成、1つはLinux、他はWindows
    • ストレージ、ネットワークの作成
    • VMのストレージ、ネットワーク設定
    • OSの導入
    • ドメインコントローラサーバへのソフト導入、各種設定 (DSC/PowerShell Extension)
    • 他Windowsサーバへのソフト導入、各種設定、ドメイン参加 (PowerShell Extension)
    • LinuxへChefサーバを導入、各種設定 (Shell Extension)
  • ChefでConfiguration

    • 各ノードのChef bootstrap(言葉が混同しやすいので注意)
    • Chef Clientサービスの起動設定
    • DBサーバのDB領域ディスク作成、フォーマット
    • DBサーバへSQL Server 2014のインストール
    • ChefがDBサーバが設定通りになるよう維持し続ける

どうでしょう、役割分担がイメージできたでしょうか。いいドキュメントがあったので、ChefのLinux/Windows混在例を紹介しましたが、Windowsとの親和性や情報量を重視するなら、ChefをAzure Automation DSCに置き換えて挑戦してもいいでしょう。そのまた逆もありで、ChefならLinux染めな環境で、とこだわってもいいと思います。

書くことが意外に多かったので、また機会があれば、参考例を交えて紹介します。

06 Jan 2016, 00:16

Azure ARM Templateによるデプロイと冪等性

宣言的に、冪等に

ここ数年で生まれたデプロイメント手法、ツールは数多くありますが、似たような特徴があります。それは「より宣言的に、冪等に」です。これまで可読性や再利用性を犠牲にしたシェル芸になりがちだったデプロイの世界。それがいま、あるべき姿を定義しその状態に収束させるように、また、何度ツールを実行しても同じ結果が得られるように変わってきています。

さて、そんな時流に飛び込んできたデプロイ手法があります。AzureのARM(Azure Resource Manager) Templateによるデプロイです。ARMはAzureのリソース管理の仕組みですが、そのARMに対し、構成を宣言的に書いたJSONを食わせて環境を構築する手法です。Azureの標準機能として、提供されています。

Azure リソース マネージャーの概要

“ソリューションを開発のライフサイクル全体で繰り返しデプロイできます。また、常にリソースが一貫した状態でデプロイされます”

“宣言型のテンプレートを利用し、デプロイメントを定義できます”

冪等と言い切ってはいませんが、目的は似ています。

なるほど、期待十分。ではあるのですが、冪等性の実現は簡単ではありません。たとえばChefやAnsibleも、冪等性はリソースやモジュール側で考慮する必要があります。多様なリソースの違いを吸収しなければいけないので、仕方ありません。魔法じゃないです。その辺を理解して使わないと、ハマります。

残念ながらARMは成長が著しく、情報が多くありません。そこで、今回は実行結果を元に、冪等さ加減を理解していきましょう。

増分デプロイと完全デプロイ

まず、デプロイのコマンド例を見ていきましょう。今回はPowerShellを使いますが、Mac/Linux/Winで使えるクロスプラットフォームCLIもあります。

PS C:\> New-AzureRmResourceGroupDeployment -ResourceGroupName YourRGName -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json

ワンライナーです。これだけで環境ができあがります。-TemplateFileでリソース定義を記述したJSONファイルを指定します。また、-TemplateParameterFileにパラメータを外だしできます。

今回は冪等さがテーマであるため詳細は省きます。関心のあるかたは、別途ドキュメントで確認してください。

さて、ワンライナーで環境ができあがるわけですが、その後が重要です。環境変更の際にJSONで定義を変更し、同じコマンドを再投入したとしても、破たんなく使えなければ冪等とは言えません。

コマンド投入には2つのモードがあります。増分(Incremental)と完全(Complete)です。まずは増分から見ていきましょう。

・リソース グループに存在するが、テンプレートに指定されていないリソースを変更せず、そのまま残します

・テンプレートに指定されているが、リソース グループに存在しないリソースを追加します

・テンプレートに定義されている同じ条件でリソース グループに存在するリソースを再プロビジョニングしません

すでに存在するリソースには手を入れず、JSONへ新たに追加されたリソースのみを追加します。

いっぽうで、完全モードです。

・リソース グループに存在するが、テンプレートに指定されていないリソースを削除します

・テンプレートに指定されているが、リソース グループに存在しないリソースを追加します

・テンプレートに定義されている同じ条件でリソース グループに存在するリソースを再プロビジョニングしません

2、3番目は増分と同じです。1番目が違います。JSONから定義を消されたリソースを削除するかどうかが、ポイントです。完全モードはスッキリするけどリスクも高そう、そんな印象を受けるのはわたしだけではないでしょう。

動きをつかむ

では動きを見ていきましょう。テンプレートはGithubに公開されているVery simple deployment of an Linux VMを使います。詳細は説明しませんので、読み進める前にリソース定義テンプレートファイル(azuredeploy.json)をリンク先でざっと確認してください。

パラメータファイル(azuredeploy.parameters.json)は以下とします。

{
  "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "adminUsername": {
      "value": "azureUser"
    },
    "adminPassword": {
      "value": "password1234!"
    },
    "dnsLabelPrefix": {
      "value": "armpocps"
    },
    "ubuntuOSVersion": {
      "value": "14.04.2-LTS"
    }    
  }
}

まず、1回目の実行です。リソースグループ “ARMEval”に対しデプロイします。このリソースグループは前もって作っておいた空の箱です。

PS C:\Workspace> New-AzureRmResourceGroupDeployment -ResourceGroupName ARMEval -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json 

DeploymentName    : azuredeploy
ResourceGroupName : ARMEval
ProvisioningState : Succeeded
Timestamp         : 2016/01/04 11:46:41
Mode              : Incremental
TemplateLink      :
Parameters        :
                Name             Type                       Value
                ===============  =========================  ==========
                adminUsername    String                     azureUser
                adminPassword    SecureString
                dnsLabelPrefix   String                     armpocps
                ubuntuOSVersion  String                     14.04.2-LTS

Outputs           :

できあがりです。空のリソースグループ にLinux VM、ストレージ、仮想ネットワーク、パブリックIPなどがデプロイされました。Modeを指定しない場合は増分(Incremental)となります。

この環境にじわじわと変更を入れていきましょう。まずはazuredeploy.parameter.json上のパラメータ、DNS名のPrefix(dnsLabelPrefix)をarmpocps -> armpocps2と変えます。

"dnsLabelPrefix": {
  "value": "armpocps2"
},

では再投入です。パラメータファイルの内容は変えましたが、コマンドは同じです。

PS C:\Workspace> New-AzureRmResourceGroupDeployment -ResourceGroupName ARMEval -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json 
[snip]
Parameters        :
                Name             Type                       Value
                ===============  =========================  ==========
                adminUsername    String                     azureUser
                adminPassword    SecureString
                dnsLabelPrefix   String                     armpocps2
                ubuntuOSVersion  String                     14.04.2-LTS

変更内容の確認です。

PS C:\Workspace> Get-AzureRmPublicIpAddress
[snip]
DnsSettings              : {
                             "DomainNameLabel": "armpocps2",
                             "Fqdn": "armpocps2.japanwest.cloudapp.azure.com"
                           }

問題なく変わっていますね。冪等チックです。この例ではシンプルにDNS名のPrefixを変えましたが、VMインスタンス数やsubnet名を変えたりもできます。関心のある方はドキュメントを。

増分モードによる変更は期待できそうです。が、さて、ここからが探検です。リソース削除が可能な完全モードを試してみましょう。 リソース定義ファイル(azuredeploy.json)から、大胆にVMの定義を削ってみます。下記リソースをファイルからごっそり消します。

{
  "apiVersion": "[variables('apiVersion')]",
  "type": "Microsoft.Compute/virtualMachines",
  "name": "[variables('vmName')]",
[snip]

では、完全モード “-Mode complete”付きでコマンドを再投入します。

PS C:\Workspace> New-AzureRmResourceGroupDeployment -ResourceGroupName ARMEval -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json  -Mode complete

確認
Are you sure you want to use the complete deployment mode? Resources in the resource group 'ARMEval' which are not included in the template will be deleted.
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): Y

DeploymentName    : azuredeploy
ResourceGroupName : ARMEval
ProvisioningState : Succeeded
Timestamp         : 2016/01/04 12:01:00
Mode              : Complete
TemplateLink      :
Parameters        :
                Name             Type                       Value
                ===============  =========================  ==========
                adminUsername    String                     azureUser
                adminPassword    SecureString
                dnsLabelPrefix   String                     armpocps2
                ubuntuOSVersion  String                     14.04.2-LTS

Outputs           :

あっさり完了しました。本当にVMが消えているが確認します。出力が冗長ですがご容赦ください。

PS C:\Workspace> Find-AzureRmResource -ResourceGroupNameContains ARMEval

Name              : myPublicIP
ResourceId        :     /subscriptions/your-subscription-id/resourceGroups/ARMEval/providers/Microsoft.Network/publicIPAddresses/myPublicIP
ResourceName      : myPublicIP
ResourceType      : Microsoft.Network/publicIPAddresses
ResourceGroupName : ARMEval
Location          : japanwest
SubscriptionId    : your-subscription-id

Name              : myVMNic
ResourceId        : /subscriptions/your-subscription-id/resourceGroups/ARMEval/providers/Microsoft.Network/networkInterfaces/myVMNic
ResourceName      : myVMNic
ResourceType      : Microsoft.Network/networkInterfaces
ResourceGroupName : ARMEval
Location          : japanwest
SubscriptionId    : your-subscription-id

Name              : MyVNET
ResourceId        : /subscriptions/your-subscription-id/resourceGroups/ARMEval/providers/Microsoft.Network/virtualNetworks/MyVNET
ResourceName      : MyVNET
ResourceType      : Microsoft.Network/virtualNetworks
ResourceGroupName : ARMEval
Location          : japanwest
SubscriptionId    : your-subscription-id

Name              : yourstorageaccount
ResourceId        : /subscriptions/your-subscription-id/resourceGroups/ARMEval/providers/Microsoft.Storage/storageAccounts/yourstorageaccount
ResourceName      : yourstorageaccount
ResourceType      : Microsoft.Storage/storageAccounts
ResourceGroupName : ARMEval
Location          : japanwest
SubscriptionId    : your-subscription-id
Tags              : {}

VMだけが消えています。定義からリソースがなくなれば、存在するリソースも消す、これが完全モードです。

さらに検証。冪等さを求めるのであれば、またリソース定義にVMを加えて再投入したら、涼しい顔で復活してほしい。先ほどazuredeploy.jsonから消したVMリソース定義を、そのまま書き戻して再投入してみます。

PS C:\Workspace> New-AzureRmResourceGroupDeployment -ResourceGroupName ARMEval -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json  -Mode complete

確認
Are you sure you want to use the complete deployment mode? Resources in the resource group 'ARMEval' which are not included in the template will be deleted.
[Y] はい(Y)  [N] いいえ(N)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): Y

New-AzureRmResourceGroupDeployment : 21:05:52 - Resource Microsoft.Compute/virtualMachines 'MyUbuntuVM' failed with message 'The resource operation completed with terminal provisioning state 'Failed'.'
[snip]
New-AzureRmResourceGroupDeployment : 21:05:52 - One or more errors occurred while preparing VM disks. See disk instance view for details.

残念ながら失敗しました。どうやらdiskまわりのエラーが発生したようです。

これは、完全モードでのリソース削除の仕様が原因です。ARMは該当のVMリソースは消すのですが、VMが格納されているストレージを削除しません。リソース作成時は依存関係が考慮されますが、削除時は異なります。

試しにストレージを消して再実行してみましょう。

PS C:\Workspace> New-AzureRmResourceGroupDeployment -ResourceGroupName ARMEval -TemplateFile .\azuredeploy.json -TemplateParameterFile .\azuredeploy.parameters.json  -Mode complete

[snip]
ProvisioningState : Succeeded

定義通りの環境になりました。依存関係をたどって消してほしいのが人情ですが、残したほうがいいケースもあるので、今後の改善を期待しましょう。

使い方

冪等であると言い切れないものの、リソース定義と実行モードを理解したうえで使えば有用。ただ、完全モードによる削除は使い方が難しい。現状ではそんな印象です。

そこで、ARM Templateをデプロイに組み込む際、ARMによるデプロイはBootstrap用途に限定し、より構成頻度が高いConfiguration用途には、冪等性を持った別のツールを組み合わせるのが現実解と考えます。

Bootstrap用途では、プラットフォームの提供機能を使ったほうが、機能も多いし最適化されています。Azureで今後この層を担当していくのはARMです。そして、この用途ではChefやAnsibleなど汎用ツールに物足りなさがあります。

また、Bootstrapは1回切りであるケースが多いので、失敗したらリソースグループをばっさり消して再作成する、と割り切りやすいです。それならば冪等でなくともいいでしょう。

長くなったので、デプロイツールの組み合わせについては、あたらめて書きたいと思います。

参考: インフラ系技術の流れ Bootstrapping/Configuration/Orchestration

19 Dec 2015, 00:01

OpenStackとAzureにDocker Swarmをかぶせてみた

どこいってもいじられる

OpenStack Advent Calendar 2015 参加作品、19夜目のエントリです。

OpenStackの最前線から離れて3か月がたちました。OpenStackつながりな方にお会いするたび、マイルドなかわいがりをうけます。ほんとうにありがとうございます。仕事としては専門でなくなりましたが、ユーザ会副会長の任期はまだ残っているので、積極的にいじられに行く所存です。でも笑いながら蹴ったりするのはやめてください。

さて、毎年参加しているOpenStack Advent Calendarですが、せっかくだからいまの専門とOpenStackを組み合わせたいと思います。ここはひとつ、OpenStackとAzureを組み合わせて何かやってみましょう。

乗るしかないこのDockerウェーブに

どうせなら注目されている技術でフュージョンしたいですね。2015年を振り返って、ビッグウェーブ感が高かったのはなんでしょう。はい、Dockerです。Dockerを使ってOpenStackとAzureを組み合わせてみます。あまり難しいことをせず、シンプルにサクッとできることを。年末ですし、「正月休みにやってみっか」というニーズにこたえます。

ところでOpenStack環境はどうやって調達しましょう。ちょっと前までは身の回りに売るほどあったのですが。探さないといけないですね。せっかくなので日本のサービスを探してみましょう。

条件はAPIを公開していること。じゃないと、Dockerの便利なツール群が使えません。Linuxが動くサービスであれば、Docker環境をしみじみ手作業で夜なべして作れなくもないですが、嫌ですよね。正月休みは修行じゃなくて餅食って酒飲みたい。安心してください、わかってます。人力主義では、せっかくサクサク使えるDockerが台無しです。

あと、当然ですが個人で気軽にオンラインで契約できることも条件です。

そうすると、ほぼ一択。Conohaです。かわいらしい座敷童の“このは”がイメージキャラのサービスです。作っているのは手練れなOSSANたちですが。

では、AzureとConohaにDocker環境をサクッと作り、どちらにもサクッと同じコンテナを作る。もちろん同じCLIから。ということをしてみようと思います。

今回大活躍するDoker Machine、Swarmの説明はしませんが、関心のある方は前佛さんの資料を参考にしてください。

ローカル環境

  • Mac OS X (El Capitan)
    • Docker Toolbox 1.9.1

ローカル、Azure、ConohaすべてのDocker環境はDocker Machineでサクッと作ります。 また、Swarmのマスタはローカルに配置します。

いざ実行

まず、Docker Machineにクラウドの諸設定を食わせます。

Azure向けにサブスクリプションIDとCertファイルの場所を指定します。詳細はここを。

$ export AZURE_SUBSCRIPTION_ID=hoge-fuga-hoge-fuga-hoge
$ export AZURE_SUBSCRIPTION_CERT=~/.ssh/yourcert.pem

Conoha向けにOpenStack関連の環境変数をセットします。

$ export OS_USERNAME=yourname
$ export OS_TENANT_NAME=yourtenantname
$ export OS_PASSWORD=yourpass
$ export OS_AUTH_URL=https://identity.tyo1.conoha.io/v2.0

次はローカルコンテナ環境を整えます。

Swarmコンテナを起動し、ディスカバリトークンを生成します。このトークンがSwarmクラスタの識別子です。

$ docker-machine create -d virtualbox local
$ eval "$(docker-machine env local)"
$ docker run swarm create    
Status: Downloaded newer image for swarm:latest
tokentokentokentoken

このトークンは控えておきましょう。

ではSwarmのマスタをローカルに作ります。先ほど生成したトークン指定を忘れずに。

$ docker-machine create -d virtualbox --swarm --swarm-master --swarm-discovery token://tokentokentokentoken head

SwarmのエージェントをAzureに作ります。VMを作って、OSとDockerをインストールして、なんて不要です。Docker Machineがやってくれます。ここでもトークン指定を忘れずに。

$ eval "$(docker-machine env head)"
$ docker-machine create -d azure --swarm --swarm-discovery token://tokentokentokentoken worker-azure01 --azure-location "East Asia" worker-azure00

Conohaにも同様に。

$ docker-machine create -d openstack --openstack-flavor-name g-1gb --openstack-image-name vmi-ubuntu-14.04-amd64 --openstack-sec-groups "default,gncs-ipv4-all" --swarm --swarm-discovery token://tokentokentokentoken worker-conoha00

さあ環境がサクッと出来上がりました。これ以降はSwarmクラスタ全体を操作対象にします。

$ eval "$(docker-machine env --swarm head)"

環境をチラ見してみましょう。

$ docker info
Containers: 4
Images: 3
 Role: primary
 Strategy: spread
 Filters: health, port, dependency, affinity, constraint
 Nodes: 3
 head: 192.168.99.101:2376
  └ Containers: 2
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=4.1.13-boot2docker, operatingsystem=Boot2Docker 1.9.1 (TCL 6.4.1); master : cef800b - Fri Dec 18 19:33:59 UTC 2015, provider=virtualbox, storagedriver=aufs
 worker-azure00: xxx.cloudapp.net:2376
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.721 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.13.0-36-generic, operatingsystem=Ubuntu 14.04.1 LTS, provider=azure, storagedriver=aufs
 worker-conoha00: www.xxx.yyy.zzz:2376
  └ Containers: 1
  └ Reserved CPUs: 0 / 2
  └ Reserved Memory: 0 B / 1.019 GiB
  └ Labels: executiondriver=native-0.2, kernelversion=3.16.0-51-generic, operatingsystem=Ubuntu 14.04.3 LTS, provider=openstack, storagedriver=aufs
CPUs: 4
Total Memory: 3.761 GiB
Name: 1234abcd

どこにどんな環境が作られたかが分かりますね。出力結果の4行目”Strategy: spread”を覚えておいてください。

ではコンテナを作ってみましょう。Nginxコンテナ三連星です。どの環境に作るか、という指定はしません。

$ for i in `seq 1 3`; do docker run -d -p 80:80 nginx; done

どんな具合でしょう。

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                NAMES
9cc2f5594fa5        nginx               "nginx -g 'daemon off"   5 seconds ago       Up 4 seconds        192.168.99.101:80->80/tcp, 443/tcp   head/goofy_goldberg
b9d54d794a85        nginx               "nginx -g 'daemon off"   32 seconds ago      Up 31 seconds       www.xxx.yyy.zzz:80->80/tcp, 443/tcp   worker-conoha00/clever_chandrasekhar
19e9d0e229a2        nginx               "nginx -g 'daemon off"   45 seconds ago      Up 42 seconds       zzz.yyy.xxx.www:80->80/tcp, 443/tcp    worker-azure00/reverent_bhaskara

Nginxコンテナがきれいに散らばっているのが分かります。これは先ほど覚えた”Strategy: spread”が効いているからです。StrategyはSwarmのコンテナ配置ポリシーで、speradを指定すると散らしにいきます。Strategyをbinpackにしておけば、ノードを埋めようとします。埋まったら他、です。randomであれば、ランダムに。

まだシンプルですが、今後このStrategyやリソース管理が賢くなると、「ローカルが埋まったら、リモートを使う」とか、使い道が広がりそうですね。最近Docker社が買収したTutumとの関係、今後どう進化していくのか、注目です。

ツールから入るハイブリッドクラウドも、またよし

ハイブリッドクラウドはまだ言葉先行です。まだクラウドを使ってない、使いこなしていない段階でツールの話だけが先行することも多いです。ナイフとフォークしか使ったことのない人が、お箸を使う和食や中華を選ぶ前に「どんなお箸がいいかねぇ」と議論している感じ。僕は、そうじゃなくて、その前に食べたいもの = クラウドを選びましょうよ、というスタンスでした。

でも、コンテナ+Dockerって、お箸に弁当ついてきたような感じなんですよね。お箸が使える人であれば、弁当持ち込める場所さえ確保すればいい。インパクトでかいです。ちょっと考えを改めました。

もちろん、だからクラウドは何でもいい、と言っているわけではありません。弁当持ち込みとしても、スペースが広い、個室で静か、お茶がうまい、お茶がタダ、揚げたてのから揚げを出してくれる、などなど、特徴は出てくるでしょう。APIを公開していないような「持ち込みやめて」のクラウドは、先々心配ですが。

簡単 = 正義です。簡単であれば使う人が増えて、要望が増えて、育ちます。かっちり感は後からついてくる。もしDockerで複数のクラウド環境を簡単に使いこなせるようになるのであれば、順番が逆ではありますが、お箸、Dockerというツールから入るのもいいかもしれません。

まずは開発、検証環境など、リスク低いところから試して慣れていくのがおすすめです。触っていくうちに、いろいろ見えてくるでしょう。Dockerはもちろんですが、それぞれのクラウドの特徴も。

OpenStackもAzureも、特徴を活かし、うまく使いこなしてほしいと思っております。

05 Nov 2015, 15:40

Azure Docker VM Extensionを使う3つの理由

まずはじめに

先月からMicrosoftで働いてます。Azure担当のソリューションアーキテクトになりました。これからAzureネタが増えると思いますが、ひとつよろしくお願いします。Microsoftテクノロジーとオープンソースの間あたりを、積極的にこすっていく所存です。

もちろん、技術者個人として、中立的に、公開できるネタを書きます。

AzureはMicrosoftテクノロジーとオープンソースの交差点です。できないと思っていたことが、実はできたりします。いまだに「AzureでLinux動くのね、知らなかった」と言われたり。また、その逆もしかり。SDKが色々あるからできると思っていたら、制約があった、とか。

なので、小ネタであっても、実践的な情報には価値があります。今後、公式ドキュメントでカバーされなかったり、細かすぎて伝わりづらいなことを、書いていこうかと。

Azure Docker VM Extension を使う3つの理由

さて、今回は話題沸騰のDocker関連のネタ、Azure Docker VM Extensionについて。名前通り、Azure上でDockerをのせたVMを動かすときに便利な拡張機能です。

このDocker VM Extension、AzureのARMテンプレートによく登場します。なんとなくおすすめっぽいです。ですが「自分でDockerをインストールするのと何が違うのよ」という疑問も、あるかと思います。実際、よく聞かれます。

ずばり、答えはGithubのREADMEにまとまっています。この拡張機能のうれしさは、

  1. Docker EngineのStable最新版をインストールしてくれる
  2. Docker デーモンの起動オプションや認証まわりを設定できる (オプション)
    • ポートマッピング、認証まわり、Docker Registoryサーバの定義など
  3. Docker Composeのパラメータを渡すことができる (オプション)

以上です。2と3はJSONで記述できます。要するに、毎度山ほどオプションつけてdockerコマンド打つよりは、宣言的にDockerを楽に使えますよ、ということです。必須ではありません。また、山ほどあるDockerのオプションを隅々まで網羅しているわけではありません。カバー範囲は基本的なところです。

Dockerの環境構築、はじめはコマンドを打つことをおすすめします。オプションがいろいろあるので、その中身を理解することには意味があります。

ですが、一度理解したあとは、かったるいことこの上ないので、この手のツールはあったほうがいいですね。

Dockerは本家のみならずエコシステムも急激に変化しているので、まだ環境構築ツールのファイナルアンサーはないでしょう。どれを学ぶか悩ましいところです。ですが、この拡張は気軽に使えますし、依存性も低いので、おすすめです。

なお、このDocker拡張、ARM属性で言うpublisherは”Microsoft.Azure.Extensions”ですが、古い”MSOpenTech.Extensions”を指定しているARMテンプレートがまだあったりします。拡張のインストール時に「そんなのねぇよ」と怒られたら、疑ってみてください。伝統を重んじるUSのリージョンでは動いて、Japanで動かないテンプレートでは、MSOpenTechが指定されているかもしれません。