しばやん雑記

Azure とメイドさんが大好きなフリーランスのプログラマーのブログ

Azure B-Series VM の挙動と CPU クレジットの仕様を確認する

Azure サポートに B-Series の core 申請を投げていたのが通ったので、前回の続きとして実際に B-Series VM を作成して調べてみることにします。

基本的な B-Series と t2 に関する違いは前回のエントリを見てください。

まずは個人的に AWS でよく使っている t2.small と同じサイズの B1ms の VM を作ります。

f:id:shiba-yan:20170916010720p:plain

プレビュー中ですが、1 時間当たりの金額はかなり安いです。コスパが非常に高いです。

f:id:shiba-yan:20170916010806p:plain

作成した B-Series VM の CPU クレジットは Azure Monitor から 1 分間隔で確認できるようになっていました。CloudWatch は 5 分だった気がするので、Azure のが少し細かいですね。

CPU クレジットとは

まだ Azure の公式ドキュメントには CPU クレジットについては言及がないので、AWS t2 インスタンスの方を読んだ方がいいかも知れません。考え方はほぼ同じになっているはずです。

CPU クレジットとは何ですか。

1 個の CPU クレジットは、1 台の vCPU を使用率 100% で 1 分間実行することに相当します。たとえば、1 台の vCPU を使用率 50% で 2 分間実行したり、2 台の vCPU を使用率 25% で 2 分間実行したりなど、他の vCPU、使用率、時間の組み合わせでも、1 個の CPU クレジットに相当します。

T2 インスタンス - Amazon Elastic Compute Cloud

t2 と同じように複数の vCPU がある場合には少し計算が分かりにくいかも知れません。

バーストと CPU クレジットの使用

B1ms はベースラインパフォーマンスが 20% ですが、CPU クレジットが残っている場合には 100% まで利用することが出来ます。実際に負荷を掛けてみると 100% まで問題なく使われます。

f:id:shiba-yan:20170916013408p:plain

Azure Monitor で CPU クレジットを確認すると、CPU クレジットが消費されていることが分かります。

f:id:shiba-yan:20170916014301p:plain

何故か 1 vCPU を 100% 使用しても、CPU クレジットは 0.5 しか消費されませんでした。これは B-Series の不具合っぽいので、質問を投げていますがよくわかりません。追記:直ってました。

ちなみに Azure Monitor 上は CPU 使用率も 50% になっていました。明らかにおかしいですね。

ベースラインパフォーマンスの確認

今は CPU クレジットの消費が何故か半分になっているので、なかなか CPU クレジットを消費しきれませんでしたが、数時間かけて何とかクレジットを使い切ることが出来ました。

f:id:shiba-yan:20170916230819p:plain

しかし、CPU クレジットが完全に 0 になることはありませんでした。

そしてベースラインパフォーマンスにまで落とされていても、タスクマネージャー上は 100% のままになります。正しい値を読み取るには Azure Monitor から参照する必要があります。

f:id:shiba-yan:20170916231514p:plain

ベースラインパフォーマンスが 20% とはいえ、ハイパーバイザによって 20% きっちりに上限が設定されるわけではないみたいです。平均値が 20% になるように調整されているように見えます。

とはいえ、Azure Monitor の値に不安があるので再検証が必要な気もします。

VM の再起動と CPU クレジット

t2 インスタンスは VM を再起動すると貯まっていた CPU クレジットが初期化されるようになってますが、Azure B-Series でも同様の挙動となっています。

たまたま何故かインスタンスが再起動した結果、Azure Monitor の値にその痕跡がありました。

f:id:shiba-yan:20170916023045p:plain

CPU クレジットが 30 を下回っていましたが、再起動後には 30 に戻っていることが分かります。この挙動を知らないと不具合かと思ってしまいそうですが、多分これは意図した動作です。

f:id:shiba-yan:20170916210456p:plain

逆に CPU クレジットが初期クレジット以上に貯まっていても、再起動で初期化されています。

インスタンスサイズと初期 CPU クレジット

Azure のドキュメントには初期 CPU クレジットが記載されておらず、Twitter ではいろいろと話が飛び交ってましたが、実際に別のインスタンスサイズで作って確認します。

申請時に 8 cores しか要求しなかったので、仕方なく Standard B4ms を作りました。

f:id:shiba-yan:20170916203152p:plain

4 vCPU と 16GB メモリの仮想マシンがプレビュー中は 7000 円程、GA になっても 14000 円程で使えるのは非常に嬉しいですね。本当にもう A-Series VM は要らないです。

