AzureでKubernetes を使う実践テクニック

大平哲也(以下、大平):一応こんな挑戦的なタイトルを書いてるんですけど、トピック的な話をいくつかできれば良いかなと思っています。

今日話そうと思ったモチベーションとしては、Azureの上でKubernetesを動かしてる人が多くて、かつ仕事で使ってる人の話をあまり聞かなくて。一応今たまたま仕事で使ってることもあるので、どんな感じで使っているのかみたいな話をしていければなと思います。

15分で話せるネタを厳選した結果、アプリケーションの作り方というよりは、仕組み的なところやシステム関数など、そういった話が多めになってますが、ご了承ください。。

一応簡単に自己紹介ですが、大平といいます。会社名は今日は出しませんが、一応大きめのECサイトのリプレイスをやりました。そのあたりの話は今日はしないので、一応個人として参加しているという感じです。

では、まず一番最初に基礎的な話、Azure上でKubernetes、何で使って動かすかという話です。みなさんご存知のとおりACSとAKSあり、最近はAKSがよく使われているという話がありますが、実は第3の選択肢があるということで、ACS Engineの話をちょっとだけしたいなと思っています。

ACS Engineをご存知の方も多いとおもいますが、ACSと同等の環境を自分で構築ができるOSSとしてAzureが提供しているものです。Microsoftの方に聞くと、ACSやAKSに投入する前に実験的な機能がいろいろ入れられていて、最新の機能は優先的に実装されるらしいという話を聞いています。数日前のリリースでもけっこう最新の機能がアップデートされて取り入れられていたりしていて、アクティブなプロジェクトとして動いてるようです。

特徴としては、最近AKSに取り込まれた機能が多くて、ACS Engineならではというところがなくなってきていますが、最新のKubernetesが使えたりだ、AKSでもできるようになっていますが任意のvNet Subnetが使えるようになったりとか。

あとはKubernetes自身でバージョン1.10以降からcluster-autoscalerという機能が採用されていて、エージェントプールの、いわゆるオートスケーリングみたいなことができるようになっています。それをcluster-autoscalerを使ってやることができたりだと。あとはAKSはJapan Eastにしかきていませんが、日本でJapan Westを使おうと思うと選択肢がないわけですが、ACS Engineになるとそこにも入れられるみたいなところがあったりします。

おそらく数ヶ月前だと、vNet SupportやAuto ScalerがACS全然対応していなかったので、けっこう差がありましたが、最近はほぼ同じような感じにはなっていますが、Japan WestでKubernetesを最新バージョンで動かしたいなら、良い選択肢です。

設定はこんな感じで、使いたいKubernetesのバージョンだとか台数だとか、あとvmのサイズだとか、あとはvNetのSubnetのIDとか指定してあげるみたいな感じでやってあげると。そしてコマンド叩くとKubernetesの環境が作られます。

あとはcluster-autoscalerを、ご存知の方も多いと思いますが、一応DaemonSetで立てて設定は細かくしなきゃいけないんですが、ACS Engineになるとアドオンみたいな感じでけっこう簡単に書けるのが良いところかもしれません。

個人的な都合でEastとWestの両方に立てる必要があったので、ACS Engineを使ってます。ただ、けっこう特殊な事情かなと思っていて、AKSが最近ACS Engineにしかなかった機能をかなり取り込んできているので、今後は不要になるかもしれませんが、一応第3の選択肢として、もし興味があったらGithubのリポジトリを見ていただければなと思います。

Kubernetes上でアプリ開発を行うための基礎知識

あと、ちょっと上から目線な感じで、「Kubernetes Readyなアプリケーション」と書いています。このへんも基礎的な話をいくつかします。12 Factor Appってけっこうみなさんご存知だと思います。Herokuの方が書かれたドキュメントで、Herokuはもともとコンテナベースのパーツなので、書かれている内容はコンテナベースの開発にかなり親和性が高くて、Dockerなどでアプリケーションを書かれる方はまず必ず目を通すドキュメントかなと思ってます。

