Gateway 用に Cloud CDN を構成する

このドキュメントでは、Google Kubernetes Engine(GKE)Gateway コントローラを使用して Cloud CDN を構成する方法について説明します。Cloud CDN のコンセプト、ベスト プラクティス、トラブルシューティングの詳細については、Cloud CDN のドキュメントをご覧ください。

Cloud CDN は、コンテンツをユーザーの近くのキャッシュに保存することで、エンドユーザーのレイテンシを短縮し、オリジンの負荷を軽減します。Cloud CDN のキャッシュ保存機能を有効にするには、GCPHTTPFilter CustomResourceDefinition を使用します。

このドキュメントは、組織のネットワークを設計するアプリケーション開発者、クラウド アーキテクト、ネットワーク スペシャリストを対象としています。 Cloud de Confiance のコンテンツで使用されている一般的なロールとタスクの例の詳細については、一般的な GKE ユーザーのロールとタスクをご覧ください。

概要

GKE Gateway と Cloud CDN の統合により、Kubernetes ネイティブ リソースを使用してエッジ キャッシュを管理できます。GCPHTTPFilter リソースを使用すると、トラフィックのさまざまなスライスに対して、キャッシュ モードや有効期間(TTL)などの構成を微調整できます。

Cloud CDN を有効にするには、GCPHTTPFilter オブジェクトを作成し、HTTPRoute ルールでそのオブジェクトを参照します。複数の GCPHTTPFilter オブジェクトを作成して、トラフィックのタイプごとに異なるキャッシュ保存動作を定義できます。たとえば、静的イメージ用のフィルタと、Cloud CDN の推奨デフォルト値を使用するデフォルト ポリシー用のフィルタを作成できます。

GCPHTTPFilter リソースを使用すると、次の構成を行うことができます。

  • キャッシュ モード: Cloud CDN が送信元からのレスポンスをキャッシュに保存する方法を制御します。
  • 有効期間(TTL)の構成: オブジェクトがキャッシュに保持される期間を構成します。
  • キャッシュキー: キャッシュキーの生成に使用されるリクエストの要素(ヘッダー、Cookie、クエリ文字列)を定義します。
  • ネガティブ キャッシュ: 一般的なエラー レスポンスまたはリダイレクトをキャッシュに保存して、障害発生時のオリジンの負荷を軽減します。
  • キャッシュ ポリシー: Cloud CDN がキャッシュ可能なリクエストを処理する方法を制御します。たとえば、Cloud CDN を有効にして次の操作を行うことができます。
    • バックエンド サービスが使用できなくなっても、キャッシュに保存されたコンテンツの提供を継続することで、高可用性を維持します。
    • キャッシュをバイパスしてバックエンドから直接データを取得する特定のリクエスト ヘッダーを定義します。
    • 同じリソースに対する複数の同時リクエストを 1 つのリクエストに統合して、バックエンドの負荷を軽減します。

GCPHTTPFilter リソースは、アタッチされている HTTPRoute リソースと同じ Namespace に存在する必要があります。GCPHTTPFilter を構成すると、フィルタはルートのフィルタチェーンに統合されます。

次の図は、GCPHTTPFilter を使用して、HTTPRoute 内の特定のトラフィック スライスに異なるキャッシュ保存構成を適用する方法を示しています。

図 1. HTTPRoute 内の GCPHTTPFilter で作成されたさまざまなキャッシュ保存構成。
図 1. HTTPRoute 内のキャッシュ保存構成。

このアーキテクチャでは、きめ細かい自動エッジ キャッシュ管理を構成できます。HTTPRoute は、リクエスト パスなどの属性に基づいて受信トラフィックを照合し、受信リクエストの処理方法を構成します。特定のルートのキャッシュ保存を有効にするには、GCPHTTPFilter を HTTPRoute 内のルールに関連付けます。GCPHTTPFilter ごとに、画像、ウェブ アセット、その他のコンテンツに対して異なるキャッシュ保存ロジックを指定できます。このキャッシュ保存ロジックは Cloud CDN によって適用され、キャッシュに保存されたコンテンツがクライアントに配信されます。