Azure Monitor で確認すると、120 CPU クレジットが与えられていました。つまり 1 vCPU あたり 30 CPU クレジットが予め与えられるようです。

f:id:shiba-yan:20170916203300p:plain

このあたりの仕様も AWS の t2 インスタンスと同じようなので、ある意味予想通りという感じです。

気になる部分については確認しましたが、バースト周りの仕様については t2 と同じようです。ただし Azure B-Series はストレージパフォーマンスにも言及されてるので、そこは注意したいです。

追記:CPU クレジットの消費が直ってました

起動したまま放置していた 1 vCPU を持った B-Series インスタンスがあったので、久し振りに負荷を目いっぱいかけてみたところ、正しく CPU クレジットが消費されるようになっていました。

以前は CPU 使用率が 100% であっても、CPU クレジットは 0.5 しか消費されていませんでしたが、今は正しくほぼ 1 が消費されていることが確認できます。

f:id:shiba-yan:20171016183436p:plain

これまでは 0.5 CPU クレジットしか消費されなかったので、ある意味お得ではあったのですが、ちゃんと Azure Monitor で正しい値が確認出来るようになって良かったです。

バースト可能な Azure B-Series と AWS t2 インスタンスを比較する

前に Burstable なインスタンスが予告されてましたが、プレビューでリリースされたようです。

大体の Web サーバーや開発用インスタンスでは常に高い CPU パフォーマンスが必要なわけではないので、便利に使えるはずです。実際に AWS では t2 を検証などでよく使っています。

まだ利用可能なリージョンは少ない上に、クオータの申請をしないと使えないのでまだ試せてないのですが、明らかに AWS の t2 インスタンスを意識したものだと分かりますね。

実際に起動可能になるまで時間がかかりそうなので、まずはドキュメントレベルで比較してみます。Azure と AWS それぞれのドキュメントは以下の通り。

結論を先に書くと B-Series の仕様は t2 インスタンスとほぼ同じのようです。

CPU クレジットという概念があり、1 時間ごとにインスタンスのサイズによって貯まる量が決まり、クレジット自体の上限値もある。という形です。初期クレジットが Azure は記載されてませんでした。

f:id:shiba-yan:20170913012023p:plain

f:id:shiba-yan:20170913011938p:plain

Azure の B-Series はストレージのパフォーマンスが、インスタンスサイズに左右されるようですが、AWS 側は特に書かれていません。NIC の帯域の問題だと思うので、実際に計れば同じぐらいなのかもしれませんが。

とりあえず Azure B-Series と AWS t2 インスタンスの対応関係は以下の通りです。t2.nano に相当する B-Series は用意されてないですが、0.5GB メモリは流石にしんどそうなのでまあいいかなと思います。

Azure B-Series AWS t2 インスタンス
1 vCPU / 0.5GB 該当なし t2.nano
1 vCPU / 1GB Standard_B1s t2.micro
1 vCPU / 2GB Standard_B1ms t2.small
2 vCPU / 4GB Standard_B2s t2.medium
2 vCPU / 8GB Standard_B2ms t2.large
4 vCPU / 16GB Standard_B4ms t2.xlarge
8 vCPU / 32GB Standard_B8ms t2.2xlarge

Azure の方は名前が分かりにくいのはこれまで通りという感じですね。きっちり t2 に合わせてきてます。

大きな仕様としては変わりないですが、細かい部分を見ていくと違いが出てきました。気になるのは使われる CPU の種類が Azure は型番まで明記されているところで、Haswell ベースの Xeon が使われるようです。

  • Azure
    • Intel® Haswell 2.4 GHz E5-2673 v3 processors or better
  • AWS
    • 高速な Intel Xeon プロセッサ

AWS は既にリリースされてから期間が経ってるので、リージョンなどでいろんな CPU が選ばれるようになっているみたいです。なので Xeon としか書かれていませんでした。

気になる金額ですが、Azure はプレビュー中なので勿論 50% 引きになってますが、GA した時は Linux / Windows の両方とも t2 インスタンスと同じ価格になるようです。

f:id:shiba-yan:20170913014432p:plain

個人的には B-Series が GA になったタイミングで A / Av2 はお役御免という感じがします。

コストパフォーマンスは A / Av2 は B に勝てる気がしないのと、元々 A / Av2 はテスト利用前提みたいな触れ込みなので、B を使った方がコスト圧縮と高パフォーマンスを実現出来そうです。

B-Series が作れるようになったら、もうちょっと詳細に調べてみようと思います。

App Service on Linux と Web App for Containers が GA したらしい

発表も突然なら GA も突然な App Service on Linux です。てっきり Ignite 合わせかと思っていましたが、特に何かあるタイミングではない今日に発表とは驚きました。

