Google Kubernetes Engine から Cloud Run を使ったサーバーレス中心のアーキテクチャに移行した話

こんにちは。UltraImpression の技術担当です。

弊社の提供する UltraImpression Ad Manager(以下 UIAM)は 2020 年 4 月のリリース以来、Google Kubernetes Engine(以下 GKE)上で運用されてきましたが、このたび Cloud Run を中心としたサーバーレス アーキテクチャへの再構成を行い、2024 年 2 月末をもってすべての GKE クラスタを削除するに至りました。

本記事では、UIAM が GKE 上に構築された経緯とそこに生まれた課題、そしてその課題を Google Cloud のマネージドサービスの進化とともに解決した事例を紹介します。


2019 年: GKE の採用

GKE は Google のインフラを使用して管理される Kubernetes のマネージドサービスです。

アプリケーションコンテナが仮想マシンに代わるコンピューティング層として利用されるようになると、次に必要となったのはそれらのコンテナを管理・運用するコンテナオーケストレーションツールでした。

さまざまなコンテナオーケストレーションツールが登場してきましたが、UIAM の開発をはじめた 2019 年には、Kubernetes が事実上のデファクトスタンダードとなっていました。そこで、私たちは既にリリースされていた GKE を採用することにしました。

GKE の課題

GKE は問題なく機能し、安定したサービスの提供を可能にしていましたが、運用をつづけていくにつれ、課題も見えてきました。

固定費の問題

GKEを利用する場合、クラスタを常に起動しておく必要があります。これにより、使用量に関係なく固定費が発生します。私たちのワークロードに対して、このコストは重荷になっていました。

学習コスト

Kubernetes は非常に強力なオーケストレーションツールですが、その分複雑であり、使いこなすまでに高い学習コストがかかります。結果、小さなチームの中でもごく少数のメンバーしか管理することができず、属人化が問題となっていました。

また、Kubernetes の持つ豊富な機能群も、そのほとんどは私たちにとっては不要なものでした。

Google Cloud のサーバーレス ソリューションの制限

以上の課題を解決する代替サービスとして、Google Cloud のサーバーレス ソリューションである Cloud Run が候補にあがりました。Cloud Run は以下の特徴を持っています。

  • コンテナベースのアプリケーションを実行する

  • Knative を基盤とするマネージドサービス

  • スケーリングと従量課金

アプリケーションはコンテナベースなので、GKE で利用していたコンテナをそのまま移行できます。その上で、Kubernetes では必要不可欠だった Deployment や Pod などの構成や、その設計を行う必要はありません(Knative は Kubernetes でサーバーレスアプリケーションを動作させるランタイムですが、Cloud Run を利用する上ではその存在を意識することはほぼありません)。

アプリケーションはリクエストベースで自動的にスケーリングし、利用されていないときには縮退するため固定費を削減できます。

しかしながら、Cloud Run で完全にサービスを置き換えるには、2020 年当時では以下の制限が障壁となっていました。

常駐プロセスが実行できない

Cloud Run で実行するサービスは、あくまで Web アプリケーションであるため、外部からの HTTP リクエストに応じて起動やスケールが行われています。つまりデーモン(Daemon)と呼ばれる、外部アクセスとは関係なく常時起動しているようなプロセスは Cloud Run 上では動作させることができませんでした。

バッチ処理の実行時間に制限がある

Cloud Run はバッチ処理を行う場合にも、バッチ用の URL エンドポイントを用意した上で HTTP リクエストを通して呼び出す必要があります。そしてそこには 60 秒というタイムアウトが設定されていました。通常の HTTP レスポンスを返す場合は気にするまでもない制限ですが、バッチ処理を行うには不十分です。2020 年 10 月には 60 分にまで緩和されましたが、それでもバッチ処理に利用するには短すぎました。

2023 年: Cloud Run への移行

以上の制限から、UltraImpression Ad Manager は長らく GKE 上で運用されてきました。しかし、2023 年までに追加されたさまざまな機能により、Cloud Run への移行を選択するに至りました。

Cloud Run の進化

Cloud Run は、その最初のリリースからわずか数年の間に革新的な機能拡張を行っており、ますます利便性の高いツールに進化しています。