要件と制限事項

  • クラスタには GKE バージョン 1.35.2-gke.1751000 以降が必要です。
  • gke-l7-global-external-managed または gke-l7-global-external-managed-mc GatewayClass を使用して、グローバル外部 Gateway を構成している必要があります。
  • HTTPRoute リソースを構成している必要があります。
  • Identity-Aware Proxy(IAP)と Cloud CDN の両方を同じ Gateway で有効にすることはできません。IAP が必要な場合は、GCPBackendPolicy を有効にする前に GCPHTTPFilter オブジェクトを削除する必要があります。
  • HTTPRoute 内の特定のパスルールに関連付けることができる GCPHTTPFilter オブジェクトは 1 つのみです。

料金

キャッシュ保存が有効になっている場合、Cloud CDN の料金が適用されます。詳細については、Cloud CDN の料金をご覧ください。

始める前に

作業を始める前に、次のタスクが完了していることを確認してください。

  • Google Kubernetes Engine API を有効にする。
  • Google Kubernetes Engine API を有効化
  • このタスクに Google Cloud CLI を使用する場合は、gcloud CLI をインストールして初期化します。gcloud CLI をインストール済みの場合は、gcloud components update コマンドを実行して最新のバージョンを取得します。以前のバージョンの gcloud CLI では、このドキュメントのコマンドを実行できない場合があります。