とはいえ、何か機能が追加されたわけではなく GA したという発表だけのようです。

同時に謎めく Web App for Containers というサービスが発表されています。

最近追加された App Service on Linux の機能は以前まとめたので、そっちを見てもらえればよいかと思います。内容的にそろそろ GA は近いかなと思っていましたが、予想より早かったです。

App Service on Linux に関してはちょっと前にフォーラムでバグ報告していたので、それが直っているか確認する作業が必要になりました。直っているといいなと思います。

Web App for Containers

突然出てきた Web App for Containers ですが、名前だけ聞くと Windows Containers にも対応したのかなと思いましたが、Linux のみの対応となります。というか、中身は App Service on Linux です。

では何故わざわざ名前を変えてリリースされたかですが、App Service on Linux に対しては大きく分けて 2 つの機能を期待する人が存在するからでしょう。

1 つは Windows の App Service と同じように GitHub や FTP を使ったアプリケーションのデプロイが行えて、Linux で動作する環境。もう 1 つは Docker Image を指定するだけで Web アプリケーションとして実行してくれる環境です。

Azure Portal から作成する時に Web App for Containers は Built-in Runtime Stack を選べなくなっています。その代わり Docker Image は必ず指定する必要があります。

f:id:shiba-yan:20170907013754p:plain

Web App for Containers として作成した場合は Deployment options は選べないようになっているので、GitHub や BitBucket からのデプロイは設定できないようになっています。

なので Azure Blog に書いてあった通り、CI/CD に関しては Azure Container Registry や Docker Hub を使った自動デプロイか、Azure CLI からアップデートする方法を選ぶことになります。

f:id:shiba-yan:20170907015522p:plain

ちなみに Application settings を見ると面白い設定値が追加されていました。このキーの有無が App Service on Linux と Web App for Containers の切り替えを行っている気がします。

f:id:shiba-yan:20170907013804p:plain

このキーを false にすると /home/site が自動でボリュームとしてマウントされなくなりそうなので、SSH で接続して確認してみたところ、予想通りマウントされていなかったです。

個人的には Web App for Containers で Windows が使えるようになって欲しいです。

App Service on Linux に関する最近のアップデートなど

最近は忙しかったのと Windows Containers ばかり弄っていたので遠ざかってましたが、そろそろ App Service on Linux は GA が近くなってきた気がしますね。リージョンは毎週のように増えていますし。

というわけで個人的なまとめを少しだけ。気になる部分は試していくことにしています。

Japan West が追加

7 月には Japan East が追加されましたが、ちょっと前に Japan West でも使えるようになりました。

f:id:shiba-yan:20170828135148p:plain

新しめのサブスクリプションでは Japan West に作れない気がしますが、何はともあれ App Service on Linux は Japan East / West の両方で使えるようになっています。

本社からの日本への期待が高いということなのかもしれません。

Node 8.0 / 8.1 がサポート

カスタム Docker Image を使っている場合には関係ないですが、標準のランタイムスタックで Node 8.0 と 8.1 に対応していました。GitHub を使った CI / CD で簡単に使えるはずです。

f:id:shiba-yan:20170828140325p:plain

.NET Core 2.0 のサポートはまだのようですが、こっちもそのうち対応するのではと思います。

Docker のログが大幅に改善

これまで App Service on Linux で致命的だと思っていた Docker ログの確認が非常に難しいという問題が、ついに解消していました。ファイル名は日付 + マシン名となっていて、スケールアウト時にも安心。

f:id:shiba-yan:20170828140656p:plain

欲を言えばディレクトリを切って欲しいとか、Azure Storage への転送が欲しいとかありますが、そのうち対応してくれればいいかなという気持ちです。

ログにはタイムスタンプが付いているので、トラブルシューティングが格段に行いやすくなりました。

f:id:shiba-yan:20170828140615p:plain

何気に docker run のコマンドも出力されているので、挙動を調べるのにも便利です。

そして Docker Container のログ出力にもいつの間にか対応していたみたいです。

Azure Portal を見ると確かに設定が増えているので有効にすると、アプリケーションが標準出力に書き出している情報も、上のログファイルに出力されるようになりました。

f:id:shiba-yan:20170828140508p:plain

ただし、現状は一度有効にすると無効に出来ないみたいなので、フォーラムで問合せしています。

Azure Container Registry との連携強化

これまでも Docker Hub からの CD には対応していましたが、Azure Container Registry とも CD 出来るように強化されています。Azure サービスとの連携は強化していってほしいです。

