【書き起こし】Microservice Dashboard Introduction and Deep Dive – Yuta Uekusa【Merpay Tech Fest 2022】

Merpay Tech Fest 2022 は、事業との関わりから技術への興味を深め、プロダクトやサービスを支えるエンジニアリングを知ることができるお祭りで、2022年8月23日(火)からの3日間、開催しました。セッションでは、事業を支える組織・技術・課題などへの試行錯誤やアプローチを紹介していきました。

この記事は、「Microservice Dashboard Introduction and Deep Dive」の書き起こしです。

それでは、始めさせていただきます。本日は「Microservice Dashboard Introduction and Deep Dive」というタイトルで、メルペイのUekusaが発表させていただきます。このセッションでは、私達が開発しているマイクロサービスのためのダッシュボードのご紹介をいたします。
マイクロサービスを運用していく中で出てきた課題を、Microservice Dashboardによってどのように解決しているのか。また、そのための機能と仕組みについてご共有できればと思います。よろしくお願いいたします。
まずは、簡単に自己紹介をさせてください。

私は、Engineering Productivityチームに所属しているUekusaと申します。経歴としましては、2018年1月にメルペイに参画し、テックリードとしていくつかのマイクロサービスの開発に携わりました。その後、Architectチームに異動し、API Gatewayの開発や今回お話しするマイクロサービスのためのダッシュボードの開発に携わりました。
今年の1月にArchitectチームから分離して、別チームとなったEngineering Productivityチームで引き続きMicroservice Dashboardの開発を担当しています。
では、本日お話しすることです。

最初にMicroservice Dashboardとは何か、このサービスを開発するに至った経緯についてご紹介します。
次に、Microservice Dashboardで使っている技術スタックやアーキテクチャと、持っている機能の中から5つに絞って、その機能や仕組みを詳しくご紹介します。
最後に、APIを活用したデータの二次利用では、Microservice Dashboardが提供しているAPIと実際の活用事例についてご紹介いたします。

Microservice Dashboardについて

では最初に、「Microservice Dashboardについて」。Microservice Dashboardとは何か。また、開発している背景についてお話させていただきます。

Microservice Dashboardとは一言でいうと、全てのマイクロサービスの情報を収集し、可視化することを目的とした社内サービスです。社員アカウントがあれば誰でもブラウザからアクセスし、マイクロサービスの情報を簡単に閲覧できるようになっています。また、集めたデータをAPIで提供していて、他のシステムから活用してもらえるようにしています。実際のAPIの活用事例については、後ほど詳しくご紹介します。

開発の経緯です。メルペイの成長につれて数多くのマイクロサービスが運用されていく中で、一つひとつのマイクロサービスの情報を把握することがだんだん難しくなっていきました。
例えば、サービスの概要やどのようなSLOが定義されているのか。開発しているチームメンバーや、普段サービスについて会話しているSlackチャンネル、オンコールのためのPagerDutyの設定など全て把握しようと思うと、いろいろなサービスを一つずつ調べる必要があり、とても大変です。
少しでも把握しやすくするために、これらの情報を各マイクロサービスごとに運用ドキュメントとして社内Wikiにまとめていました。しかし、メルペイの開発規模が大きくなっていくにつれて、全てのサービスを網羅したり継続した更新をしたりといった管理が難しくなっていきました。
そこで、まずはこの運用ドキュメントの管理をなくして、マイクロサービスの情報の把握を簡単にすることを目標に、2019年12月頃に開発がスタートしました。

Microservice Dashboardの機能と仕組み

では、「Microservice Dashboardの機能と仕組み」について詳しくご紹介していきたいと思います。

まずは使っている技術スタックです。BackendはGoで実装しています。GCPのサービスはCloud Spanner、Pub/Sub、Schedulerを使っています。APIはGraphQLとgRPCがあります。
Frontendは、TypeScriptで実装しています。フレームワークはReactを使っており、UIツールにMaterial-UIを使っています。表示するためのデータはGraphQLを使って取得しています。

次にMicroservice Dashboardのアーキテクチャです。こちらはSingle Page Applicationになっています。
運用コストを減らすために、GoのサーバーでFrontendのビルドファイルも配信しています。Webアプリの認証はGoogle OAuthを利用していて、社員アカウントであれば誰でもログインできるようになっています。

また、APIはgRPCとGraphQLの二つです。gRPCは、Cloud Pub/SubとSchedulerのリクエストを受け取るために用意しています。リクエストはHTTP Requestで来ますが、前段のAPI Gatewayが共通の仕組みでgRPCへ変換しています。
GraphQL APIは、他のシステムからデータを活用してもらうために用意しているものです。Googleサービスアカウントの認証情報を使って利用できるようになっています。