その中に書かれている12 Factor App、一応12個の項目があるんですけれども、こういったところに気をつけて書くのが、Kubernetes上でアプリケーションを作る際のベースとなるところかなと思っています。

一応そういった前提知識を共有た上で、いくつかのトピックを話していきます。1つは設定情報の扱いみたいなところです。ここに関しては12 Factor Appでもかなり項目を割いて書かれていますが、基礎的な話をいくつかお話します。

コードベースという概念があって、コードベースは必ず1つにしましょうみたいな話が書かれています。

開発環境のアプリや本番環境のアプリに分けるのではなく、コードベースは1つにして、デプロイした環境上で設定情報を注入することによって振る舞いを変えることが一応推奨されているみたいな。基本的には環境変数で振る舞いを変えるという話。

あとはBuild-Release-Runの話で、さっきはコードベースの話でしたが、一応コードがあってBuildして、それをReleaseします。

Buildした結果、DockerだとDockerイメージを作るというかたちになるんですけれども、Docker Imageも、開発環境のDocker Imageを作るということではなくて、基本的には同じDocker Imageを用意する。

それを実際動かすときに、設定を注入することによって振る舞いを変えると。その設定は環境変数で変えますよみたいな話とか。

あとはBackend Serviceで、例えばデータベースなど外部でリソースに接続するときは、基本的には疎結合のようなかたちにしておいて、実行時に環境変数で振る舞いを変えるみたいなことが推奨されたり。

Docker上でアプリケーションを動かす時は、環境変数を与えることで振る舞いを変えることが、作りとして推奨されているところがあります。

秘匿情報の扱い方

そういうことを考えた時に、秘匿情報ってどうしたら良いのかというと、一番最初に思い当たるところで、この解決策は環境によっては面倒くさいです。まずみなさんもやられているところで言うとkeyvaultで管理をされていると思うんですけれども、それをKubernetesと連携する時に、flexvolという仕組みがあって、それと組み合わせて良い感じでKubernetes上に秘匿情報が渡すツールが、Azureのオープンソースで提供されています。

というところで、こんな感じで設定してあげるとkeyvaultに設定されている内容を、良い感じでflexvolの仕組みを使ってKubernetesに渡すさせるみたいな。

Kubernetes上で動くDockerイメージみたいなことができるみたいな感じになってます。一応こういったことを配慮してアプリケーションを作るのが、必要になってくると思います。

Logの管理について

あとLog回りの管理に関しては、一応12 Factor Appの中にもログの項目があって、ここに書かれていることとは、一応先ほどでもお話がありましたが、基本的にLogはDockerやKubernetesのログ管理は、コンテナの標準出力や標準エラーで書くことを推奨されています。

ではそのLogをどうやって扱うのかというところは、意外と考えなきゃいけないところで、一応抽象的に概念を書くと、何者かがコンテナログを吸い上げてどこかにまとめておいて、どこかに置かれたログを何者かが解析するみたいな感じの流れを、なんとかして用意する必要があります。

一般的に、用語で置き換えるとLog CollectorとかStorageとかVisualizerみたいな感じになります。

先ほどご紹介されてた中だとLogstashとかElasticSearch基盤みたいなものを使ってやるのが一般的かなと思います。

一応今日はAzureのコミュニティなので、今日はAzure縛りでなるべく話そうかなと思っていて、Azureで実現しようとすると、このOperation Management Suiteといったものがけっこう使えるのかなと思っています。これは一応僕の認識だと、Azureが提供するさまざまなアプリケーションリソースとかのイベントログを網羅的に収集するサービスです。これはKubernetesのログも収集してくれまして、かつデータのダッシュボードもついてるので便利です。

KubernetesとOMSを連携させるのはかなり簡単で、Kubernetesのクラスターにdaemonsetでoms-agentを置くだけで、基本的にはいけます。それか、oms-agentをdaemonsetとして置く事例みたいな感じなんですけれども、ちょっと全部は書いてないですがこんな感じで書いてあげるとOMSと連携されて、ダッシュボードを勝手に作ってくれて、これはけっこう便利だと個人的には思っています。

