コンテンツに移動
アプリケーション開発

プラットフォーム エンジニアリングを駆使してデベロッパー エクスペリエンスを簡素化 - パート 2

2025年7月17日
Darren Evans

EMEA Practice Solutions Lead, Application Platform

Alex Moss

Principal Platform Engineer, John Lewis Partnership

【Next Tokyo ’25】

【Next Tokyo】120 以上のセッションをアーカイブ公開中。話題の Gemini、生成 AI、AI エージェントなどの Google Cloud のアップデートや顧客事例をチェックしましょう。

視聴はこちら

※この投稿は米国時間 2025 年 6 月 27 日に、Google Cloud blog に投稿されたものの抄訳です。

前回の記事では、John Lewis Digital Platform と、プラットフォーム エンジニアリングと「舗装道路」機能を通じてデベロッパー エクスペリエンスを簡素化するアプローチを紹介し、Google Cloud でのリソース作成や、専用のテナント環境内でのプラットフォームの運用機能とセキュリティ機能のデプロイをプラットフォーム エンジニアリングによって実現する方法に焦点を当てました。この記事では、そのコンセプトを基に、プラットフォームによってコンポーネント(通常はマイクロサービス)レベルでもビルドと実行を簡素化する方法について、さらに詳しく説明します。

わずか 1 年ほどで、John Lewis Digital Platform は完全に製品レベルに進化しました。当社のプラットフォームを使用するチームは約 25 チームで、本番環境で実行されている johnlewis.com の小売ウェブサイトの主要な部分でも使用されています。チームが Google Cloud でリソースをプロビジョニングできるようにセルフサービス機能を構築し、プラットフォームの基盤が Google Kubernetes Engine(GKE)上にあることを明確にしました。しかし、最近のチームからは、Kubernetes の習得に時間がかかるという声が聞こえてきました。これは想定されていたことでした。チームが独自のサービスを構築して実行するという文化変革を推進していたため、アプリケーション開発者が独自のソフトウェアをサポートするのに Kubernetes のスキルが必要になることは予想できていたのです。とはいえ、私たちのビジョンは開発者の負担を軽減することであり、彼らのフィードバックは明確でした。優れたドキュメントがあるにもかかわらず、チームが推奨する手順に従っていないケースがいくつか見られました。たとえば、ワークロードが障害に耐えられるように支援するアンチアフィニティ ルールや PodDisruptionBudgets を使用していませんでした。

2017 年に Kelsey Hightower は次のように書いています。「Kubernetes はプラットフォームを構築するためのプラットフォームです。これはより良いスタート地点であって、最終目標ではありません。」

Kelsey の言葉に触発された私たちは、行動を起こしました。Kubernetes を使用する開発者のインタラクション ポイントを簡素化するために、独自のカスタム コントローラを作成するというアイデアが浮かんだのです。私たちが好むアプローチに沿って John Lewis 固有の抽象化を行うのです。こうして JL Microservice が誕生しました。

これを行うために、開発者が設定する必要があると思われるフィールドのみを含む簡略化された仕様で Kubernetes CustomResourceDefinition を宣言しました。たとえば、テナントがアプリケーションを自ら構築して運用することを想定しているため、レプリカの数や必要なリソース量などの属性は、開発者自身に任せるのが最適です。しかし、ノード間で Pod を分散する方法を定義するルールを彼らがカスタマイズできるようにする必要は本当にあるのでしょうか。Deployment を参照する Service を変更することはどのくらいの頻度で必要になるでしょうか。詳しく調べてみると、重複が非常に多いことがわかりました。当時の分析では、開発者が作成した YAML ファイルの内容のうち、アプリケーションに関連するものは約 33% にすぎませんでした。これは、簡素化の対象が豊富にあるということです。

https://storage.googleapis.com/gweb-cloudblog-publish/images/article2-image1.max-1300x1300.png

この機能を構築するにあたり、Kubebuilder を選択し、それを使用して CustomResourceDefinition を宣言し、コントローラ(MicroserviceManager と命名)を構築しました。これは有益な決定でした。最初のプロトタイピングは迅速に行われ、数か月後に機能がリリースされ、非常に好評を博しました。チームは Go プログラミング言語のスキルアップが必要でしたが、Kubebuilder がもたらすメリットを考えると、このトレードオフは価値があると感じました。それ以来、他のソフトウェア エンジニアリングにも役立っています。

最初の実装では、エンジニアが DeploymentService を理解して完全に構成する必要がなくなり、代わりに、変更する必要があるフィールドのみを含む、はるかに短い YAML ファイルを適用すればよくなりました。同一のフィールドの直接変換(たとえば、imagereplicas  は、Deployment にあるものと同等)だけでなく、Kubernetes API で行われる選択を簡素化することもできました。John Lewis では、その機能の一部は必要なかったからです。たとえば、writablePaths: [] はエンジニアが理解しやすいコンセプトです。その裏では、コントローラがこれをより複雑な Volume  と VolumeMount の組み合わせに変換しています。同様の例として、visibleToOtherServices: true は Kubernetes NetworkPolicy とのやり取りを簡素化します。チームがリソースに正しくラベルを付けるためにドキュメントを読んで必要な構文を理解する必要はなく、コントローラがそれらの規則を理解して処理します。

