カナリアデプロイメント
Gateway API は、重み付けトラフィック分割をネイティブにサポートしており、追加のツールや Service Mesh インフラストラクチャなしでカナリアデプロイメントを可能にします。このセクションでは、UI アプリケーションの新しいバージョンをデプロイし、HTTPRoute の重み付けを使用して、元のバージョンから新しいバージョンへトラフィックを段階的に移行します。
従来の Kubernetes Ingress では、重み付けトラフィック分割はネイティブにサポートされていません。これを実現するには、Istio や App Mesh のような Service Mesh が必要になります。Gateway API は、backendRefs の weight フィールドを通じて、これを第一級の機能として提供します。
新しい UI バージョンのデプロイ
まず、UI アプリケーションの第 2 バージョン(ui-v2)をデプロイします。これはオレンジ色のテーマを使用しており、元の青色のテーマと視覚的に区別できます。
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui-v2
namespace: ui
labels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
app.kubernetes.io/component: service
app.kubernetes.io/created-by: eks-workshop
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
template:
metadata:
labels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
spec:
containers:
- name: ui
image: public.ecr.aws/aws-containers/retail-store-sample-ui:1.2.1
ports:
- containerPort: 8080
protocol: TCP
env:
- name: RETAIL_UI_THEME
value: "orange"
主な違いは RETAIL_UI_THEME=orange 環境変数で、これにより視覚的に異なるオレンジ色のテーマの UI が生成されます。
また、新しい Pod にトラフィックをルーティングするための Service も必要です。
apiVersion: v1
kind: Service
metadata:
name: ui-v2
namespace: ui
labels:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
app.kubernetes.io/created-by: eks-workshop
spec:
selector:
app.kubernetes.io/name: ui
app.kubernetes.io/version: v2
ports:
- port: 8080
targetPort: 8080
protocol: TCP
両方のリソースを適用します。
新しい Pod が準備完了になるまで待ちます。
90/10 カナリアルートの適用
次に、既存の ui-route HTTPRoute を、元の UI に 90%、ui-v2 に 10% のトラフィックを送信する重み付けバージョンに置き換えます。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ui-route
namespace: ui
spec:
parentRefs:
- name: retail-store-gateway
namespace: ui
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: ui
port: 80
weight: 90
- name: ui-v2
port: 8080
weight: 10
backendRefs フィールドに、明示的な weight 値を持つ 2 つのエントリが含まれていることに注目してください。Gateway コントローラーは、これらの重み付けに基づいてトラフィックを比例的に分散します。
カナリア HTTPRoute を適用します。
トラフィック分割のテスト
Gateway に複数のリクエストを送信し、分散を観察します。約 10% のレスポンスがオレンジ色のテーマの ui-v2 から返されるはずです。
href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-default.css"theme: {href="/assets/css/theme-orange.css"theme: {ほとんどのレスポンスが theme-default を返し、20 回のリクエストのうち約 1〜2 回が theme-orange を返すことが確認でき、90/10 のトラフィック分割が機能していることがわかります。
50/50 へのトラフィック増加
新しいバージョンが正しく動作していることを確認したら、カナリアの重み付けを 50% に増やします。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ui-route
namespace: ui
spec:
parentRefs:
- name: retail-store-gateway
namespace: ui
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: ui
port: 80
weight: 50
- name: ui-v2
port: 8080
weight: 50
再度テストして、均等な分割を確認します。
レスポンスの約半分がオレンジ色のテーマを返すことが確認できるはずです。
ロールアウトの完了
新しいバージョンに満足したら、重み付けを 0/100 に設定して、すべてのトラフィックを ui-v2 に移行します。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: ui-route
namespace: ui
spec:
parentRefs:
- name: retail-store-gateway
namespace: ui
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: ui
port: 80
weight: 0
- name: ui-v2
port: 8080
weight: 100
すべてのトラフィックが新しいバージョンに移行したことを確認します。
すべてのレスポンスがオレンジ色のテーマを返し、ui-v2 への完全な切り替えが確認できるはずです。

まとめ
このセクションでは、Gateway API のネイティブな重み付けトラフィック分割を使用して、段階的なカナリアデプロイメントを実行しました。
- 視覚的に区別できる新しいバージョンの UI をデプロイ
- リスクを最小限に抑えるために 90/10 の分割で開始
- 新しいバージョンを検証した後、50/50 に増加
- 0/100 の分割でロールアウトを完了
Gateway API と Ingress の比較
| 機能 | Gateway API | Kubernetes Ingress |
|---|---|---|
| 重み付けトラフィック分割 | backendRefs の重み付けによりネイティブサポート | ネイティブにサポートされていない |
| カナリアデプロイメン ト | 組み込み済み、追加ツール不要 | Service Mesh またはアノテーションが必要 |
| クロスネームスペースルーティング | parentRefs によりネイティブサポート | IngressGroup などの回避策が必要 |
| ロール指向モデル | GatewayClass → Gateway → HTTPRoute | 単一の Ingress リソース |
| ルートごとの複数バックエンド | 重み付けとフィルターによりネイティブサポート | パスごとに単一のバックエンドに制限 |
| 段階的ロールアウト | 宣言的な重み付け更新 | 外部コントローラーが必要 |
Gateway API のネイティブなトラフィック分割により、カナリアデプロイメントが簡潔かつ宣言的になり、従来の Ingress で必要とされる追加の Service Mesh インフラストラクチャやカスタムアノテーションが不要になります。