今までの Azure 関連の記事は以下。
Azure Container Serviceを使う(1) 基本のデプロイ編
Azure Container Serviceを使う(2) 自動化してみる編
Azure Container Service と Micro Services
Azure Container Service(以下 ACS) についてやってきましたが、ACS は構成を作成するテンプレートという性格上、運用とか監視などは、あくまでこちらがやらなければならないものでした。
Docker Container を利用することによる自由の代償ですが、そもそもそこまで自由である必要がないケースも多くあると思います。
例えば最近 Buzz word になってる感がある Micro Services を、コンテナベースにしてACS上で動かしてみようとすると、以下のような課題を解決していく必要があります。
- アプリの監視系統まで用意しないといけない
- アプリそのもののスケール方式を用意しないといけない
- アプリのリカバリ方式を用意しないといけない
- …その他
実際にアプリケーションを運用していく際に、必要になっていくものを、自前で解決しないとなりません。環境構築マニアなら楽しいかもしれませんが、結構な時間が必要なのも事実です。
また、環境以外でも、サービス間の連携について考慮すべき点など、考える必要があるものはこれ以外にも多岐に渡ります。
こういった点から、すでに周辺でこういった環境が用意されていないのであれば、ACS はファーストチョイスとしづらいかと思います。
Azure 上で Micro Services を構築しようとした時、ファーストチョイスとなるのは ACS ではなく、 Service Fabric になるかと思います。
Service Fabric
Service Fabricとは、以下の特徴を持つ Microsoft Azure が 提供する Managed Service です。
- 小さなサービスを組み合わせて一つのサービスとする
- それぞれのサービスは自動的にスケールする
- 各サービスが個別に冗長化される
- ステートフルなサービスとステートレスなサービスを明示的に分けられる
- 更新のあったサービスのみを更新するライブアップデートが標準装備
- サービス間の通信を標準化できる
- コンテナをサービスとして実行できる(2016/10時点ではDockerのみ、Linux サーバー限定)
- Azure/オンプレ間で同一の実装を動かせる
Service Fabric 自体は、その名の通りサービスの基礎としてのサービスを提供しています。実際に Azure が提供している Managed Service や、Microsoft本体のサービスでも利用されているようで、公式には少なくとも以下のサービスで利用されているようです。
Skype for Business、Intune、Azure Event Hubs、Azure Data Factory、Azure DocumentDB、Azure SQL Database、Cortana
Service Fabric の説明の中では、 Micro Services = Service Fabric 内の各サービス、とされているようです。ステートレスなマイクロサービスってよくわかりませんが、例では nginx 等のプロキシとかが挙げられていました。
用語はさておき、Service Fabric は Micro Services を構築していく中で困ることや欲しい機能が、標準で用意されているところに大きな利点があります。上に挙げたように、スケールの制御とか冗長化とか、自前で行うと結構ヘビーな機能が標準で用意されていますので、作る側としては作ることに集中することが出来ます。
Service Fabric の制限
割とサービスを構築する上でいたれりつくせりな感がある Service Fabric ですが、いくつか制限があります。
- X509証明書が必要
- 管理用と接続用に2つ必要です。ちゃんと署名されている必要があるようで。。。
- PowerShellが強い
- 公式サンプルのほぼ全てがPowerShellです。Azure CLIのサンプルも欲しい。。。
- SDKに則らなければならない
- これは、他のクラウドの Managed Service でも大抵そうなってるので、まぁ普通かなと
この他の制約としては、基本的にVisual Studio 推しである、というくらいでしょうか。C#をやるにおいて最強のIDEであることに異論はありません。
Service Fabric と Java/Linux
さて、実際に Service Fabric で動作するアプリケーションを作ってみたいところですが…残念ながら私のような、メインマシンが Linux であるようなマイノリティは、Visual Studio も PowerShell も(今の所)利用することが出来ません。
これは詰んだか、と思いきや、最近の Microsoft らしく、 Linux 上での環境構築と、Java での実装ガイドがありました。
これを読みながら、 他でも流用できるように Vagrant で動かせるようにしていきましょう。Java で動かすのか C# で動かすのかはその後でも。
Service Fabric の用語
事前に 公式の用語集 を読んでおいたほうがいいかと思います。結構独自の概念がありますので。
Vagrantを立ち上げる
まずはVagrantを立ち上げましょう。サポートしているのが Ubuntu 16.04 (Xenial Xerus)
ということなので、公式のを…といきたいところですが、Ubuntu公式のboxは結構問題があって、大抵2回め以降起動しなくなります(経験済み)。
そこで、評価の良い bentoのubuntu 16.04 を使います。bentoのロゴが本当の弁当箱な辺り、Chefプロジェクトっぽいですね。
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-16.04"
そして、事前に Service Fabric Explorer で利用するポートを開けておきます。
...
config.vm.network "forwarded_port", guest: 19080, host: 19080
...
Vagrant 本体の設定はこれくらいで、実際のセットアップは provisioning から行うことにします。
# !/bin/sh
sudo sh -c 'echo "deb [arch=amd64] http://apt-mo.trafficmanager.net/repos/servicefabric/ trusty main" > /etc/apt/sources.list.d/servicefabric.list'
sudo apt-key adv --keyserver apt-mo.trafficmanager.net --recv-keys 417A0893
sudo apt update
sudo apt upgrade -y
sudo locale-gen ja_JP.UTF-8
# servicefabricとservicefabricsdkcommonの両方に対して、EULAの承諾が必要。
echo debconf servicefabric/accepted-all-eula select true | sudo debconf-set-selections
echo debconf servicefabric/accepted-all-eula seen true | sudo debconf-set-selections
echo debconf servicefabricsdkcommon/accepted-all-eula select true | sudo debconf-set-selections
echo debconf servicefabricsdkcommon/accepted-all-eula seen true | sudo debconf-set-selections
sudo DEBIAN_ERONTEND=noninteractive apt install -yq software-properties-common git-core servicefabricsdkcommon servicefabricsdkjava
sudo /opt/microsoft/sdk/servicefabric/common/sdkcommonsetup.sh
# Azure クロスプラットフォーム CLIも利用するので追加しておく
git clone https://github.com/Azure/azure-xplat-cli.git
pushd azure-xplat-cli
npm install
sudo ln -s $(pwd)/bin/azure /usr/bin/azure
popd
azure --completion >> ~/azure.completion.sh
echo 'source ~/azure.completion.sh' >> ~/.bash_profile
sudo /opt/microsoft/sdk/servicefabric/java/sdkjavasetup.sh
sudo /opt/microsoft/sdk/servicefabric/common/clustersetup/devclustersetup.sh
最初の2行と、真ん中辺りが実際に Service Fabric 関連をインストールする設定です。Service Fabric 関連をインストールする際に、EULAの承諾を必要とするため、その部分をスキップしています。
後半は、実際に利用する上で、クロスプラットフォームCLIも利用するので、それも追加しています。
最後の行は、ローカルでの開発に利用するためのクラスタを作成しています。これ自体は一回行えば良いため、provisioning のタイミングで行っています。
ここまで設定した時点で、 vagrant up
後に自動的に Service Fabric が起動するようになります。最初に開いておいた 19080 ポートにブラウザでアクセスすると、ちゃんと設定できていれば、以下のようなページが開きます。
ちなみに、マシン起動時のService Fabricの立ち上がりには、それなりに時間がかかります。大体4〜5分を見ておけばいいかと。
最初の Service をJavaで作ってみる
それでは、初めての Service を作っていってみます。今回はあくまでサンプルなのと、私が個人的に Eclipse をあんまり使いたくないので、全部 CUI からやっていきます。
といっても、 実際は 公式ガイド の内容とほとんど変わらないのですが。
まずはテンプレートから、基本形を作成します。なんでか知りませんが、 Yeoman が利用されています。
$ yo azuresfjava
生成されたファイルを見るとわかりますが、ビルドシステムは Gradle でした。が、 gradle-wrapper を設定してくれていません…。Linux ユーザーはGradleくらい入ってるだろ?ってことでしょうか。
Service Fabric の Java SDK をインストールした時点で、gradle自体は入ります。今回は Vagrant 上に環境を構築していますが、実際にはgradleが無い環境で開発することもあると思いますので、gradle-wrapper の設定を追加しておきます。
$ cd first_service/myapp
$ gradle wrapper --gradle-version 2.14.1
後は、gradle/ ディレクトリをコミットすればOKです。
テンプレートですが、実際には4つ(一つは全体をまとめるためのproject)の gradle プロジェクトが出来ます。ここでは
* myapp = アプリケーション
* myactorservice = サービス
* myactorserviceTestClient = テスト用のクライアント
となっているようです。
ビルド自体は、gradlew を実行するだけです。
$ ./gradlew
とりあえず、テンプレートそのまんまではありますが、これをVagrant上のService Fabricにデプロイします。公式ガイドでは、ここでコマンド名が違うようです。
$ azure servicefabric cluster connect
$ cd /vagrant/first_service/myapp
$ ./install.sh
デプロイが終わると、こんな感じになります。3つのノードに分散していて、Node1がプライマリだ、というのがわかります。
公式にしたがって、フェールオーバーを体験してみます。
cd /vagrant/myapp/myactorserviceTestClient
watch -n 1 ./testclient.sh
これを実行した状態で、上の画像にある Primary のノードを止めたり開始したりしてみます。(System欄のサービス自体がシングルトンになっているのが要因かもしれませんが、restartは選択してもうまく行かないようでした)
やってみるとわかりますが、このサンプルは Stateful なサービスのようで、プライマリを止めてもちゃんとカウントアップし続けます。ただし、フェールオーバーを行うためだと思いますが、1〜2秒程カウントアップは止まるようです。
今回やった内容はこちらです。
おまけ:CLIからサービスを更新してみる
さて、テンプレートからやってみましたが、このテンプレートはやっぱり基礎でしかありません。
その証拠?として
- インストール/アップデートしかできない
- バージョンがベタ書き
などがあります。あくまで動作を学ぶっていう意味であればいいと思うんですが、とりあえず更新くらいはしたいですよね。しかし、公式ではJava/Azure CLI のことが書いてあるのはこの辺までで、後はPowerShellについてばっかりです。
とりあえずやってみようということで、テンプレートの以下の部分を書き換えます。myapp とか myactorservice とかは、自分のアプリケーションとサービス名で置き換えれば、他の名前でもOKです。
- myapp/ApplicationManifest.xml の
ApplicaitonManifest@ApplicationTypeVersion
を 1.0.1 に - myapp/myactorservicePkg/ServiceManifest.xml 内の各
Version
属性を 1.0.1 に
そして、以下のコマンドを実行します。
azure servicefabric application package copy myapp fabric:ImageStore
azure servicefabric application type register myapp
azure servicefabric application upgrade start --application-name 'fabric:/myapp' --target-application-type-version 1.0.1 --rolling-upgrade-mode Monitored
成功すると、こんな感じに進むのが確認できます。
実際には、各サービスのManifest.xmlはそれぞれで管理すべきですし、アプリケーションのバージョンも外部から設定できるような仕組みを用意すべきでしょう。が、とりあえずはできるってことは確認できました。
まとめ
よりよいテンプレートが欲しいです。Microsoft的には C# 最強なのはわかりますし、正直私もPure Javaにはそんなに魅力を感じていないですけど。(ぉぃ
ただ、それでもJVMが使えるということは、JVM上で動作する他の言語を利用できるということなので、それらを使うための第一歩になるのでは無いかと思います。
今回は開発用のローカルクラスタでしたが、次回は実際にAzure上のService Fabric を作成して、その上でJava製サービスを動かしてみたいと思います。