Microservice リソースの基本コンセプトが確立されたことで、さらに機能を追加して付加価値を高めることができました。すぐに拡張して Prometheus のスクレイピング構成を定義し、さらに、チームが Google Cloud Endpoints を使用することを宣言できるようにするなどの複雑な機能を追加しました。これにより、コントローラは必要なサイドカー コンテナを Deployment に挿入し、Service に接続できます。機能を追加するにつれて、既存のテナントはこの仕様を使用するように変更され、現在ではプラットフォームで宣言されたワークロードの大部分を占めています。

プラットフォームの境界を移動する

MicroserviceManager を構築する動機は、開発者の作業を楽にすることにありました。しかし、当初は予想していなかったさらなるメリットがあることがわかりました。それは、プラットフォーム内でも大きなメリットが得られるということです。テナントを巻き込むことなく、バックグラウンドで変更を加えることができるようになったことで、テナントのトイルが減り、プロダクトの改善が容易になりました。これは少し予想外でしたが、非常に大きなメリットでした。テナントとプラットフォームの間で確立された契約を変更することは一般的に困難ですが、このような抽象化を作成することでより多くのものを我々の管理下に置くことができ、これはすべてのユーザーにとってメリットとなります。

その一例として、johnlewis.com のライブ負荷テストで、特定のワークロードが数百の Pod までバーストしたことがありました。これは、クラスタで実行していた通常のノード数を上回る数です。これにより、新しいノードが作成され、Pod の自動スケーリングが遅くなり、ビンパッキングが不十分になりました。Kubernetes の運用経験が豊富な方なら、ここで何が起こったかはお察しいただけるでしょう。デフォルトのアンチ アフィニティ ルールは、復元力を最適化するように設定されており、特定のノードには 1 つのレプリカしか許可されていませんでした。ただし、幸運なことにワークロードは Microservice Manager の制御下にあり、関連する YAML をデプロイにコピーするようテナントに指示する必要がなかったため、アンチ アフィニティ ルールをより新しい podTopologyConstraints に置き換えるのは簡単でした。これにより、特定のレプリカ数を超えるワークロードについて、ノードにスタックできるレプリカ数をカスタマイズできるようになりました。テナントによる操作は一切必要ありませんでした。

より複雑な例としては、サービス メッシュをロールアウトしたときが挙げられます。我々はコントロール プレーン コンポーネントの実行の複雑さの処理を Google Cloud に任せたいと基本的に考えていたので、Google の Cloud Service Mesh プロダクトを使用することにしました。しかし、それでも、常に使用されているビジネス クリティカルなプラットフォームにメッシュをロールアウトするには、リスクが伴います。Microservice Manager では、Microservice リソースのフィーチャー トグルを使用して、ワークロードをメッシュに登録する頻度を制御できます。まず、プラットフォームが所有するワークロードでロールアウトを開始してアプローチをテストし、その後、先行ユーザーが Cloud Service Mesh の一部の機能を検証して利用できるように、テナントにフラグを通知します。ロールアウトを拡大する際には、ビジネス上の重要度に基づいて段階的にリリースするようにフラグを操作し、必要に応じてオプトアウト メカニズムを提供します。これにより、実装が大幅に簡素化されました。プロダクト チームがやるべきことはほとんどなく、数百のマイクロサービスを実行している約 40 のチームに適切な構成変更を依頼する必要もありませんでした。フィーチャー トグルを活用するこの手法は、独自のテストをサポートするために幅広く活用しています。

マイクロサービスを超えて

Microservice Manager を構築したことで、Kubernetes ネイティブな方法が考えられるようになりました。カスタム リソース + コントローラというコンセプトは強力な手法であり、これを使用して他の機能も構築しました。たとえば、外部接続の必要性を Istio リソースに変換して、下り(外向き)ゲートウェイ経由でルーティングするコントローラです。Istio は非常に強力なプラットフォーム機能ですが、活用する際にユーザー側に求められる知識やスキルは少なくありません。したがってこれは、プラットフォーム エンジニアリングがチームの代わりに管理し、チームがその機能を活用できるようにするのに最適な例と言えます。テクノロジーに対する信頼が高まった今、この分野でさまざまなアイデアが生まれています。

まとめると、John Lewis Partnership は Google Cloud とプラットフォーム エンジニアリングを活用して、e コマースの運用とデベロッパー エクスペリエンスをモダナイズしました。マルチテナント アーキテクチャで「舗装道路」アプローチを実装することで、開発チームを強化し、デプロイ サイクルを加速させ、カスタムの Microservice CRD を使用して Kubernetes のインタラクションを簡素化しました。この戦略により、運用効率を維持し、エンジニアリング チームを効果的にスケールしながら、複雑さを軽減することで、効果的なスケールとデベロッパー エクスペリエンスの向上を実現できました。

Google Cloud でのプラットフォーム エンジニアリングの詳細については、プラットフォーム エンジニアリングに関する 5 つの誤解: プラットフォーム エンジニアリングとは一体なのかプラットフォーム エンジニアリングにまつわるさらなる 5 つの誤解道を照らす: プラットフォーム エンジニアリング、ゴールデンパス、セルフサービスのパワーなどの記事をご覧ください。

-アプリケーション プラットフォーム担当 EMEA プラクティス ソリューション リード、Darren Evans
-John Lewis Partnership、プリンシパル プラットフォーム エンジニア、Alex Moss 氏

投稿先