Container Registry を選ぶと、自動的に格納されているイメージやタグがドロップダウンリストで表示されるので、かなり設定が行いやすいです。なお ACR の Admin は有効化必須です。

f:id:shiba-yan:20170828140858p:plain

CD を試してみましたが、思ったような挙動にならなかったので、これもまたフォーラムで聞いています。解決策が分かればブログでまたまとめてみようかと思います。

久し振りに触ってみた感じとしてはインフラ周りの挙動は大幅に安定していました。早く仕事で使いたい。

ACS Engine を使って Dv3 インスタンスベースの Kubernetes クラスタを作成する

Azure Portal から Azure Container Service を作ろうとすると Dv2 までしかインスタンスが選べないので、新しい Nested Virtualization に対応した Dv3 を使ってクラスタを作ることは出来ませんが、ACS Engine を使うと作成することが出来ます。

ACS Engine は ARM Template を作成するだけなので、ACS の制限とは無縁です。

セットアップは README などに書いてある通りなので省略します。前までは Azure Cloud Shell にインストール出来ましたが、最近のバージョンでは Go 1.8 が必要らしく手間がかかりそうです。

基本的に Windows ベースの Kubernetes しか作る気がないので、ACS Engine のリポジトリに用意されている Windows 向けのサンプルを修正して、D2 v3 を使うようにします。

"agentPoolProfiles": [
  {
    "name": "windowspool",
    "count": 2,
    "vmSize": "Standard_D2_v3",
    "availabilityProfile": "AvailabilitySet",
    "osType": "Windows"
  }
]

修正したサンプルから ACS Engine を使って ARM Template を作成し、リソースグループにデプロイを行うだけで Dv3 ベースの Kubernetes が完成します。

あまり関係ないですが、Managed Disk を使って VM が作成されていました。課金に注意ですね。

f:id:shiba-yan:20170817230128p:plain

作成された VM を確認すると、指定通り D2 v3 なインスタンスとなっています。Hyper Threading なインスタンスなので、コンテナを多く立ち上げる場合には少し不安があります。

f:id:shiba-yan:20170817225611p:plain

これで Hyper-V Containers が利用可能な Windows Server と Kubernetes な環境が手に入りました。

既に Kubernetes は Windows Server Containers と Hyper-V Containers に対応していると発表されています。

Support for Both Windows Server Containers and Hyper-V Containers - There are two types of containers in Windows Server 2016. Windows Containers is similar to Docker containers on Linux, and uses kernel sharing. The other, called Hyper-V Containers, is more lightweight than a virtual machine while at the same time offering greater isolation, its own copy of the kernel, and direct memory assignment. Kubernetes can orchestrate both these types of containers. 

対応していると発表されてはいますが、軽く調べた限りでは Hyper-V Containers を利用する方法は分かりませんでした。まともに Windows Containers を使う場合には Hyper-V が必要なので、何とかしたいところです。

Hyper-V Containers で実行する方法が分かれば続きを書く予定です。

App Service Premium V2 が Public Preview になった

あまりアップデートが無かった App Service 周りですが、ここ数日で一気にインフラ周りにアップデートがあって色々と見るのが大変です。割高感しかなかった Premium がついに改善です。

Premium V2 自体は App Service Environment で使える Isolated と同じインスタンスタイプです。具体的には D1-3 v2 が使われるようになりました。

現在利用可能なリージョンは South Central US / West Europe / North Europe / Australia East / Australia Southeast の 5 つだけです。EU と Australia は Premium ユーザーが多かったのかもしれないです。

検証のために、日本から比較的近そうな South Central US を使うことにしました。

f:id:shiba-yan:20170731163932p:plain

ちなみに気になる価格ですが、ぶちぞう RD 曰く Preview 中でも値引きされていないのではないかという話でした。なので GA 後もこれまでの Premium と同じ価格で Premium V2 が使えるかもしれません。

確かに価格に関しては 50% 引きになっているという記載はありませんでした。

GA 済みの Isolated より高くなることはないと思うので、多分このままの価格で行くのだと思います。

パフォーマンスを検証

CPU に関してはこれまでの A シリーズから Dv2 にアップグレードされているので、ACU 換算で倍にはなっているはずです。ちなみにリージョンによっては Premium と Premium V2 で同じ CPU が使われています。

使われているのは Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz です。Azure で一番使われています。メモリも Premium と比べて 2 倍になっているので、これまでよりもバランスの良い構成になりました。

さて、App Service の最大の弱点としてストレージのパフォーマンスが悪いことがありました。

Premium V2 になっても共有ストレージのパフォーマンスは原理上変わらないはずですが、キャッシュなどで使われるストレージは Dv2 化の恩恵を受けているはずなので簡単に確認しました。