続いて、Microservice Dashboardの持っている機能の中から、スライドの5つに絞ってその機能や仕組みについてお話させていただきます。

はじめに、サービスの情報を可視化する機能についてご紹介いたします。この機能は、マイクロサービスの情報を簡単に把握できるようにすることを目的とした機能です。サービスの概要や開発しているチームメンバー、そのサービスについて話をするためのSlackチャンネルなどを一目でわかるようにすることで、開発者が自分たちのサービスだけでなく、他のサービスの理解にも役立てることを期待しています。
また、新しく入ってきたチームメンバーのためのオンボーディング資料の一つとして活用することも期待しています。
マイクロサービスの情報をまとめるために集めているデータは主に二つあります。

一つ目が、マイクロサービスStarter-kitです。メルペイでは、マイクロサービスの構築にMicroservice Starter-kitというツールを利用しています。このツールは、Platformチームが提供しているTerraform moduleです。マイクロサービスの初期構築に必要なインフラリソースを自動的に用意してくれるものになります。
このStarter-kitにはサービスIDと呼ばれる、サービスを一意に識別するためのIDが定義されていて、Microservice Dashboardは情報をまとめるためにこのIDを利用しています。

二つ目が、Microservices Specです。マイクロサービスの情報の中には、インフラリソースを宣言的に管理するStarter-kitだけでは表現できないメタデータがあります。そのようなメタデータを表現するために、Microservices Specという定義を用意しています。
具体的には、service.yamlというYAMLファイルでサービスの概要やSlackチャンネルやドキュメントのリンクなどが記述できるようになっています。YAMLファイルの構造はprotobufで定義しています。protobufで構造を定義することで、入力のバリデーションやメッセージのマーシャリングなどを機械的に扱いやすくしています。

これらのStarter-kitやSpecファイルは、具体的にはmicroservices-terraformというGitHubリポジトリで管理されています。microservices-terraformリポジトリは数百を超えるマイクロサービスのTerraformファイルを管理しているMonorepoです。サービスごとにディレクトリが区切られていて、Starter-kitの設定を含むTerraformファイルやSpecファイルが、この図のような構成で置かれています。

こちらはMicroservice Starter-kitのデータを集める仕組みの図になります。Starter-kitのデータは、microservice-terraformリポジトリをgit cloneしてStarter-kitのTerraformファイルをパースすることで取得しています。取得したデータはサービスIDごとにまとめてデータベースに保存。この処理はCloud Schedulerをトリガーとして1日2回実行しています。

Microservices SpecファイルはPub/Subのプッシュ配信で連携し、microservices-terraformリポジトリのCIからSpecファイルをpublishしています。
Specファイルはpublishする際に、YAMLからprotobufメッセージへ変換しています。protobufメッセージへ変換することで、未定義のフィールドがあったらエラーとなり、そこで気づくことができます。
また、protoc-gen-validate(PGV)というプラグインを使い入力のチェックを行っています。Microservice Dashboardは、Pub/Subのメッセージを受け取ったら、それを扱いやすい形に加工してデータベースに保存しています。
基本的にファイルの変更をトリガーとしてメッセージをpublishしていますが、取りこぼしたときのために1日1回全てのマイクロサービスのSpecファイルをpublishするようにしています。
そうして集めたマイクロサービスの情報を可視化した画面がこちらになります。

こちらのサービス一覧画面では、全てのマイクロサービスとそれに紐づいたチームや概要などが一覧できるようになっています。こちらのデータは、マイクロサービスの棚卸にも活用されていたりします。

こちらはサービスの概要画面になります。Slackチャンネルやドキュメントへのリンクといった情報が載っているので、マイクロサービスの基本的な情報を知りたければ、この画面を見れば大体のことがわかるようになっています。

チームの情報ですが、メルペイでは、チームの管理にMicroservices Team-kitというツールを利用しています。このツールは、Starter-kitと同様にPlatformチームが提供しているTerraform moduleで、チームのメンバーリストやリソースに対する権限を、宣言的に管理できるようになっています。
Starter-kitからTeam-kitを紐付けることができるので、その情報を基にMicroservice Dashboardもサービスとチームの紐付けを行っています。Team-kitのデータは、先ほどご紹介したStarter-kitと同じ仕組みで集めています。
集めたチームの情報を可視化した画面がこちらになります。

チームのメンバーが一覧できて、誰がどの役割なのか一目でわかるようになっています。GitHubアカウントやSlackのメンション先もデータとして集めていて、この画面で把握できるようになっています。
メンバーの役割が明確にわかるようになったことで、例えば他のチームのマネージャーに何か相談事があるときなど、誰がマネージャーなのかといったことを調べる手間が少なくなって便利になりました。

続いて、サービスの情報資産を可視化する機能についてご紹介いたします。

