はじめに
Tutorial Advent Calendar 2020の1日目、最初の記事を投稿するのは、Tutorial Advent Calendar 2020の主宰というか言い出しっぺであるSREの平田です。よろしくおねがいします。
Tutorial Advent Calendar 2020は「Robotic Crowdを支える技術」というテーマで、全エンジニア+弊社カスタマーサクセスチームのゲスト3人が25日間毎日お送りする社員発のアドベントカレンダーです。
その最初の記事として、今回は「Prometheus in GKE」というテーマで、Prometheusを利用した監視の導入方法と、GKEで運用する上での注意点をご紹介します。
Prometheusとは?
Prometheusは、オープンソースのモニタリングソリューションの1つです。Prometheus自体にもかなりリッチなコンソールが準備されているため、これ単体で使うことももちろん可能です。しかし既存のCloudWatchやStackdriverからPrometheusの取得したメトリクスを参照してモニタリングを充実させるという使い方も可能で、弊社もこのパターンを採用しました。
GKEでの導入
経緯
弊社はメインプロダクトのRoboticCrowdを公開して以来GKEを利用しており、監視ツールとしてもStackdriver Monitoringを導入していました。GKEを利用しているためStackdriver Monitoringの利用料が非常に安く上がり、非常に満足していましたが、稼働中のPod数等Kubeletに関してのメトリクスを設定することができず、これを実現するためにPrometheusを採用しました。
モニタリングのダッシュボードはStackdriver Monitoringのものをそのまま利用することにしました。ダッシュボード用サービスを作成・運用すると、サーバコストも人的コストも必要になってしまう一方でダッシュボードが複数にまたがってしまい見づらくなることも予想されたためです。
導入方法
今回は既存のCluster上にSidecarで起動することにしました。現行のCluster内の各Nodeにリソースに余裕があり、なおかつ最小工数で導入するためにこの導入方法を採用しましたが、本来であればプロダクト向けNodePoolからは切り離したほうが良いと思います。
また、弊社はHelmを利用していないので、kubectlコマンドで直接yamlをapplyする形での起動方法を採用しています。
まず、GCPのGitHubレポジトリ群からYamlサンプルをCloneします。URLは こちら です。公式ではありますが、コミッターは第三者がメインなので、取り扱いには注意しましょう。
そのCloneしたレポジトリに入る前に、以下の環境変数をローカルで定義しておきましょう。SIDECAR_IMAGE_TAGはContainer Registryで確認可能です。
SIDECAR_IMAGE_TAG=<SidecarのContainerImageのタグ / 2020年12月1日現在の最新は0.8.0>
GCP_PROJECT=<起動先クラスタの所属するProject名 or ID>
GCP_REGION=<起動先Region名>
KUBE_CLUSTER=<起動先Cluster名>
DATA_VOLUME=<起動先のmount対象ボリューム / 実在していて既存の利用中のものとかぶらなければOK>
DATA_DIR=<起動先のmountディレクトリ / 実在していて既存の利用中のものとかぶらなければOK>
DATA_VOLUMEやDATA_DIRは、メトリクスをPod側に永続化させる必要が特にないのであれば、あまり深く意識しなくても良いと思います。
続いて、Cloneしたレポジトリに入り、まずはをprometheus-service-account.yamlをapplyしてPrometheusがメトリクスを取得したりする際に利用するServiceAccountを作成します。もし類似のものを事前に作っているのであれば、この手順は特に必要ありません。
ServiceAccountが完成したら、次はConfigMapです。prometheus-configmap.yamlをapplyすれば完了です。Prometheusのアプリケーション用の環境設定等もここに入っています。ちなみに、ScrapeIntervalはStackdriver Monitoringのメトリクス取得間隔に合わせてデフォルトで60sとなっています。基本的にこれより短くしても最短取得間隔が1分であるStackdriver Monitoringの上では確認できませんが、何らかの事情で取得間隔を伸ばしている場合は、それに合わせてConfigMap内のScrapeIntervalを調整すると良いと思います。
最後に、gke-prometheus-deployment.yamlをapplyすれば、Sidecarが起動します。Diskやイメージを準備する必要はないので、ほんの数秒で起動が完了します。それから60秒以内に最初のメトリクス取得とPushが始まります。
注意点
コストに気をつけよう
Prometheusでの監視は課金対象の外部監視となります。詳しく言い換えると、PrometheusのSidecarがメトリクスを取得してStackdriver MonitoringにPushして表示できるようにした場合、そのPushしたデータ分は「Metric Volume」というSKUでの課金対象となります。
Metric Volumeは最初の150MiBこそ無料であるものの、それ以降は100GiBまで$0.2580/MiB、そこから250GiBまで$0.1510/MiB、それ以上が$0.0610/MiBとなっています。累進割引にはなっていますが、何れにせよ単位が全てMiBになっている点に注意が必要です。
そしてデフォルトでは全てのメトリクスをPushするようになっているので、放っておくとかなりシビアな課金をされてしまいます。
コストをカットするには?
デフォルトのgke-prometheus-deployment.yamlでは、全てのメトリクスをPushするようになっています。これを制限して必要なメトリクスのみPushすれば、コストは大幅にカットすることが可能です。
gke-prometheus-deployment.yamlの47行目付近に起動時の引数が定義されています。ここにPrometheusフィルタを書いてあげれば、起動時に引き渡してくれます。例えば、稼働中Pod数を取得するkubelet_running_pod_count等を確認したい場合は、kubernetes-nodesだけを確認すれば良いので
- --include={job="kubernetes-nodes"}
と追記して再度gke-prometheus-deployment.yamlをapplyすれば最適化完了です。
このincludeの中にはPrometheusのクエリをそのまま書くことができます。もっと複雑なクエリを書いてメトリクスを増やしたり、最適化したり、そういったことも可能です。
結び
Prometheusは設定次第で色々なメトリクスが取得可能なため、モニタリングツールとしては底なし沼のような存在とも言われています。それ故に忌避する人も多いのですが、世の中に転がっている情報量も多いため、沼にはまらないよう気をつけてさえいれば非常に有用なツールだと思います。また、情報量ゆえに導入も簡単で、導入でかかった作業時間は実質2時間程度でした(値の反映待ちやフィルタ調整のすったもんだは別途必要になりましたが・・・)。
忌避されている技術でも好き嫌いせず試してみると、意外と自分たちにとっては使えることもあるんだなと思ったPrometheus導入のお話でした。