念のために Standard / Premium / Premium V2 の 3 環境でパフォーマンスを確認しました。

Standard

D:\local\Temp>StorageBenchmark.exe 1000 0
WriteFile : 929ms
ReadFile : 265ms
DeleteFile : 392ms

D:\local\Temp>StorageBenchmark.exe 1000 512
WriteFile : 1088ms
ReadFile : 245ms
DeleteFile : 326ms

Premium

D:\local\Temp>StorageBenchmark.exe 1000 0
WriteFile : 1120ms
ReadFile : 252ms
DeleteFile : 377ms

D:\local\Temp>StorageBenchmark.exe 1000 512
WriteFile : 1053ms
ReadFile : 221ms
DeleteFile : 516ms

Premium V2

D:\local\Temp>StorageBenchmark.exe 1000 0
WriteFile : 304ms
ReadFile : 102ms
DeleteFile : 169ms

D:\local\Temp>StorageBenchmark.exe 1000 512
WriteFile : 433ms
ReadFile : 95ms
DeleteFile : 140ms

Standard / Premium はハードウェアは全く同じなので、基本的に性能に差は出ないはずです。Premium V2 は他の 2 つに比べると 2-3 倍はストレージのパフォーマンスが改善しているようです。

ストレージのパフォーマンスが改善したと言っても共有ストレージには影響なさそうですが、最近の App Service では Dynamic Cache がデフォルトで有効化されるようなので効果があります。

同様にローカルストレージにファイルをキャッシュする Local Cache を使った場合にも効果があると思います。とは言え、大半のケースでは Dynamic Cache だけで有効だと思いますが。

Azure Container Instances の裏側を少しだけ覗いてみる

Azure Container Instances に sshd を有効化したイメージをデプロイすると、当然ながら ssh で接続出来るのでコンテナに関するいろいろな情報を収集できます。

とりあえず気になるインスタンスの情報について調べます。まずは CPU 周りから。

f:id:shiba-yan:20170731150030p:plain

Intel(R) Xeon(R) CPU E5-2673 v3 @ 2.40GHz が使われています。Haswell 世代のようです。ちなみに CPU コアのリクエスト数を 1 つにしても 4 つのコアが見えていました。

この時点ではまだ Dv3 なのか Dv2 の判別は付かないので、ぶちぞう RD に聞いてみました。

てっきりインスタンスメタデータはまだプレビューかと思っていたら、普通に使えるようになっていました。流石世界のぶちぞう RD、レドモンド行き待ったなし。

コンテナから実際にメタデータを取得してみると、いろんなことが分かりました。最初に分かることは、少なくとも Linux の場合は Hyper-V Containers を使った分離は行われていないということです。*1

インスタンスも予想された Dv3 / Ev3 ではなく Standard_D3_v2 でした。

{
  "compute": {
    "location": "westus",
    "name": "k8s-agentpool3-a02wus0l-4",
    "offer": "UbuntuServer",
    "osType": "Linux",
    "platformFaultDomain": "0",
    "platformUpdateDomain": "2",
    "publisher": "Canonical",
    "sku": "16.04-LTS",
    "version": "16.04.201706191",
    "vmId": "1901479c-26b8-42ac-92d8-81015daa970b",
    "vmSize": "Standard_D3_v2"
  },
  "network": {
    "interface": [
      {
        "ipv4": {
          "ipAddress": [
            {
              "privateIpAddress": "10.240.0.234",
              "publicIpAddress": ""
            }
          ],
          "subnet": [
            {
              "address": "10.240.0.0",
              "prefix": "16"
            }
          ]
        },
        "ipv6": {
          "ipAddress": []
        },
        "macAddress": "000D3A33B315"
      }
    ]
  }
}

ホスト OS が Linux になっているので、普通に Linux と Docker の組み合わせで ACI は作られているようです。そして実際に裏側でコンテナのオーケストレーションを行っているのは Kubernetes のようです。

3 行でまとめると以下のようになりました。

  • ACI の裏側は Ubuntu + Kubernetes が使われている
  • インスタンスは Nested Virtualization に非対応の Dv2
  • Hyper-V Containers は当然ながら使われていない

Cloud Native Computing Foundation にプラチナメンバーとして参加した理由もわかる結果となりました。Windows に関してはイメージを作る手間がかかるので、また今度試してみることにします。

*1:Hypervisor レベルでの分離というのが嘘っぽく感じる気が…

Azure Container Instances を Kubernetes の仮想ノードとして利用できる aci-connector-k8s を試してみた