この機能は、マイクロサービスがどういった情報資産を保有しているか把握できるようにすることを目的とした機能です。マイクロサービスの持っている情報資産をシステム的に管理することで情報資産の棚卸を効率化したり、サービスの重要度を把握することで情報セキュリティ対策の分析に役立てることを期待しています。

サービスの情報資産は、現在個人情報のみを対象としてデータ化しています。個人情報の分類をprotobufで定義して、マイクロサービスのメタデータとしてSpecファイルに記述できるようにしています。各マイクロサービスのオーナーが自分たちの管理している情報資産について、Specファイルに記述する責任を持っている形です。
個人情報の分類は、個人情報区分と個人情報の種類のマトリックスで定義しています。区分と種類の組み合わせによって決まるサービスの重要度も同様に定義しています。例えば、お客さまという区分とクレジットカードという情報の種類の組み合わせだったら、重要度はトップシークレットになる、といったような形です。

集めたデータを可視化した画面がこちらになります。上の列が個人情報区分で、左の行が個人情報の種類です。今回の例ですと、Customer列のCredit Information行にチェックが入っているので、お客さまの残高情報などを持っているサービスということがわかります。

また、集めたデータを基に情報資産台帳を自動生成することが可能です。情報資産台帳とは、情報資産を適切に管理するために部署の扱っている情報資産を一つに取りまとめた資料のことです。以前はこの資料を手動でスプレッドシートに管理していて大変だったと聞いています。しかし、今は集めたデータから自動生成することができるようになったため、大きな効率化に繋がっていると思います。

続いて、サービスの依存関係を可視化する機能についてご紹介いたします。

この機能は、マイクロサービスの呼び出し元と呼び出し先をわかりやすく把握できるようにすることを目的とした機能です。知らないサービスからリクエストを受けていないか、意図しないサービスへリクエストをしていないか、開発者が気づけるようにしています。

サービスの依存関係は三つの異なるデータを基にそれぞれグラフ化しています。一つ目はDatadogのService Dependency APIです。二つ目はMicroservices Terraformリポジトリで管理しているNetwork Policyの設定です。三つ目は、マイクロサービスの環境変数に設定されている値です。メルペイのマイクロサービスはほぼ全てのサービスで、環境変数にリクエストの宛先を設定しているので、三つ目のデータが最も信頼できると思っています。

今回は、三つ目の環境変数を基に依存関係グラフを作成する仕組みについてご紹介いたします。メルペイのマイクロサービスはKubernetesの上で動いています。Kubernetesにはコントローラーという特定のリソースの状態変化に応じて任意の処理を行う仕組みが用意されています。
この仕組みを使って、マイクロサービスの環境変数を取得するためのカスタムコントローラーを開発しています。具体的には、カスタムコントローラーの扱うリソースにPodとCronJobを指定し、そのリコンサイル処理でnamespace内のConfigMapを含む環境変数を取得しています。
取得した環境変数の中から、宛先のパターンに当てはまる文字列を抽出して、データベースに保存。PodとCronJobリソースのリコンサイルはかなり数が多いため、キューイングシステムで処理の流量を調整しています。

このようにして集めたデータを可視化した画面がこちらになります。左側の青い枠のサービスが呼び出し元で、右側の赤い枠のサービスが呼び出し先です。
この例ではkouzoh-echo-jpサービスがメルカリやメルペイのgatewayサービスからリクエストを受けていて、メルカリのautholityサービスにリクエストしている様子がわかるようになっています。

続いて、サービスのコストを可視化する機能についてご紹介いたします。

この機能は、組織のメンバーがコスト最適化できるサービスを探したり、開発チームがサービスのコストの状態を把握できるようにすることを目的とした機能です。

サービスのコストの情報は、Platformチームが毎月BigQueryに集計しているデータを利用。現在はGCP、GKE、Datadogの三つのコストを対象として集めています。

こちらは、サービスのコストの情報を集める仕組みの図です。毎月1回BigQueryに費用のデータを取得するクエリを実行して、取得したデータをサービスIDごとにまとめてデータベースに保存しています。

そうして集めたデータを可視化した画面がこちらです。月ごとのコストの履歴を6ヶ月分グラフ化しています。開発者が過去と比較してコストの状態に変化がないかどうか、ここを見て確認できます。

また、全てのマイクロサービスのコストの履歴をまとめたダッシュボード画面も用意しています。この画面ではマイクロサービスごとのコストの履歴を一覧で見ることが可能です。過去数ヶ月分の全てのマイクロサービスのコストの動向がわかるようになっています。

最後に、サービスの品質を可視化する機能についてご紹介いたします。

この機能は、マイクロサービスの信頼性について、開発チームだけではなく組織のメンバーも把握できるようにすることを目的とした機能です。メルペイSREチームが主導して開発している機能になります。
参考資料:メルペイにおけるSLOの活用事例 – 信頼性を定義しよう

