HireRooのインフラ基盤をCloud RunからKubernetesへ移行しモノレポで管理し始めた話

目次

はじめに

こんにちは。株式会社ハイヤールーの伊藤(@icchy_san)です。 弊社では Cloud Run 環境から Kubernetes 環境へシステムを移行をすると同時に分散したリポジトリ管理からモノレポに変更しました。 移行前と移行後を比較して、改善されたことについて紹介していきます。

弊社と同じように Cloud Run のようなサーバレス環境でマイクロサービス開発をしている人や、Cloud Run から Kubernetes への移行について興味のある人に、移行の判断基準の 1 つになるような知見を共有したいと考えています。

TL;DR

Cloud Run から Kubernetes 環境に移行したことで以下のように改善しました。

  • クライアントとサーバーの結合テスト開始までの時間が5 分から 0〜1 分に短縮された。
  • Gateway の奪い合いが無くなり、各サービス開発者が自由に更新可能になった。
  • Cloud Run の時に比べて技術的な拡張性や選択肢の幅が広がった。
  • Cloud Run の時に比べてレイテンシーが約 1sほど短縮された。
  • 分散していたリポジトリをモノレポにすることで凝集度が上がり、保守性が上がった。

移行前の設計と課題

移行前の設計は Cloud Run ベースのマイクロサービスアーキテクチャでした(詳細は別記事:HireRoo を支えるマイクロサービスたちのご紹介)。

HireRoo を支えるマイクロサービスたちのご紹介より引用した図を図 1 として次に示す。

図 1 の通りマイクロサービスは Cloud Run で稼働していました。 Cloud Run で稼働していたため弊社のアプリケーションでは以下のような課題がありました。

課題 1: サーバレスと弊社のアプリケーションの相性問題

例えば、Cloud Run ではファイルをすべてインメモリに保存されるため(ファイルシステムへのアクセス)、ファイルサイズによってはメモリが枯渇しサーバーが起動しない可能性があり、厳しい制約の中でスケールさせなければならなず調整が困難であることや、他にも僕らのユースケース上調整が困難な場面がある。

課題 2: 統合テストにおけるリードタイムの問題

ウェブブラウザを通した結合テストを行うためには**、**CI でアプリケーションイメージをビルドし、更新のたびに Cloud Run へデプロイする必要があるため時間がかかる。

課題 3: 開発時における Gateway の占有問題

クライアントからの HTTP/JSON リクエストを gRPC へコード変換する役割(HTTP/JSON の gRPC へのコード変換)を持つ Gateway は開発者間で共有されるリソースであるため、開発時に作業がコンフリクトしてしまい一人しか開発できない。

課題 4: Cloud Run のコールドスタートによるレイテンシー増大問題

Cloud Run では起動時にコンテナイメージを Pull する必要があり、Cloud Run から別の Cloud Run を呼ぶ際にコールドスタートがレイテンシーを増大させる。

課題 5: 分散したリポジトリによる問題

リポジトリが分散しているため、依存関係のあるインターフェースの変更を各マイクロサービスごとに変更のプルリクエストを作成する必要があったり、変更をデプロイするべくインフラストラクチャ管理用のリポジトリにリリース用の PR を作成する必要があり、レビュー時にレビューコストが高い。 また、複数の IDE を起動する必要があるため、マシン負荷が高くなる。

これらが Cloud Run ベースのインフラストラクチャの課題でした。 次にどのような設計・実装で課題を解決したのか紹介します。

移行後の設計と改善された点

下図は、図 1 と対比する形で表現したアーキテクチャ図で、移行後の全体の大まかな設計を表しています。

移行後はこれまで Cloud Run で稼働していたサービスは全て Kubernetes の Pod 上で稼働するようになりました。

また、Kuberentes への移行で前節で述べた課題 1〜5 を解決できました。

課題 1: サーバーレスと弊社のアプリケーションの相性問題の解決

Kubernetes は GCE インスタンスを Node として管理しており、GCE は Cloud Run に比べてよりカスタマイズでき、例として挙げたCloud Run の制約によるローカルストレージの上限の低さの問題などが解消された。

課題 2: 統合テストにおけるリードタイムの問題の解決

クライアントを通した統合テストを行う際にTelepresenceを利用することで、ローカルで起動しているサーバーを Kubernetes 内のサーバーとの接続を可能にし、ビルド時間などの短縮が可能になった

