[Azure Container Service版] 30分で作るMesos + Chronos + Marathon + Dockerクラスタ環境

当記事は
----

牛尾さんの記事:[瞬殺で作るMesos + Chronos + Marathon + Dockerクラスタ環境](http://qiita.com/TsuyoshiUshio@github/items/9d8f5b952b635d94ae6f)をベースにしています。

上記牛尾さんの記事、そのっつさんの[正月休みだし Mesos 触ってみた](http://blog.livedoor.jp/sonots/archives/35421955.html)および、Azureの公式/非公式な多くのドキュメントを参考にしています。
みなさまありがとうございますmm



# TL;DR


Azure Container ServiceがPublic Previewになったので、試してみました。
[Public preview: Azure Container Service](https://azure.microsoft.com/en-us/updates/public-preview-azure-container-service/)

AzureのSubscriptionを持っている人なら、待ち時間込みの30分強で誰でもDockerクラスタ環境を手に入れることができちゃいます。

当記事の内容を実施いただくと、去年牛尾さんが書かれていた下記記事と似た構成のDockerクラスタをAzure上にサクッと構築することができます。
[瞬殺で作るMesos + Chronos + Marathon + Dockerクラスタ環境](http://qiita.com/TsuyoshiUshio@github/items/9d8f5b952b635d94ae6f)



# どんなクラスタを構築するの？

今回は↓のARM Templateを使用して構築します。
[101-acs-mesos](https://github.com/Azure/azure-quickstart-templates/tree/master/101-acs-mesos)


※ARM Templateについて今回は説明しません。わからなくても問題なくDockerクラスタを構築できますが、気になる人は [ARM Templateって何？](http://qiita.com/nntsugu@github/private/4a72e17e9d84ce089331#arm-template%E3%81%A3%E3%81%A6%E4%BD%95%E3%81%A3%E3%81%A6%E4%BA%BA%E3%81%AF) を読んでみてください。


![構成](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/101-acs-mesos/images/mesos.png)

図1

- Mesos master xN台とMesos slave xN台な構成です。

----
図中では

- Mesos masterはmaster availability set
- Mesos slaveはagent VM scale set

と表現されています。

- Mesos slaveで構成されたリソース上でDockerコンテナを動かします。

----
- Mesos/Marathon/Chronosの管理UIはMesos master上にあります。これらにはSSHポートフォワーディングで作ったトンネルを通して、ブラウザで接続します。
- 管理UIにアクセスする際のURLはこうなります。
    - Mesos: http://localhost/mesos/
    - Marathon: http://localhost/marathon/
    - Chronos: http://localhost/chronos/

----
 
- DockerコンテナをデプロイするMesos slaveはLoad Balancer(以下LB)にぶさがっており、LBに割り当てられたPublic IP address/Public DNS nameの80/443/8080番ポートを通してアクセスすることができます。図中のLBでは43となっていますが、443が正しいです。
- Mesos slave上にデプロイしたアプリケーションやDockerコンテナをどのポートにマッピングするかは、Marathonの管理UIでCreate する際に指定できます。

----

なお、上記説明は、[Mesos Container Service Walkthrough](https://github.com/Azure/azure-quickstart-templates/blob/master/101-acs-mesos/docs/MesosWalkthrough.md)をかいつまみつつ説明したものとなります。


# Dockerクラスタを構築する手順


## 前提

AzureのSubscriptionを持っているだけでOKです。

## クラスタのセットアップ

↓のARM Templateを使用して構築します。
[101-acs-mesos](https://github.com/Azure/azure-quickstart-templates/tree/master/101-acs-mesos)

やり方はとても簡単。

<img width="830" alt="github" src="https://qiita-image-store.s3.amazonaws.com/0/14859/600d531c-9c68-627c-01f3-8569858031ec.png">

上記githubをブラウザで開き、"Deploy to Azure"ボタンを
クリックします。

<img width="830" alt="Azure Management Portal" src="https://qiita-image-store.s3.amazonaws.com/0/14859/b4658448-f200-c8e2-8d9d-073f7c8e5fd0.png">

するとAzureの管理Portalが開きます。
今回使用するARM Templateに必要なパラメータ、Subscription、Dockerクラスタを構築するResource Group名とロケーションの入力とLegal termへの合意を行います。

----
- ARM Templateに必要なパラメータ
  - DNS name prefix : DNS名の頭に付く文字列です。
  - Agent count : Mesos slaveクラスタを構成するAzure VMの数です。試すだけなら1でOK。
  - Agent VM size :  Azure VMのスペックです。金額などの詳細は[こちら](https://azure.microsoft.com/ja-jp/pricing/details/virtual-machines/)を参照してください。
  - Linux admin user name : SSHログインする際のユーザ名です。
  - Orchestrator type : Dockerクラスタを管理するOrchestratorを選択できます。今はMesosかSwarm(preview)のみ。今回はMesosを選択します。
  - Master count : Mesos masterを構成するAzure VMの数です。試すだけなら1でOK。
  - SSH RSA public key : SSH接続/ポートフォワーディングする際に使用する鍵の公開鍵の中身の文字列をコピペすればOKです。(ssh-keygenで生成した鍵のhoge.pubの中身です。ex. "ssh-rsa AAAAB3Nz~[略]~fuga meado@hoge.com")

----
- Subscription
  - 複数持っている場合はここで選択できます。

----
- Dockerクラスタを構築するResource Group名とロケーション
  - Resource group name : 今回は"ACSdesuyo"という名前で新しくResource groupを作成しています。Resouce groupはできれば分けておきましょう。あとでまとめて削除できるので便利です。
  - Resource group location : 任意で。今回は西日本リージョンを選択しました。VMが東日本より安いので。。
  - Legal terms : 中身を確認して問題なければCreateボタンを押して合意しましょう。

----


入力し終わったらCreateボタンを押し、Deployされるのを待ちます。

<img width="299" alt="deploying" src="https://qiita-image-store.s3.amazonaws.com/0/14859/511198d0-b51a-b0be-900b-4ea454946556.png">

↑はデプロイ中のPortalの様子。
20分以上かかると思うので、気長に待ちます。

----
~~ 20分後 ~~

<img width="299" alt="finish" src="https://qiita-image-store.s3.amazonaws.com/0/14859/2e946cfb-584f-562f-1cc3-d0d6e21686ca.png">

完成！




# 動作確認(Mesos masterへの接続)

## SSHポートフォワーディング

ブラウザで localhost:80 へアクセスすると、Mesos master上の80番ポートへリクエストが転送されるよう、SSHポートフォワーディングでトンネルを作ります。


ローカルPCのターミナル上で下記コマンドを実行します。

```command
# Windowsの場合は下記を参照してください
https://github.com/Azure/azure-quickstart-templates/blob/master/101-acs-mesos/docs/SSHKeyManagement.md#key-management-and-agent-forwarding-with-windows-pageant


# Mac/Linuxの場合
sudo ssh -L 80:localhost:80 -N azureuser@nntugumgmt.japanwest.cloudapp.azure.com -i ~/.ssh/azure-acs-dayo -p 2200


# 構文はこんな感じ
sudo ssh -L 80:localhost:80 -N [Linux admin user name]@[Mesos masterのDNS name] -i [Path to SSH secret key] -p [Mesos masterへの接続用Port]
```

[]で囲っている部分を自分の環境に合わせて置き換えればOK。


- Linux admin user name : ARM Templateに引き渡したパラメータそのままのものでOK。当記事では azureuser と入力しました。
- Mesos masterのDNS name : [Mesos masterのDNS nameの確認方法](http://qiita.com/nntsugu@github/private/4a72e17e9d84ce089331#mesos-master%E3%81%AEdns-name%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95) 確認方法はこちら
- Path to SSH secret key : ARM Templateに引き渡したSSH RSA public keyの対になる秘密鍵
- Mesos masterへの接続用Port : Mesos masterへSSH接続するためのポート。デフォルトでは、Mesos masterの台数に応じて2200番から順に振られていきます。※図1を参照。



## 管理UIへアクセスしてみる

- Mesos master : http://localhost/mesos/
<img width="800" alt="Mesos master" src="https://qiita-image-store.s3.amazonaws.com/0/14859/45b59f7f-1d06-bc5d-29a8-96611277e58e.png">

- Marathon : http://localhost/marathon/
<img width="800" alt="Marathon" src="https://qiita-image-store.s3.amazonaws.com/0/14859/64d46e9d-f799-e8f4-fb9b-7c24dc71940e.png">

- Chronos : http://localhost/chronos/
<img width="800" alt="Chronos" src="https://qiita-image-store.s3.amazonaws.com/0/14859/fd7279aa-a8c8-60b4-5514-aeaf76b42f2b.png">


これで準備は完了です。

502 Bad Gatewayあたりが返ってきてUIへアクセス出来ない場合は、[こちら](http://qiita.com/nntsugu@github/private/4a72e17e9d84ce089331#mesoschronosmarathon%E3%81%AEui%E3%81%AB%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%99%E3%82%8B%E3%81%A8502-bad-gateway%E3%81%AB%E3%81%AA%E3%81%A3%E3%81%A6%E3%81%97%E3%81%BE%E3%81%86%E5%A0%B4%E5%90%88%E3%81%AE%E5%AF%BE%E5%87%A6%E6%96%B9%E6%B3%95)を参考に対処すると大抵の場合解決します。

# Mesosを試してみる

当記事ではすでにわかりやすい記事があるため、Chronos/Mesos masterのUIについては割愛します。


Chronos/Mesos masterのUIについては、

[牛尾さんの記事](http://qiita.com/TsuyoshiUshio@github/items/9d8f5b952b635d94ae6f#1-chronos%E3%81%8B%E3%82%89%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)
　[1. Chronosからタスクを実行してみる](http://qiita.com/TsuyoshiUshio@github/items/9d8f5b952b635d94ae6f#1-chronos%E3%81%8B%E3%82%89%E3%82%BF%E3%82%B9%E3%82%AF%E3%82%92%E5%AE%9F%E8%A1%8C%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B)

や[当記事で使用したARM Templateのドキュメント]()

がわかりやすいのでおすすめです。
何かいいネタがあれば追記します。

## 1.Marathonを使ってみる＠シンプルなアプリケーションのデプロイ

Mesosが管理するリソース上にDockerコンテナをデプロイする前に、80にアクセスしてきた相手に「HTTPレスポンスコード:200」と「Hello World」を返すだけのアプリケーションをデプロイしてみます。

　1. Marathon(http://localhost/marathon/)へアクセス
　2. Create New Application

<img width="211" alt="Create" src="https://qiita-image-store.s3.amazonaws.com/0/14859/3b1d116f-8f53-158a-27d1-94974c3d14dc.png">

レフトナビのCreateボタンを押します。

----

<img width="372" alt="New Application" src="https://qiita-image-store.s3.amazonaws.com/0/14859/0d8af8e7-4d00-d1db-2cd8-79d72eb0dd0d.png">

デプロイするApplicationの情報を入力するフォームが表示されるので、

- ID : hello-world
- CPU : 0.1
- Command :

```
while true; do ( echo "HTTP/1.0 200 Ok"; echo; echo "Hello World" ) | nc -l 80; done
```
- Optional settings
  - Ports : 80



と入力してCreateします。


- Optional settings > Ports : 80 について
  - Marathonは、Portsに何も入力しなかった場合、Applicationにランダムでポートを割り振ります。
  - ApplicationがデプロイされるのはMesos slave上です。
  - 図1にある通り、Mesos slaveへはLBの80/443/8080版ポートを通してアクセスできるようになっています。
  - LBの設定を変更せずにデプロイしたApplicationへ外部からアクセスするには、Applicationに80/443/8080いずれかのポートを割り振る必要があります。


　3. ApplicationのStatusがRunningになるまで待つ。

<img width="736" alt="Status" src="https://qiita-image-store.s3.amazonaws.com/0/14859/c531a330-9f36-b719-c27a-ce1e04a1e10a.png">

この時点でMesos slave上にデプロイされたApllicationが動き始めました。

　4. ブラウザ経由でアクセスしてみる。

<img width="447" alt="Simple Application" src="https://qiita-image-store.s3.amazonaws.com/0/14859/6ab1016f-237d-3282-4302-fc5847014df4.png">


URLはMesos slave(図1でいうところのagent)に紐付いたLBから確認できます。
[Mesos slaveのDNS nameの確認方法](http://qiita.com/nntsugu@github/private/4a72e17e9d84ce089331#mesos-slave%E3%81%AEdns-name%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95)


## 2.MarathonでDockerコンテナをデプロイする

今回利用したARM Templateの作者がDocker Hubに用意してくれたDockerイメージをデプロイしてみたいと思います。
https://hub.docker.com/r/yeasy/simple-web/


ではやってみましょう。


　1. Marathon(http://localhost/marathon/)へアクセス
　2. Create New Application

<img width="211" alt="Create" src="https://qiita-image-store.s3.amazonaws.com/0/14859/3b1d116f-8f53-158a-27d1-94974c3d14dc.png">

レフトナビのCreateボタンを押します。

----

<img width="372" alt="New Application" src="https://qiita-image-store.s3.amazonaws.com/0/14859/70e6acda-e339-8587-31f4-0c5b64abc39f.png">
<img width="372" alt="New Application" src="https://qiita-image-store.s3.amazonaws.com/0/14859/af193ebd-67fb-7e8c-b9be-9dbd3a57732f.png">

デプロイするApplicationの情報を入力するフォームが表示されるので、

- ID : simple-web
- CPU : 0.1
- Memory : 256

- Docker container settings 
  - Image : yeasy/simple-web
  - Network : Host

- Optional settings
  - Ports : 80


と入力してCreateします。


- Optional settings > Ports : 80 について
  - Marathonは、Portsに何も入力しなかった場合、Applicationにランダムでポートを割り振ります。
  - ApplicationがデプロイされるのはMesos slave上です。
  - 図1にある通り、Mesos slaveへはLBの80/443/8080版ポートを通してアクセスできるようになっています。
  - LBの設定を変更せずにデプロイしたApplicationへ外部からアクセスするには、Applicationに80/443/8080いずれかのポートを割り振る必要があります。


　3. ApplicationのStatusがRunningになるまで待つ。


<img width="858" alt="Status" src="https://qiita-image-store.s3.amazonaws.com/0/14859/9f771f24-5948-9fa9-38a1-f5b52218074a.png">

今回はdocker pullしているのでそこそこ時間がかかります。
この時点でMesos slave上にデプロイされたDockerコンテナが動き始めました。

　4. ブラウザ経由でアクセスしてみる。

<img width="914" alt="simple-web" src="https://qiita-image-store.s3.amazonaws.com/0/14859/893891e2-58d4-237b-9080-9364112c8ca9.png">


URLはMesos slave(図1でいうところのagent)に紐付いたLBから確認できます。
[Mesos slaveのDNS nameの確認方法](http://qiita.com/nntsugu@github/private/4a72e17e9d84ce089331#mesos-slave%E3%81%AEdns-name%E3%81%AE%E7%A2%BA%E8%AA%8D%E6%96%B9%E6%B3%95)




# まとめ

まだPublic previewなAzure Container Serviceですが、ARM Templateの仕組みがとても良く出来ているおかげで詰まることなくDockerクラスタ環境が構築できてしまいました。
慣れてくると30分もあれば環境を再構築できちゃいます。
Dockerコンテナをbuildしている間に、Dockerクラスタ環境を作れちゃうなんてすごいですよね。
(利用料金はかかりますが)検証しほうだいです。

リソース監視、サービス死活監視、Scale out/inあたりのルールをチームに合わせた運用ポリシーとして整備して、
セキュリティやパフォーマンスといった非機能要件をクリアできればすぐにでも本番環境として使えそうな印象でした。

以上、@nntsuguでした。


# Tips

## Mesos masterのDNS nameの確認方法

<img width="1129" alt="DNS name" src="https://qiita-image-store.s3.amazonaws.com/0/14859/cfb3312e-bc65-3c47-97f7-da95e3c21ccf.png">

- Mesos masterへはLoad Balancer(以下LB)のNATを通してアクセスします。
- Mesos masterのLBに紐付いたPublic IP addressのDNS nameはAzure portalから上図の通り確認することができます。


## Mesos slaveのDNS nameの確認方法

<img width="1129" alt="DNS name" src="https://qiita-image-store.s3.amazonaws.com/0/14859/7e22eb22-a87e-eaf2-96f7-bd744b6124d6.png">


- Mesos slaveへはLoad Balancer(以下LB)を通してアクセスします。
- Mesos slaveのLBに紐付いたPublic IP addressのDNS nameはAzure portalから上図の通り確認することができます。


## Mesos/Chronos/MarathonのUIにアクセスすると502 Bad Gatewayになってしまう場合の対処方法

- Mesos masterの乗っているVMを再起動する(当記事だと"mesos-master-C72CC01D-0")

or

- [公式ドキュメントのコメント](https://azure.microsoft.com/en-us/documentation/articles/container-service-connect/#comment-2524721470)にあるプロセス再起動を実施する

で大抵の場合は解決できます。

## Mesos slaveのScale out/Scale in

ARM explore or REST APIでさくっと変更できるようです。
サービス断無しに操作できるか？などなど確認してからどこかにまとめたいなー。


# 参考資料

## ARM Templateって何？

って人は
[Azure リソース マネージャーの概要](https://azure.microsoft.com/ja-jp/documentation/articles/resource-group-overview/)を読んでみるといいかも。

## 今回お世話になった資料たち

みなさんのおかげでMesosとACSのTemplateの構成がすっと頭に入ってきました。
ありがとうございますmm

[瞬殺で作るMesos + Chronos + Marathon + Dockerクラスタ環境](http://qiita.com/TsuyoshiUshio@github/items/9d8f5b952b635d94ae6f)

[正月休みだし Mesos 触ってみた](http://blog.livedoor.jp/sonots/archives/35421955.html)

https://github.com/Azure/azure-quickstart-templates/tree/master/101-acs-mesos

https://github.com/Azure/azure-quickstart-templates/blob/master/101-acs-mesos/docs/MesosWalkthrough.md