Azure Container Instances は単体ではオーケストレーターが提供されてないですが、実験的に Kubernetes と連携して利用できる aci-connector-k8s が同時にリリースされています。

GitHub でソースコードが、Docker Hub でビルド済みイメージが公開されています。

https://github.com/Azure/aci-connector-k8s

利用するためにはサービスプリンシパルと Container Instances が実際にデプロイされるリソースグループが必要なので、予め Azure CLI などを使って作っておきます。

Cloud Shell で作るのが手っ取り早いかと思います。

公式に Docker Hub で提供されているイメージは、最新版の Resource Provider に対応していないようなので、そのままデプロイしてしまうと aci-connector-k8s でエラーになってしまいます。

仕方ないのでサクッと対応コードを書いて Docker Hub にプッシュしておきました。

https://hub.docker.com/r/shibayan/aci-connector-k8s/

サンプルにある YAML のイメージを変更するだけで使えます。Pull Request を送っているので、ひょっとしたら取り込まれて公式対応されるかもしれません。とりあえずの対応です。

他には作成しておいたサービスプリンシパルやリソースグループの名前などセットします。

apiVersion: v1
kind: Pod
metadata:
  name: aci-connector
  namespace: default
spec:
  containers:
  - name: aci-connector
    image: shibayan/aci-connector-k8s:latest
    imagePullPolicy: Always
    env:
      - name: AZURE_CLIENT_ID
        value: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      - name: AZURE_CLIENT_KEY
        value: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      - name: AZURE_TENANT_ID
        value: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      - name: AZURE_SUBSCRIPTION_ID
        value: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
      - name: ACI_RESOURCE_GROUP
        value: YOURRESOURCEGROUP-NAME
  nodeSelector:
    beta.kubernetes.io/os: linux

nodeSelector は私が持っている Kubernetes クラスタが Windows なので指定しています。Linux のみの Kubernetes クラスタの場合は指定する必要はないはずです。

ダッシュボードからデプロイしてしばらく待つと、ノードに aci-connector が現れます。

f:id:shiba-yan:20170728004344p:plain

このノードに対するコンテナ起動リクエストは Azure Container Instances が透過的に使われるようになります。今後 Container Instances にネイティブ対応したオーケストレーターが出てくると楽しそうです。

実際に aci-connector に対してデプロイを行ってみます。これもサンプルの通りです。

apiVersion: v1
kind: Pod
metadata:
  name: nginx-aci
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    imagePullPolicy: Always
    name: nginx-aci
  dnsPolicy: ClusterFirst
  nodeName: aci-connector

nodeName として aci-connector を明示的に指定しているので注意です。

デプロイすると一瞬で新しい Pod が立ち上がり、パブリック IP アドレスも割り当てられます。

f:id:shiba-yan:20170728004613p:plain

パブリック IP アドレスにアクセスすると、Nginx が確かに立ち上がっていることが簡単に確認できます。

Kubernetes クラスタ内に Pod を作成する時よりも、コンテナの起動が早い気がします。

f:id:shiba-yan:20170728005721p:plain

Kubernetes の知識が少しあれば、バックエンドが Azure Container Instances かどうか全く意識することなく使うことが出来ました。リソース管理も不要ですし、これはかなり便利ですね。

ただし Kubernetes のマスターノードは作っておく必要があるので、Azure Container Services が管理された Kubernetes マスターを提供してくれたら最高です。

Azure Container Instances は Hypervisor レベルでの分離を備えた次世代のコンテナ実行環境

ASE v2 について書いたし、そろそろぶちぞう RD に後のことを任せて寝るかと思っていたら、突然 Azure Container Instances という新しいサービスが発表されました。コンテナと聞いたら寝るわけにはいかないので、例によって興味のある部分だけサクッと試しました。

まずは公式情報がいろいろと出てきているので、しっかりと目を通しておくべきです。要約すると Azure Container Instances こそ真の Container as a Service ということです。

ASE v2 よりもドキュメントが充実している気がします。しっかりと Linux と Windows に対応していますし、コンテナ間の分離にはハイパーバイザが使われているともあります。

要するに Hyper-V Container が使われているということでしょう。

何はともあれ触ってみたいという人は、Azure Cloud Shell に Container Instances 対応の Azure CLI 2.0 がインストールされているので、そこから簡単に試せます。Quick Start を読めば誰でも作れます。

一応 Azure Portal からも作れるようになってるみたいです。

そして気になる課金ですが、コンテナ作成リクエストと秒単位の課金で CPU コア数、そしてメモリ量によって決まります。ガンガン使ってガンガン捨てるような運用が容易です。