ロールと権限

  1. 構成された Cloud de Confiance リソースを表示するには、roles/compute.networkViewer IAM ロールがあることを確認します。

  2. GKE クラスタにアクセスでき、必要な操作を実行する権限があることを確認します。次のスニペットは、必要な最小限の RBAC 権限を示しています。

    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: gateway-caching-admin
    rules:
    # 1. Full access to manage HTTPRoutes
    - apiGroups: ["gateway.networking.k8s.io"]
      resources: ["httproutes"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    # 2. Read-only access to view the Gateway
    - apiGroups: ["gateway.networking.k8s.io"]
      resources: ["gateways"]
      verbs: ["get", "list", "watch"]
    # 3. Full access to manage caching filters
    - apiGroups: ["networking.gke.io"]
      resources: ["gcphttpfilters"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
    

RBAC と IAM の使用の詳細については、Identity and Access Management とのやり取りをご覧ください。

GCPHTTPFilter を使用してキャッシュを構成する

Cloud CDN を有効にして構成するには、1 つ以上の GCPHTTPFilter リソースを作成し、HTTPRoute オブジェクトでそれらを参照します。

GCPHTTPFilter を作成する

GCPHTTPFilter リソースは、キャッシュ保存ポリシーを定義します。次の例では、3 つの GCPHTTPFilters を作成します。

  • 最初のフィルタは、静止画像をキャッシュに保存して、エンドユーザーへの配信を高速化します。
  • 2 番目のフィルタは、CSS ファイルなどのウェブアセットをキャッシュに保存します。
  • 3 つ目のフィルタは、残りのトラフィックの「キャッチオール」として機能します。
  1. 次のマニフェストを store-caching-images-filter.yaml として保存して、最初のフィルタを作成します。

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-caching-images-filter
    spec:
      cachePolicy:
        cacheKeyPolicy:
          includeQueryString: false
        cacheMode: CACHE_ALL_STATIC
        defaultTTL: 12h
    

    このマニフェストでは、次のようになります。

    • includeQueryString: キャッシュキーのクエリ パラメータを無視するように Cloud CDN に指示します。これにより、同じ画像に対するさまざまなユーザー リクエストに同じキャッシュ コピーが確実に提供されます。
    • cacheMode: CACHE_ALL_STATIC に設定されています。これにより、画像などの静的コンテンツが自動的にキャッシュに保存されます。
    • defaultTTL: Cloud CDN に画像を 12 時間キャッシュに保存するように指示します。時間は、時間(h)、分(m)、秒(s)で指定できます。
  2. 2 番目のフィルタを作成します。次のマニフェストを store-caching-webassets-filter.yaml として保存します。

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-caching-webassets-filter
    spec:
      cachePolicy:
        cacheKeyPolicy:
          includeQueryString: false
        serveWhileStale: 24h
        cacheMode: CACHE_ALL_STATIC
        defaultTTL: 24h
    

    このマニフェストには、最初のフィルタと同じ設定がいくつかありますが、次の点が異なります。

    • serveWhileStale: 24 時間に設定されています。ウェブアセット(CSS ファイルなど)が defaultTTL の後に期限切れになった場合、Cloud CDN はその古いアセットをキャッシュから最大 24 時間配信し続け、バックグラウンドでコンテンツを再検証します。
    • defaultTTL: 24 時間の長い期間に設定されます。
  3. 3 つ目のフィルタを作成して、パラメータなしでデフォルトのキャッシュ保存ポリシーを定義します。次のマニフェストを store-caching-default-filter.yaml として保存します。

    apiVersion: networking.gke.io/v1
    kind: GCPHTTPFilter
    metadata:
      name: store-caching-default-filter
    spec:
      cachePolicy: {}
    

    GCPHTTPFilter リソースでパラメータを指定しない場合、GKE はキャッシュ保存のデフォルト値を使用します。

  4. フィルタをクラスタに適用します。

    kubectl apply -f store-caching-images-filter.yaml
    kubectl apply -f store-caching-webassets-filter.yaml
    kubectl apply -f store-caching-default-filter.yaml
    

フィルタを HTTPRoute に接続する

キャッシュ ポリシーを適用するには、既存の HTTPRoute マニフェストを更新してフィルタを参照します。

同じ HTTPRoute オブジェクト内で異なるフィルタを参照して、一貫したキャッシュ保存ルールを適用できます。たとえば、プログレッシブ ロールアウト中に異なるバックエンド バージョン間でトラフィックを分割する場合など、異なるルール間で同じフィルタを再利用することもできます。

  1. 既存の HTTPRoute マニフェスト(store-route-external.yaml など)を変更して、ルーティング ルールに filters セクションを含めます。

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # RULE 1: Default /img/ traffic to store-v1
      - matches:
        - path:
            value: /img/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-images-filter
        backendRefs:
        - name: store-v1
          port: 8080
      # RULE 2: Default /web/ traffic to store-v1
      - matches:
        - path:
            value: /web/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-webassets-filter
        backendRefs:
        - name: store-v1
          port: 8080
      # RULE 3: Canary /img/ traffic (header + path match) to store-v2
      - matches:
        - headers:
          - name: env
            value: canary
          path:
            value: /img/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-images-filter
        backendRefs:
        - name: store-v2
          port: 8080
      # RULE 4: Canary /web/ traffic (header + path match) to store-v2
      - matches:
        - headers:
          - name: env
            value: canary
          path:
            value: /web/
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-webassets-filter
        backendRefs:
        - name: store-v2
          port: 8080
      # RULE 5: Default (catch-all) traffic to store-v1
      - backendRefs:
        - name: store-v1
          port: 8080
        # If you need caching for default traffic, it can be enabled by placing
        # filters directly under backendRefs
        filters:
        - type: ExtensionRef
          extensionRef:
            group: networking.gke.io
            kind: GCPHTTPFilter
            name: store-caching-default-filter
    
  2. 更新された HTTPRoute 構成をクラスタに適用します。

    kubectl apply -f store-route-external.yaml
    
  3. HTTPRoute と Gateway がデプロイされていることを確認します。

    kubectl describe httproute store-external
    kubectl describe gateway external-http
    

    出力は、HTTPRoute リソースで Cloud CDN が有効になっていることを示しています。Cloud CDN は、構成されたキャッシュ保存ポリシーをトラフィックに適用し、静的画像、ウェブアセット、その他のトラフィックの配信を高速化します。

キャッシュに保存されたコンテンツの無効化

キャッシュから古いコンテンツを削除するには、無効化リクエストを送信する必要があります。無効化の仕組みの詳細については、Cloud CDN ドキュメントのキャッシュに保存されたコンテンツを無効にするをご覧ください。

  1. Gateway に関連付けられている URL マップを見つけます。

    kubectl describe gateway external-http
    

    networking.gke.io/url-maps アノテーションを探します。次に例を示します。

    Name: external-http
    Namespace: foo
    API Version: gateway.networking.k8s.io
    Kind: Gateway
    Annotations: networking.gke.io/backend-services: gkegw-service1
                 networking.gke.io/firewalls: gkegw-l7-fw
                 networking.gke.io/forwarding-rules: gkegw-fr1
                 networking.gke.io/health-checks: gkegw-hc1
                 networking.gke.io/ssl-certificates:
                 networking.gke.io/target-proxies: gkegw-tp1
                 networking.gke.io/url-maps: gkegw-url-map1
    
  2. ホスト、パス、キャッシュタグ、レスポンス ステータス コード、MIME タイプ、バックエンドなど、複数の無効化マッチャーを使用してコンテンツを無効にできます。たとえば、ホストとステータス コードのマッチャーを使用して無効化リクエストを送信するには、次のコマンドを実行します。

    gcloud compute url-maps invalidate-cdn-cache URL_MAP_NAME
        --host="store.example.com" 
        --status=404
    

    URL_MAP_NAME は、前の手順で特定した名前(gkegw-url-map1 など)に置き換えます。

Cloud CDN のパフォーマンスをモニタリングする

Cloud Logging と Cloud Monitoring を使用して、キャッシュ ヒット率とパフォーマンスを追跡できます。

Cloud CDN ログは、GKE Gateway Controller によってプロビジョニングされたロードバランサに関連付けられます。ログは、ロードバランサの転送ルールと URL マップでインデックス化されます。最近のログを取得するには、次のコマンドを実行します。

gcloud logging read 'resource.type="http_load_balancer" AND 
    resource.labels.url_map_name="URL_MAP_NAME" AND 
    logName="projects/PROJECT_ID/logs/cloudcdn_googleapis_com%2Frequests"' 
    --project PROJECT_ID --limit 100 --format json

Cloud CDN は指標を Cloud Monitoring にエクスポートします。モニタリング クエリで matched_url_path_rule フィルタを使用すると、指標を特定の HTTPRoute に絞り込むことができます。

Cloud CDN のログとモニタリングの表示の詳細については、キャッシュ保存のログと指標をご覧ください。

Cloud CDN を無効にする

キャッシュ保存を無効にするには、HTTPRoute から GCPHTTPFilter 参照を削除します。

  1. HTTPRoute マニフェストを編集し、GCPHTTPFilter を参照する filters ブロックを削除します。次の例は、フィルタが削除された HTTPRoute マニフェストを示しています。

    kind: HTTPRoute
    apiVersion: gateway.networking.k8s.io/v1
    metadata:
      name: store-external
    spec:
      parentRefs:
      - kind: Gateway
        name: external-http
      hostnames:
      - "store.example.com"
      rules:
      # RULE 1: Default /img/ traffic to store-v1
      - matches:
        - path:
            value: /img/
        backendRefs:
        - name: store-v1
          port: 8080
      # RULE 2: Canary /img/ traffic (header match) to store-v2
      - matches:
        - headers:
          - name: env
            value: canary
          path:
            value: /img/
        backendRefs:
        - name: store-v2
          port: 8080
      # RULE 3: Default (catch-all) traffic to store-v1
      - backendRefs:
        - name: store-v1
          port: 8080
    
  2. 更新された HTTPRoute マニフェストをクラスタに適用します。

    kubectl apply -f store-route-external.yaml
    

次のステップ