【TECH BLOG】FAANSにおけるCloud RunからGKE Autopilotへのリプレイス事例
はじめに
こんにちは。ブランドソリューション開発本部 WEAR部 SREの笹沢(@sasamuku)です。
FAANSはショップスタッフの効率的な販売をサポートするスタッフ専用ツールです。FAANSの一部機能は既にリリースされており全国の店舗で利用いただいております。正式リリースに向け、WEARと連携したコーディネート投稿機能やその成果をチェックできる機能などを開発中です。
FAANSのコンテナ基盤にはCloud Runを採用しており、昨年にSREとしての取り組みをテックブログでご紹介しました。しかし、運用していく中で機能需要や技術戦略の変遷があり、Cloud RunからGKE Autopilotへリプレイスすることを決めました。本記事ではリプレイスの背景と、複数サービスが稼働している状況下でのリプレイス方法についてご紹介します。
リプレイスの背景
なぜCloud Runだったのか
そもそもなぜCloud Runを採用していたのか簡単に振り返ります。詳細は昨年の記事をご覧ください。
コンテナ化されたアプリケーションを利用する前提で、開発・運用両面の要件を満たせるサービスには、Cloud RunとGKEがありました。ここでの要件とは、「Goのバージョン1.16をサポートしていること」と「サーバレスなコンテナ基盤であること」の2つです。Cloud Run採用の決め手は構築・運用コストの低さです。リリース当初、Kubernetesを運用できるほど人員が潤沢ではなく、時間的な制約もありました。実際、Cloud Runは非常にシンプルで、素早く利用開始でき、GCPサービスとの連携も容易にできます。おかげでリリースまでに構築を終えられましたし、追加要件にもスピーディーに対応できました。
なぜGKEに移行したいのか
GKEに移行する理由は2つあります。
- Cloud Runはサイドカーコンテナ非対応である
- コンテナ運用におけるチーム標準をKubernetesにする
まず、「1.」について説明します。Cloud Runはserviceと呼ばれる単位で管理されます。1 serviceにデプロイできるのは1コンテナのみとなっており、サイドカーコンテナは利用できません。弊社では主な監視ツールにDatadogを利用しています。サイドカーコンテナとしてDatadog Agentを構成できないことはトレース取得の観点で痛手でした。Datadog Agentを直接アプリケーションコンテナにインストールする方法も考えられますが、イレギュラーな対応を要するため見送りました。
次に、「2.」についてです。私達のチームは、FAANSの他に2つのプロダクトを運用しています。これらはECSを採用していましたが、デプロイやスケールのさらなる柔軟さを求め、EKSへの移行が検討されていました。FAANSも足並みを揃えてGKEに移行することにより、チームが利用するコンテナ基盤をKubernetesに統一できます。こうすることで、プロダクト毎の技術差異が抑えられ、運用負荷の軽減、ノウハウ横展開による効率化を実現できると考えました。
なぜGKE Autopilotなのか
GKEにはStandardとAutopilotの2つの運用モードがありますが後者を採用しました。その主な理由は、運用負荷が軽減されるためです。
Standardは、マスターノードはマネージドであるものの、ワーカーノードの管理はユーザに委ねられます。一方のAutopilotは、ワーカーを含む全てのノード管理がマネージドです。そのため、マシンタイプ選定やオートスケーラー構成といったノードに関する対応は必要ありません。Pod仕様に応じて自動的に必要サイズのノードが必要数プロビジョニングされます。
ただ、大規模トラフィックや急峻なスパイクが見込まれるケースではStandardの利用が推奨されています8。FAANSはtoBアプリケーションであり、そうした傾向は現在のところありませんでした。そのため、Autopilotの恩恵をありがたく享受することにしました。
Autopilotの制限事項により利用できるHelm Chartに制限が生じることもありましたが、現在のところクリティカルな影響は生じていません。これについては後述します。
リプレイスの全体像
制約条件
リプレイスを進める上で、まず始めに制約条件として下記を掲げました。
- サービスをメンテナンスモードにしない
- アプリケーションのリリースを停止させない
- アプリケーションコードの改修は最小限にする
FAANSはリリース済みのサービスであり、メンテナンスモードにするには各所へ調整が要ります。そのため無停止で完了させる方針としました。また、機能開発が盛んな状況だったため、コードフリーズは行わず開発の足かせとなる改修も極力避ける方針としました。
アーキテクチャ
それでは、新旧アーキテクチャを説明します。
Cloud Runを活用した既存のアーキテクチャがこちらです。
稼働しているCloud Run serviceは3つあります。
- 「外部公開API」: 一般ユーザからリクエストを受け付ける
- 「非同期タスクAPI」: Cloud Tasksからタスクを受け付ける
- 「社内連携API」: 連携システムからPub/Sub経由でメッセージを受け付ける
そして、リプレイス後のアーキテクチャがこちらになります。
アプリケーションの改修を避けるためアーキテクチャはほとんど変更しません。Cloud TasksやPub/Subといったサービスは継続利用し、各APIのエンドポイントをCloud RunからGKEに置き換えます。リクエストはIngressのhostベースルーティングで各APIに振り分けます。
段階的リプレイス
問題発生時の影響を最小限にするため段階的にリプレイスを進めます。具体的には、影響度の小さい順にCloud Run serviceをGKEへ置き換えます。検討の結果、社内連携API、非同期タスクAPI、外部公開APIの順でリプレイスする方針にしました。
Phase1: 社内連携API
社内連携APIは、Pub/SubからPush型でリクエストを受け取るため、サブスクリプションに設定しているPushエンドポイントをCloud RunからGKEに変更します。なお、無停止で移行させるため、移行先のGKEには最新バージョンのコンテナがデプロイされている状態になっています。
続きはこちら