Pricing - Container Instances | Microsoft Azure

そして一番重要なポイントとしては Hyper-V Containers がおそらく使われているので、Windows Server Containers の面倒な制約を受けることなく、安全に Windows Containers を使うことが出来ることです。

まさに Windows Containers の実運用に必要なサービスが出てきたと感動しています。これからは ASP.NET アプリケーションも Dockernize して動かす時代になる、と思っています。

Azure Container Instances の特徴

最近は Windows Containers のクラスタ周りで苦しんでいたので、思いを書きすぎました。Azure Container Instances の何が素晴らしいのか、もうちょっと具体的に書きます。

  • クラスタレス
  • 高速なコンテナの起動
  • 秒単位での課金
  • ハイパーバイザで分離された実行環境
  • CPU / メモリの柔軟な割り当て
  • Linux / Windows に対応

どれを取っても最高ですね。要するに Hyper.sh と直接競合するサービスだと思います。

これまで Function as a Service が Serverless だと良く言われてきましたが、実際にホストするサーバーを全く意識することなく使える Container Instances や Hyper.sh こそが Serverless だと私は思っています。

喋りすぎなので、実際に Container Instances を使って Windows Server Core で動作する ASP.NET アプリケーションをデプロイしてみます。

Container を作成する

Cloud Shell とビルド済みのイメージがあれば、1 コマンドを実行するだけでデプロイ可能です。注意するポイントは --os-type で Windows を指定することです。

使用する Docker Image は AppVeyor を使って自動ビルドを行っている ASP.NET MVC アプリケーションです。本当に Windows Containers に欠けていたものは実行環境だけでした。

az container create -g ContainerInstance-RG --name aspnetapp --location westus \
    --image shibayan/appveyor-aspnet-docker:master-19 --ip-address public --os-type Windows

外部からアクセスするように IP アドレスは公開を指定して実行しました。

すると以下のエラーが表示されてしまいました。エラーメッセージを読むと Windows の場合には最低でも 2 コアと 3.5GB メモリを指定する必要があるらしいです。

The resource requirments '{"requests":{"memoryInGB":1.5,"cpu":1.0}}' is invalid. Windows containers can only request 2 CPU and 3.5GB memory.

なので --cpu と --memory を追加してコマンドの実行をやり直します。

az container create -g ContainerInstance-RG --name aspnetapp --location westus \
    --image shibayan/appveyor-aspnet-docker:master-19 --ip-address public --os-type Windows --cpu 2 --memory 3.5

今度はすんなりと上手くいって、すぐに確保された IP アドレスを含む情報が表示されました。

f:id:shiba-yan:20170727005212p:plain

まだこの時はコンテナの作成中なので IP アドレスにアクセスしても何も返ってきません。作成が完了したかを知るためには別のコマンドを使います。

Container Status を確認

作成リクエストを投げたコンテナの状態を知るためには container show コマンドを使います。名前とリソースグループ名を指定するだけの、非常に簡単なコマンドです。

az container show -n aspnetapp -g ContainerInstance-RG

実行するとステータスなどを含む JSON が表示されるので、ProvisioningState の値が Succeeded になっていることを確認すれば OK です。

f:id:shiba-yan:20170727014318p:plain

このコマンドの実行結果には docker 周りのイベントログも出てるので、以下のようなクエリを使うと簡単に見ることが出来ます。

az container show -n aspnetapp -g ContainerInstance-RG --query "containers[0].instanceView.events"

docker pull などに、どのくらい時間がかかっているかを簡単に把握できます。

f:id:shiba-yan:20170727005949p:plain

関係ないですが、同じ Docker を使った App Service on Linux は簡単にログを確認する方法が用意されていないので、GA までには Azure Portal から確認できるような機能が欲しいと思ってますし、要望もしてます。

Public IP にアクセス

コンテナの作成が完了後に Public IP にブラウザからアクセスすると、少し後に見慣れた ASP.NET MVC アプリケーションのページが表示されました。

手順としてはコマンドを 2 回打ち込んだだけです。本当にたったこれだけで ASP.NET アプリが動いてます。

f:id:shiba-yan:20170727010055p:plain

非常に簡単にコンテナのデプロイが行えるので、Azure Container Service を使ってクラスタから作成していた部分を全てスキップして、アプリケーションの開発をデプロイのみに集中することが出来そうです。

ただし実際に本番、運用環境で使う場合にはオーケストレーターが必要となります。何故なら作成したコンテナはイミュータブルであり、後からイメージのアップデートなどは出来ないからです。

オーケストレーションについて