課題 3: 開発時における Gateway の占有問題の解決

Gateway に設定するルーティングや認証機能を各サービスの namespace 配下で行うことができるため、開発時のコンフリクトがなくなり、自由に更新できるようになった

課題 4: Cloud Run のコールドスタートによるレイテンシー増大問題の解決

Kubernetes に移行したことで、サーバフルなインスタンス(GCE)を利用するようになり、リクエストのたびに発生する Cloud Run の起動時間を考慮する必要がなくなり、レンテンシーを 1s ほど短縮することができた。

課題 5: 分散したリポジトリによる問題の解決

モノレポで管理することで、分散してた時と比べて依存関係のあるサービス同士のインターフェース変更をまとめて 1 つのプルリクエストで完結するようになったためレビューコストの削減や、変更全体の見通しの良さが上がった。

移行完了までのスケジュール

Kubernetes の作業者と期間は以下の通りです。

  • 3 人(バックエンド開発者)
  • 3 ヶ月(2022 年 6 月〜2022 年 8 月)

これらの人数と期間で次のような議論を実施しました。

なぜモノレポを選択したのか?

移行初期では次の 2 つの選択肢がありました。

  1. Git のサブモジュール機能を使って分散したリポジトリを一つに集約し擬似モノレポにする方法
  2. 1 つのリポジトリで全てのファイルを管理する方法

初めは 1 方法で進めようという話になりましたが、最終的に 2 に落ち着きました。

方法 1: サブモジュールを利用したモノレポ

各サービスのデプロイやリソースの管理はモノレポ側、各サービスの開発は各分散したリポジトリ側という棲み分けをするというものでした。すると、モノレポ側にある各サービスのコミットハッシュを見ることで今どのバージョンが出ているのか把握しやすくなり、不要なサービスはローカルにクローンする必要がなく軽量化されるメリットがありました。

方法 2: すべてのファイルを単一のモノレポで管理

サブモジュールにすることにより、CI で毎回サブモジュールを取得する必要がありビルドの時間が延びてしまったり、管理するリポジトリが結局増える懸念がありました。今出ているバージョンがコミットハッシュで分かるというメリットはありましたが、この設計に限った話ではなく、また、あえてリポジトリを分散させて CI を必要以上に複雑にする必要はないため、サブモジュールを使わないモノレポを選択しました。

実際の移行方法

移行方法としては、Cloud Run で稼働しているすべてのマイクロサービスを Kubernetes 上に構築後、Cloud Run 側に流れているトラフィックを全て Kubernetes 側に一括でシフトするLift and Shiftを採用しました。そのため不具合があった場合でもすぐにロールバックができる状態で移行したため、スムーズに進めることができました。

対応が終わったマイクロサービスから移行することもできましたが、その場合開発基盤ができるまでは新旧のリポジトリ両方を管理をする必要があり、移行班の作業リソースのみで全マイクロサービスを管理するのは厳しく、ずるずると移行作業が延びてしまうのを避けたかったためです。

おわりに

本記事では移行前後の設計の全体像の比較と移行後に解決した課題、そして移行完了までのスケジュールについて述べました。

Kubernetes に移行したことで技術的な拡張性や選択肢の幅が広がり、より一層顧客要望に応えることができるシステムになりました。さらに、Datadogサービスメッシュの導入により監視システムの強化を計りました。

また、もともと Cloud Run で稼働していた多くのサービスを全て Kubernetes 上に移行するために約 3 人で 3 ヶ月ほどで移行を完遂しました。

次回予告

次回以降の記事ではテーマを分けて実装レベルで詳細に書いていく予定です。少しでも興味のあるテーマがあれば幸いです。

以下に今後公開を予定している記事のテーマを載せておきます。

  • Cloud Run vs KubernetesCloud Run の時の設計と Kubernetes になったあとの設計を比較しながら、ここがよかった、ここがよくなかったを紹介
  • モノレポに関する記事モノレポになったことで変わった CI の設定やディレクトリ構造などをコードベースで紹介
  • マイクロサービス開発における DXTelepresence を用いた開発や Kubernetes 周りのツール紹介
  • Datadog 導入により変わったトラッキングの世界Datadog の分散トレーシングの導入、そしてその効果についての紹介

ではまた次の記事で。✋