品質を可視化するために、マイクロサービスのSLOのステータスを利用しています。メルペイでは、SREチームによってマイクロサービスのSLOの設定をサポートする基盤が整備されています。SLO moduleというTerraform moduleが提供されていて、DatadogのSLOモニターなどを宣言的に管理しています。

こちらは、SLOのステータスを集める仕組みの図です。SLO moduleファイルはmicroservices-terraformに置かれていて、Datadogにリソースを作成するとPub/SubでそのリソースのIDがMicroservice Dashboardに連携されるようになっています。Microservice DashboardはそのリソースのIDを使って、1日1回Datadog APIからSLOのステータスを取得し、データベースに保存しています。

このようにして集めたデータを可視化した画面がこちらです。マイクロサービスのSLOの履歴と、各モニターのSLOのステータスがわかるようになっています。履歴は、週ごと、月ごと、クォーターごとに確認できるようになっていて、その期間SLOを維持できていたかどうかが簡単に把握できるようになっています。

また全てのマイクロサービスのSLOの履歴をまとめたダッシュボード画面も用意しています。この画面では、マイクロサービスごとにSLOを維持できているかどうかが一覧できます。もしSLOを維持できていないマイクロサービスがあれば、この画面のように赤くなるので、簡単に見つけられます。

APIを活用したデータの二次利用

では最後に、Microservice Dashboardが提供している「APIを活用したデータの二次利用」についてご紹介いたします。

Microservice Dashboardは、集めたデータを社内で有効活用してもらうためにAPIを提供しています。様々なデータを正規化して再利用性を高めておくことで、異なるユースケースで同じようなデータが必要になったときに便利に使うことができます。また、それによって業務の自動化を推進して生産性の向上に繋げたいという思いもあります。
このAPIはシステムからだけではなく、個人でも利用できるようになっています。
GraphQLを採用した理由は、単に使ってみたかった、というところが大きいです。しかし実際に使ってみたところ、ユースケースに縛られない柔軟性という特徴が、どのような使われ方をするか予想できないMicroservice DashboardのAPIと相性が良かったと感じました。

では、実際の活用事例を二つほどご紹介いたします。一つ目は個人で活用している事例です。Slackの@hereなどで、各マイクロサービスに何か対応のお願いをすることがあります。しかし、中にはなかなか対応を進めてもらえないマイクロサービスが出てくることもあります。

そんなときはマイクロサービスのオーナーに直接メンションして対応のお願いをします。しかし、そのようなマイクロサービスが複数あるとメンション先を調べるのが大変です。そこでメンション先を一括取得するためにAPIが活用されています。

こちらは、curlを使ってデータを抽出する例です。認証用のIDトークンを取得して必要なクエリをパラメータに渡してリクエストすると、実行結果としてデータが返ってくる、という図です。この例は、サービスリソースに関連しているチームリソースの中から、チームメンバー全員のメンションを取得するクエリを表しています。
このようなデータ抽出は、社内アカウントを持っていれば手順に従ってAPIの利用登録をしていただくことで、誰でも利用できます。

二つ目は、システム的に活用されている事例です。
参考資料:Shifting to Zero Touch Production

メルペイでは、一時的な権限の取得にCarrierというツールを使っています。CarrierはPlatformチームが開発しているツールで、指定のサービスに対してGCPやKubernetesのRoleをリクエストできます。サービスのオーナーがリクエストを承認すると、一時的に権限が付与されるようになっています。本番環境などで作業する必要があるときに利用されています。

Carrierは左の画面のような入力フォームを持っています。権限付与をリクエストするために必要な情報をこのフォームに入力すると、指定したサービスのSlackチャンネルに右の画面のような、リクエストの承認を求める通知が行われます。この処理の裏側では、入力されたサービスIDの確認だったり、通知先のSlackチャンネルを取得したりするためにAPIが活用されています。このようなシステムは、サービスアカウントを手順に従って登録していただくことで利用できるようになっています。

それではまとめです。本日は私達が開発しているMicroservice Dashboardのご紹介をいたしました。全てのマイクロサービスの情報を収集し可視化するためには、情報をまとめる必要があります。情報をまとめるためには、情報の整理が必要です。
メルペイでは、Platformチームが整備しているInfrastructure as Codeを利用して、マイクロサービスの情報を規則性をもって宣言的に管理していることが情報の整理をする上で大きな利点となりました。今後も集めるデータは、コードとして表現できる形で管理していきたいと思っています。また、引き続き社内のエコシステムの一部として、APIの利用を広げていきたいです。

以上で私の発表を終わります。ご清聴ありがとうございました。

  • X
  • Facebook
  • linkedin
  • このエントリーをはてなブックマークに追加