Cloud Run のウォームアップと Always on CPU

2021 年 3 月に、最小インスタンス数が設定できるようになりました。これにより、外部からのリクエストがなくても最低 1 インスタンスは起動させておくことが可能になりました。

しかし、これだけでは常駐プロセスを実行するには不十分です。Cloud Run はリクエストを処理している間のみ CPU の割り当てが保証されているので、インスタンスは立ち上がっていても満足に処理を継続できません。

この問題を解決するために、2021 年 12 月に Always on CPU が登場しました。この 2 つの機能により常駐プロセスと同等のアプリケーションが実装できるようになりました。

Cloud Run Jobs

前述したように Cloud Run は Web アプリケーションとして実装、デプロイするものでした。対して 2023 年 3 月にリリースされた Cloud Run Jobs は、その名の通りバッチ処理を実行するためのものです。HTTP リクエストに依らず、任意のタイミングでコンテナ化した処理を実行でき、さらには最長 24 時間もの長時間の実行が可能となりました。

移行時の注意点

こうした Google Cloud 側の機能追加により、要件を損なうことなく移行できる確証が得られたため、2023 年度に再構築を行うことにしました。

ただし、GKE で構築していた部分のいくつかについては、そのまま移行できなかったため、以下のように対処しました。

ロードバランサーと TLS 証明書

GKE ではロードバランサーに Ingress を使い、TLS 証明書の発行・更新には cert-manager を使っていましたが、そのどちらもが Kubernetes で動作するコンポーネントでした。

再構築後は、ロードバランサー、TLS 証明書の管理は共に Google Cloud の Cloud Load Balancing(GCLB) に移行しました。GCLB で TLS 証明書を発行するためには、対象となるドメインが GCLB に紐づく IP を参照していなければならないため、以下の順で移行を行いました。

  1. 静的外部 IP アドレスを予約する

  2. そのアドレスを GCLB に紐づける

  3. Cloud DNS で、利用するドメインの A レコードの IP アドレスを今回発行した IP アドレスに変更する

  4. 変更が反映されたら TLS 証明書を発行し、プロビジョニングされるのを待つ

3 から 4 の間にはダウンタイムが発生しますが、だからといって先に 4 の TLS 証明書発行をしてはいけません。ドメインはまだ GKE の Ingress を参照しているため、プロビジョニングに失敗してしまいます。

その後に 3 を行っても、再プロビジョニングがいつ行われるかはまったくコントロールできないため、余計にダウンタイムを長引かせてしまうことになってしまいます。

ConfigMap / Secrets の移行

GKE では各 Pod の、Cloud Run においては各サービスで利用する設定値は、前者では ConfigMap および Secrets で管理していました。しかしこちらも Kubernetes の機能であるため移行する必要があります。

UIAM では Terraform でインフラの管理を行っているため、ConfigMap の管轄にあった設定値は単純に Terraform の Variables に移行しました。Secrets に関しては Google Cloud の Secret Manager に移行しています。

まとめ

現在は Cloud Run に移行して半月ほどですが、目に見えた性能の劣化や障害などは起こっていません。Kubernetes は確かに有用なソリューションですが、要件によってはオーバースペックになってしまいます。

最後に、現時点での移行の影響・効果をパフォーマンスと費用の観点から紹介します。

パフォーマンス

常時起動の必要のないサービスに関しては最小インスタンス数や Always on CPU の設定を施していないため、コールドスタンバイの状態では起動時に 1 ~ 2 秒の遅延が入るようになりました。

しかしこれは、その遅延が許容できない場合は、そのサービスのみ設定を変えてデプロイしなおせば良いだけです。GKE では想定される CPU 数や RAM の最大値をクラスタに設定していたため、一部のヘビーなサービスのために固定費が嵩んでいました。

費用

約半数を占めていたクラスタの費用がまるごと削減されました。今まで GKE が担ってきた処理がすべて Cloud Run に移行され、その分の利用料が課金されるため、単純に半減とまではいきませんが、かなりの固定費が削減されることになりそうです。こちらに関しては従量課金となるため、引き続き監視していくことになるでしょう。


この記事が気に入ったらサポートをしてみませんか?