Azure Container Instances 自体は Swarm や Kubernetes のようなオーケストレーション機能は持っておらず、非常に低レベルなコンテナを実行することに特化したサービスとなっています。

サンプルとして用意されている aci-connector を使うと、Kubernetes と Container Instances をシームレスに統合することが出来るようです。

個人的な認識としては Container Instances はコンテナ版 Cloud Services に近いかなと思います。各サービスの土台となるようなサービスという印象です。

まだプレビューリリースされたばかりの新しいサービスですが、今後の Microsoft と Azure が本気でコンテナに注力していることが分かりますね。私は Azure 最高の素晴らしいサービスだと思います。

App Service Environment v2 がリリースされたので v1 からの変更点を調べてみた

最近はあまり ASE について興味を持っていなかったのですが、今朝 ASE v2 がリリースされたと聞いたので v1 との違いに注目して調べてみることにしました。

ドキュメントは一部更新されているみたいですが、まだまだ足りていない印象です。

恐らく詳細に関しては @kosmosebi がブチザッキに書いてくれるはずなので、例によって自分の興味のある部分だけ見ています。ASE v1 は知っているという前提なので注意。

ASE v2 を作成するのは非常にシンプルで、名前とリソースグループ、そしてリージョンを選択するぐらいで作れます。既存の VNET への参加も勿論できます。

f:id:shiba-yan:20170726205531p:plain

今日は ASE v2 以外にも ILB ASE で WebJobs サポートなどもリリースされたらしいですね。

料金プランの変更

これまでの ASE v1 では Frontend Pool に最低でも P2 が 2 台、Worker Pool に P1 が 1 台必要でした。つまり 1 か月間動かす場合には最低でも 113,832 円必要です。*1

新しい ASE v2 では基本使用料的なものが導入されていました。正直まだよくわかっていませんが、説明を読む限りでは Frontend Pool や File Server などの費用が含まれているようです。

f:id:shiba-yan:20170726205459p:plain

App Service Plan の数に関係なく、最低でも上の金額が必要となるみたいですね。ちょっと自信ないです。月額で表示されていますが、一応時間割されるらしいです。

なので ASE v2 を使う場合には最低でも 130,533.89 円かかりそうです。ちょっと高くなりました。

インスタンスが Dv2 ベースに

ASE v1 と比べて v2 は少し価格は上がったように感じますが、v2 では利用可能なインスタンスが Dv2 にアップグレードされているので、パフォーマンスは確実に v1 よりも上がっています。

新しく App Service Plan を作成する際に I1 から I3 で選ぶことが出来ます。

f:id:shiba-yan:20170726221806p:plain

ストレージも v1 の 500GB から 1TB に増えているので、実質値下げと言っても過言ではないと思います。ローカルストレージも SSD になり、CPU とメモリのバランスも良くなりました。

ただし素の Dv2 から比べると結構高いので、ASE 専用インスタンスと捉える必要があります。

Worker Pool から Isolated Worker に

事前に 3 つの Worker Pool のどれかに対してインスタンスと数を割り当てておく必要があった ASE v1 に対して、ASE v2 では通常の App Service と同じように App Service Plan を作る形になりました。

作成されたインスタンスは ASE によって管理されているので、追加の作業が必要になることはないです。

f:id:shiba-yan:20170726231949p:plain

スケールアップも App Service Plan の設定から行えますが、例によってスケール完了までには時間がそれなりにかかるので注意が必要です。

しかし ASE であることを感じさせずに、Web App などを作れるので便利になりました。

Storage が Azure File から変更

料金部分に File Server とあったので気になっていましたが、v1 ではコンテンツのストレージとして Azure File が使われていたのに対して、v2 では通常の App Service と同じ方式になってました。

f:id:shiba-yan:20170726231034p:plain

Azure File を使うとシンプルになって良さそうでしたが、パフォーマンスが悪かったので仕方ないです。

Frontend Pool のスケールが自動に

確か v1 では手動でスケールさせる必要があったはずですが、v2 では App Service Plan のインスタンス数に応じて自動的にスケールさせることが出来るみたいです。

f:id:shiba-yan:20170726230955p:plain

標準では I2 が使われている感がありますが、更にパワフルな I3 を使うことも出来そうです。ただし追加料金が必要になるようなので、課金周りがはっきりするまでは選びにくいですね。

色々と書いてきましたが、個人的にはインスタンスが A シリーズから Dv2 シリーズに変更になったというのが一番魅力的でした。通常の App Service も早く Dv2 ベースに切り替わってもらいたいものです。

*1:\45,532.80 * 2 + \22,766.40 * 1 = \113,832