LegalOn Technologies Engineering Blog

LegalOn Technologies 開発チームによるブログです。

IngressでもGateway APIでもなかったWebフロントエンド向けゲートウェイ再構築

はじめに

こんにちは、SRE&プラットフォームチームの和田です。 今回は、「Google Cloud Next 2025」の発表ではお伝えしきれなかった、アプリケーションプラットフォームのグローバル化プロジェクトの詳細をご紹介したいと思います。 「Google Cloud Next 2025」の弊社の発表内容についてはこちらをご覧ください。

www.youtube.com

グローバル化プロジェクトでは、2024年にリリースした「LegalOn(旧製品名 LegalOn Cloud)」のアプリケーション基盤をベースに、グローバル向けサービス「LegalOn Global」との基盤統合を目指したマルチリージョン・マルチプロダクト対応のアプリケーション基盤へと再構築を行いました。このプロジェクトには、「LegalOn」と「LegalOn Global」の旧基盤からのインフラ移行とトラフィック移行が含まれ、1年がかりの大規模プロジェクトとなりました。

この記事では、決断に二転三転したフロントエンドゲートウェイについて取り上げています。我々がどのように課題を乗り越え、TerraformとGoogle Kubernetes Engine (GKE)を組み合わせたハイブリッド構成によって Webフロントエンド向けゲートウェイを実現したか、その技術的な詳細とノウハウを共有します。

フロントエンドゲートウェイの要件と元の構成

まず、我々が扱うフロントエンドゲートウェイの主な要件と、移行前の構成について説明します。

フロントエンドゲートウェイの主な仕様

  • アセット配信: ブラウザ向けの静的なフロントエンドアセット(JavaScript, CSS, 画像など)を配信します。
  • 負荷軽減: Google Cloud CDNを有効化し、オリジンサーバーへのアクセス負荷を低減します。
  • メンテナンス対応: アプリケーションのメンテナンス時には、Google Cloud Storage (GCS) をバックエンドとしてメンテナンス画面を配信し、ロードバランサでシームレスに切り替えます。これにより、GKEノードレベルの障害にも対応します。
  • マイクロサービスアーキテクチャ: フロントエンドアプリケーションは、URLパスに基づいた機能群のコンテナイメージへリクエストがルーティングされます。

移行前の構成

移行前のフロントエンドゲートウェイは、そのほとんどをTerraformで管理していました。この構成は「LegalOn」リリースから変わらない安定した稼働実績がありましたが、他のゲートウェイ構成と比較してフロントエンドだけが特殊な管理方法となっており、構成管理を標準化する上で課題でした。

目指した構成と最終的な着地点

我々が目指したのは、以下の2点です。

  1. 移行リスクの最小化:グローバル対応に伴う新環境へのトラフィック移行では、メンテナンス中の不確定要素を可能な限り低減したい。
  2. 構成管理の標準化:アプリケーションプラットフォームが提供するゲートウェイ構成を標準化し、サービス固有の事情(ルーティング、カスタムヘッダーなど)は、よりアプリケーションに近いIstio VirtualServiceで管理することで、責務を明確に分離する。

構成管理方法の比較

元の構成、アプリケーションプラットフォームで提供している Gateway の一般的な構成管理、そして様々な制約から最終的に採用した構成の管理方法を比較すると、以下のようになります。詰まるところ Terraform 管理に終着しましたが、より詳細を見ていきましょう。

Frontend Gateway 移行前 アプリケーションプラットフォームの Gateway 一般 Frontend Gateway 最終系
Static IP Address Terraform Terraform Terraform
Cloud Armor Terraform Terraform Terraform
SSL Policy Terraform Terraform Terraform
Forwarding Rule Terraform Kubernetes Terraform
URL Map Terraform Kubernetes Terraform(具体的なサービスルーティングは Istio Gateway 層へ移動したことでシンプルに)
Target HTTPS Proxy Terraform Kubernetes Terraform
Certificate Terraform(Compute SSL Certificate) Kubernetes (Managed Certificate) Terraform(Certificate Manager/Certificate Map)
Backend Service Terraform(フロントエンドの Kubernetes Service ごとの standalone NEG へルーティング) Kubernetes Terraform(Istio Gateway を構成する K8s Service への名前付き NEG の識別子を利用したルーティングに置き換えシンプルに)
Backend Bucket Terraform None Terraform
Istio Gateway None Kubernetes Kubernetes
Istio VirtualService None Kubernetes Kubernetes(URL Map の Path Matcher で実現していた、パスベースルーティングは、VirtualService に置き換えることで、サービス開発者に近い層でのルーティングに変更)
Frontend workload Kubernetes Kubernetes Kubernetes

最終的な構成図

以下は、移行前と移行後の構成を簡略化した図です。

移行前

移行後

最終的に、Cloud Load Balancing (GCLB)や証明書、GCSバックエンドといった部分はTerraformで管理しつつ、具体的なパスベースのルーティングはKubernetesクラスタ内のIstio VirtualServiceに責務を移譲するハイブリッドな構成に落ち着きました。

技術的な詳細と意思決定

なぜこのようなハイブリッド構成になったのか、いくつかの重要なポイントについて詳しく解説します。

URL Map / Backend Serviceの簡素化

元の構成では、URL Map のPath Matcherを使い、Terraformでマイクロサービスごとのルーティングを定義していました。

