このページでは、Google Kubernetes Engine(GKE)のトラフィック管理を Ingress API から Gateway API に移行する方法について説明します。Gateway API は、アプリケーション トラフィックを処理するためのフルマネージドの Google Cloud ソリューションを提供します。
ダウンタイムを最小限に抑え、リスクを軽減するには、既存の Ingress API と新しい Gateway API 構成を同時に実行することが、Gateway API への移行に最も効果的な方法です。この方法では、現在のサービスに影響を与えることなく、ライブ環境で新しいゲートウェイ構成を徹底的にテストできます。新しいゲートウェイ構成を検証したら、DNS をすばやく切り替えてトラフィックを Gateway API にリダイレクトし、スムーズでリスクの低い移行を実現できます。
移行戦略は、大まかに次のフェーズで構成されます。
- 新しいロードバランサを構成します。
- 着信トラフィックを処理するルールを定義します。
- 新しい構成をデプロイし、新しいゲートウェイの IP アドレスへのトラフィック フローをテストします。
- 本番環境トラフィックを Gateway API に切り替えます。
- 残りの Ingress リソースをクリーンアップします。
新しいロードバランサを構成する
このフェーズでは、Kubernetes ゲートウェイ リソースをデプロイして、GKE クラスタへのトラフィックをロード バランシングします。ゲートウェイ リソースをデプロイすると、GKE はクラスタで実行されているアプリケーションに HTTP(S) トラフィックを公開するようにレイヤ 7 アプリケーション ロードバランサを構成します。必要なクラスタまたはロードバランサごとに 1 つのゲートウェイ リソースをデプロイします。
次の例では、グローバル外部アプリケーション ロードバランサを構成します。ゲートウェイを作成するには、次のマニフェストを gateway.yaml として保存します。
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
name: external-http-gateway
spec:
gatewayClassName: gke-l7-global-external-managed # GKE's managed external Application Load Balancer
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: Same # Only allow HTTPRoutes from the same namespace
上記のマニフェストでは、次のフィールドを含むゲートウェイを記述しています。
gatewayClassName: gke-l7-global-external-managed: このゲートウェイの GatewayClass を指定します。このゲートウェイ クラスは、グローバル外部アプリケーション ロードバランサを使用します。protocol: HTTPとport: 80: ゲートウェイが HTTP トラフィック用にポート 80 を公開することを指定します。
着信トラフィックのトラフィック ルールを定義する
Route リソースは、ゲートウェイからバックエンド サービスにトラフィックをマッピングするためのプロトコル固有のルールを定義します。
このフェーズでは、Ingress マニフェストを HTTPRoute リソースに変換します。Ingress マニフェストを変換するには、ingress2gateway ツールの手順に沿って操作します。
この例では、次の Ingress リソースがあることを前提としています。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cafe-ingress
spec:
ingressClassName: nginx
rules:
- host: cafe.example.com
http:
paths:
- path: /tea
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80
- path: /coffee
pathType: Prefix
backend:
service:
name: coffee-svc
port:
number: 80
ingress2gateway ツールを使用してマニフェストを変換すると、出力は変換された HTTPRoute マニフェストになります。
次のサンプル マニフェストを httproute.yaml として保存します。
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: cafe-route
spec:
# This route attaches to our new Gateway
parentRefs:
- name: external-http-gateway
# The hostname is the same as before
hostnames:
- "cafe.example.com"
# The routing rules are now more explicit
rules:
- matches:
- path:
type: PathPrefix
value: /tea
backendRefs:
- name: tea-svc
port: 80
- matches:
- path:
type: PathPrefix
value: /coffee
backendRefs:
- name: coffee-svc
port: 80
HTTPRoute マニフェストの rules フィールドは、元の Ingress マニフェストで定義されたルーティング ルールに直接対応しています。
新しい構成をデプロイしてテストする
このフェーズでは、前の 2 つのフェーズで作成したゲートウェイと HTTPRoute のマニフェストを適用し、トラフィックがゲートウェイの新しい IP アドレスに流れることをテストします。
ゲートウェイと HTTPRoute のマニフェストを適用します。
kubectl apply -f gateway.yaml kubectl apply -f httproute.yamlゲートウェイの IP アドレスを取得します。IP アドレスの割り当てには数分かかることがあります。
kubectl get gateway external-http-gateway -o=jsonpath="{.status.addresses[0].value}" --watch出力は、ゲートウェイの外部 IP アドレスです(例:
203.0.113.90)。新しいゲートウェイの IP アドレスをテストします。次の
curlコマンドを使用して、IP アドレスにリクエストを送信し、cafe.example.comホスト名を指定します。次に例を示します。curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/tea curl --resolve cafe.example.com:80:203.0.113.90 http://cafe.example.com/coffee203.0.113.90は、前の手順で取得した外部 IP アドレスに置き換えます。出力は、新しいゲートウェイの IP アドレスが DNS ルックアップを実行せずにcafe.example.comのトラフィックを正しくルーティングしていることを確認します。
新しいゲートウェイの IP アドレスにトラフィックを転送する
このフェーズでは、DNS レコードを更新して新しいゲートウェイの IP アドレスを指すようにすることで、以前の Ingress から新しいゲートウェイにライブ トラフィックを切り替えます。DNS レコードを更新する正確な手順は、DNS プロバイダによって異なります。
たとえば、Ingress で cafe.example.com を構成した場合は、DNS プロバイダで cafe.example.com の A レコードを見つけて、古い Ingress IP アドレスの値を新しいゲートウェイの IP アドレスである 203.0.113.90 に変更します。
DNS レコードを更新すると、トラフィックは Ingress からゲートウェイに移行し始めますが、すべてのクライアントで切り替えがすぐに発生するわけではありません。前のレコードをキャッシュに保存している DNS リゾルバは、レコードの有効期間(TTL)値の期限が切れるまで待機してから、レコードを再度クエリして、更新された IP アドレスを取得します。このため、Ingress へのトラフィックが停止したことを確認するまで、既存の Ingress と新しいゲートウェイを並行して実行する必要があります。Ingress へのトラフィックが停止したことは、DNS 伝播が完了し、クライアントが古い IP アドレスに転送されなくなったことを示します。これは、ロードバランサまたは Ingress コントローラのトラフィックをモニタリングすることで確認できます。詳細については、DNS 伝播の確認をご覧ください。
Cloud DNS を使用すると、ターゲットの重みを使用して、トラフィックを古い IP アドレスから新しい IP アドレスに段階的に移行できます。詳細については、DNS ルーティング ポリシーとヘルスチェックを構成するをご覧ください。
残りの Ingress リソースをクリーンアップする
新しいゲートウェイが正常に動作していることを確認したら、古い Ingress リソースをクリーンアップします。
Ingress リソースを削除します。
kubectl delete ingress cafe-ingressingress-nginxコントローラをアンインストールします。たとえば、Helm を使用してコントローラをインストールした場合は、次のコマンドを実行します。helm uninstall ingress-nginx -n ingress-nginx
Ingress NGINX と GKE Gateway の機能の比較
Gateway API は、より標準化された方法で上り(内向き)を構成し、ルーティング、ヘッダー、トラフィック分割などの最も一般的な機能と同等の機能を備えています。
次の表に、Ingress コントローラと Gateway API の一般的な機能で使用されるアノテーションを比較します。
| 機能 | Ingress のアノテーション | GKE Gateway のアノテーション | 同等 |
|---|---|---|---|
| URL の書き換え | nginx.ingress.kubernetes.io/rewrite-target |
urlRewrite フィルタを使用した HTTPRoute。 |
部分的に同等。GKE Gateway は、接頭辞の置換のみをサポートします。 |
| ヘッダーの操作 | nginx.ingress.kubernetes.io/proxy-set-headers または add-headers |
requestHeaderModifier 修飾子または responseHeaderModifier フィルタを使用した HTTPRoute。 |
完全に同等。 |
| パスベースの転送 | Ingress オブジェクトの spec.rules.http.paths。 |
HTTPRoute オブジェクトの rules.matches.path。 |
完全に同等。 |
| ホストベースのルーティング | Ingress オブジェクトの spec.rules.host。 |
HTTPRoute オブジェクトの hostnames。 |
完全に同等。 |
| トラフィック分割 | nginx.ingress.kubernetes.io/canary アノテーション。 |
重み付けされた backendRefs を含む HTTPRoute。 |
完全に同等。また、トラフィックをきめ細かく制御して分割できます。 |
| 認証 | 外部認証の nginx.ingress.kubernetes.io/auth-url。 |
|
部分的に同等。Identity-Aware Proxy は、ゲートウェイを保護する推奨の方法であり、バックエンドで構成されます。 |
次のステップ
- ゲートウェイを保護する方法を学習する。
- ゲートウェイのトラフィック管理の仕組みを確認する。