すごい便利なんですが1つ難点があって、データの反映が遅いんです。これはMSさんにも話をしたんですが、なかなか解決できないということで、だいたい10分ぐらいdelayしちゃうので、リアルタイムに関しては使えません。一応標準機能として持っているものなので、データを入れておいて過去のトレンドの分析には使えるって感じです。

あとはアプリケーションのアクセスログとか、そういったアプリケーション固有の問題に関しては、自分である程度やる必要があるところがあります。

結局はほかのものを組み合わせてやることになるんですが、例えばElasticSearch基盤みたいなものを自分でがんばって作るみたいな話もありますし、他社さんの商用製品を使うみたいなところもあるかなと思ってます。今日はAzureのコミュニティなので、具体的な商品名は差し控えますけれども、一応おすすめのサービスがありまして、犬のアイコンである程度察していただければと思っております。

システムの監視について

最後はシステムの監視。ちょっと軽めの話が続いていますが、システムの監視もオーバービューみたいなところを話していきます。Kubernetes上でAzure縛りな監視をしようとすると、これぐらいの選択肢があります。Azure Metricsと、先ほどあげたOMS、あとAKS限定になりますが、Azure Monitor Container Healthという機能があります。

これはKubernetesのノードの情報や、個々のAgent Poolで動いているコンテナの情報を可視化してくれるサービスです。一応これはAKSだけ向けみたいな感じです。画面はブログから持ってきたものをそのまま貼っちゃったんですけどこんな感じになっていて、特定のAgent Poolの中にどんなイメージが動いているか、botが何台動いているか見れたりします。

kubectlとかで見れるような情報が、そのまま画面で見れるだけという言い方もできることはできますが、こんな機能がAzureポータルで標準についてきてるのは、けっこう便利かなと思っています。

ただ、やはりAzureの機能だけだと足りない部分がありますし、アプリケーション固有の状況については、別途自分たちで用意する必要があると思っています。エラー数だとやJavaの場合はJavaVMの状況が知りたいみたいな話があったりします。

今いろんな選択肢がありますが、個人的によく使っているのは、Prometheus Exporterを立てて、それを何かしらのMonitoring Toolで収集するかたちですね。例えばWeb アプリケーションだとした場合、それを作る場合は必ずEnd pointとしてPrometheus Exporterも一緒に設置するようなかたちにして、アプリケーションのメトリクスは何かしら取得できるような状況を作っておく。

それに対して何かしらのMonitoring ToolでExporterからデータを収集して、Visualizingしたりグラフ作ったり、もしくはアラート処理をするのが良いんじゃないのかと思います。

ここはJavaの限定の話になりますが、例えばSpring Bootとかでアプリケーションを作っている場合、現在Spring2.0以降が最新のバージョンになりますが、2.0からMicrometerという、主に監視回りのことを司ってくれるライブラリが一応正式に採用されています。

Micrometerを使うと、さまざまな監視ツールとかにメトリクスを伝搬することができるようになっています。Datadogにも連携できますし、Prometheus Exporterにも対応してます。

こんな感じで必要なライブラリ用意して、あとちょっとSpring Bootにちょっとしたアノテーションを追加する必要があるんですが、それをやってあげると基本的にはPrometheus Exporterが勝手に作られる。

End pointが勝手作られます。こんな感じで叩いてあげると、こうJavaのメトリクスとかが簡単に取れるようになります。

これでメトリクスを収集するためのもとは出来たので、それをいかにMonitoring Toolで収集するかみたいな感じの構成をすればいいんですが、PrometheusとGrafanaを組み合わせるのが一番あるやり方かなと思っております。一応私は、他社の商用製品を用いる選択肢を選んでいて、おすすめのサービスがありますが、ここはAzureのコミュニティなので、空気を読んで割愛させていただきます。

みたいな感じの軽い話をさせていただきます。ご静聴ありがとうございました。