// 従来: Terraformで複雑なルーティングを定義
resource "google_compute_url_map" "frontend" {
  // ...
  default_service = local.is_maintenance ? google_compute_backend_bucket.maintenance.id : google_compute_backend_service.normal_system.id

  path_matcher {
    content {
      match_rules {
        prefix_match = route_rules.value.route_rule.path_prefix
      }
      // フロントエンドのマイクロサービス毎に 1 Backend Service を構成していた
      service  = route_rules.value.backend_service_id != null ? route_rules.value.backend_service_id : google_compute_backend_service.normal_system[route_rules.value.name].id
      priority = route_rules.value.priority
    }
  }
  // ...
}

新しい構成では、このルーティングの役割をIstio VirtualServiceへ移行しました。これにより、Terraformで管理するURL MapとBackend Serviceは、Istio Gatewayへトラフィックを転送するだけのシンプルな構成になりました。

// 変更後: Istio Gatewayへのルーティングのみ
resource "google_compute_url_map" "frontend" {
  name            = "frontend-gateway-name"
  // Istio Gateway への 1 Backend Service のみ
  default_service = local.is_maintenance ? google_compute_backend_bucket.maintenance.id : google_compute_backend_service.normal_system.id
}

Certificate: DNS認証による証明書の事前取得

トラフィック移行の不確定要素を事前に対処する上で、証明書の管理が課題でした。 元の構成で利用していたGoogle-managed SSL Certificateロードバランサ認証では、ロードバランサを構築し、トラフィックが実際に流れるようになってからでないと証明書の検証・発行が完了しません。これでは、証明書が発行されるまでの時間が不確定となります。そこで、Certificate ManagerDNS認証を採用しました。DNSレコードでドメインの所有権を証明することで、トラフィックを流す前に証明書を事前に取得できます。これにより、事前に /etc/hosts を書き換えたローカルマシンで新構成への疎通確認を万全に行った上で、安心してDNSを切り替えることができました。

認証方式 Google Managed SSL Certificate Certificate Manager
ロードバランサ認証 o o
DNS認証 x o

Gateway API vs Ingress API: なぜ採用を見送ったか

当初はGKEのGateway APIIngress APIを使って、Kubernetesリソースとしてゲートウェイを宣言的に管理することを目指していました。しかし、調査を進めるうちに、我々の要件を満たすにはいくつかの機能が不足していることがわかりました。

項目 Gateway API Ingress API 備考
CDNサポート × 静的アセット配信にはCDNが必須
GCSバックエンドサポート × × メンテナンス画面の配信に必須
Cert Manager証明書 × 事前取得した証明書を利用したい
Google Managed SSL 証明書 × ロードバランサ認証のみのため不採用

(図表は 2025年7月29日 時点の情報です)

特に、GCSバックエンドCDNの両方を満たすことができず、Gateway/Ingress APIの採用は見送らざるを得ませんでした。

Standalone NEGによるTerraformとKubernetesの連携

Gateway/Ingress APIを使わない場合、Terraformで管理するBackend Serviceと、Kubernetes上で稼働するPod(Istio Ingress Gateway)を紐付ける必要があります。

そこで登場するのが Standalone Network Endpoint Group (NEG) です。KubernetesのServiceマニフェストに特定のアノテーション cloud.google.com/neg を付与することで、そのServiceに紐づくPod群をNEGとして作成できます。ポイントは、このアノテーションでNEGに固定の名前(name)を付けられることです。

Kubernetes Service (YAML)

apiVersion: v1
kind: Service
metadata:
  name: frontend-gateway
  annotations:
    cloud.google.com/neg: '{"exposed_ports":{"443":{"name":"frontend-gateway"}}}'

この名前を使うことで、Terraform側からNEGを一意に特定し、Backend Serviceのバックエンドとして設定できます。

Terraform Backend Service (HCL)

resource "google_compute_backend_service" "frontend" {
  name = "frontend-gateway"
  # ...
  backend {
    group = "https://www.googleapis.com/compute/v1/projects/<YOUR_PROJECT>/zones/<YOUR_ZONE>/networkEndpointGroups/frontend-gateway"
    balancing_mode = "RATE"
  }
}

この仕組みにより、異なるレイヤーのリソースをマッピングし、ハイブリッド構成を実現しました。

導入効果と今後の展望

得られた効果

今回の再構築により、主に2つの大きな効果が得られました。

  1. 移行時のダウンタイムリスクの払拭:DNS認証による証明書の事前取得と、それによる新構成の事前疎通確認が可能になり、移行当日の「いつ終わるか分からない証明書発行待ち」という不安から解放されました。
  2. 構成管理の責務分離と標準化:複雑なパスルーティングやカスタムヘッダーの設定を、Terraformの世界からKubernetesクラスタ内のVirtualServiceに移行できました。これにより、フロントエンドゲートウェイの構成が他のゲートウェイの標準構成に近づき、見通しが良く、メンテナンスしやすい状態になりました。

今後の展望

  • Gateway APIの進化に期待:今後、GKEにおけるGateway APIのサポートが拡充され、今回採用を見送る原因となったGCSバックエンドやCDNがサポートされれば、よりKubernetesネイティブな構成管理への移行を検討していきたいです。
  • Cloud CDN + GCSバックエンドへの移行:よりフロントエンドのアセット配信がリクエストヘビーになった場合には、アプリケーションの配信経路から完全に切り離し、GCSとCloud CDNを組み合わせたストレージベースの配信構成に寄せることも選択肢の一つとして考えています。

謝辞

問題解決する際にアドバイスいただいたSRE&プラットフォームチームのグローバル化対応メンバー、レビューしてくださった伊藤さんに深く感謝します!この記事と資料はこれらの方々の協力なしではありえませんでした。ありがとうございました。

仲間募集!

LegalOn Technologiesでは一緒に働く仲間を募集しています!ご興味のある方はぜひご応募ください。お待ちしております。

herp.careers

herp.careers

recruit.legalontech.jp