Cloud CDN

このページでは、BackendConfig カスタム リソースを使用して Google Kubernetes Engine で Cloud CDN を構成する方法を説明します。

概要

GKE クラスタでは、受信トラフィックが Cloud Load Balancing のコンポーネントである HTTP(S) 負荷分散によって処理されます。一般に、HTTP(S) ロードバランサは GKE Ingress コントローラによって構成され、このコントローラは構成情報を Kubernetes Ingress オブジェクトから取得します。Ingress は、1 つ以上のサービス オブジェクトに関連付けられています。それぞれのサービスで、受信リクエストを特定のポッドとポートに転送するときに使用されるルーティング情報が保持されます。

Kubernetes バージョン 1.10.5-gke.3 以降では、サービスポートを BackendConfig という名前のカスタム リソースに関連付けることで、ロードバランサの追加の構成を指定できます。

GKE Ingress コントローラは、BackendConfig から構成情報を読み取り、それに従ってロードバランサを設定します。BackendConfig には、Cloud Load Balancing に固有の構成情報が格納されています。Kubernetes Ingress とサービスのリソースでは Cloud CDN のようにプロバイダ固有の機能を構成することはできませんが、BackendConfig ではこれを構成できます。

この演習で BackendConfig を設定する方法の全体像は以下のとおりです。

  1. BackendConfig を作成します。
  2. サービスを作成し、そのポートの 1 つを BackendConfig に関連付けます。
  3. Ingress を作成して、Ingress を(サービス、ポート)ペアに関連付けます。

始める前に

このタスクの準備として、次の手順を行います。

  • Google Kubernetes Engine API が有効になっていることを確認します。
  • Google Kubernetes Engine API の有効化
  • Cloud SDK がインストール済みであることを確認します。
  • デフォルトのプロジェクト ID を設定します。
    gcloud config set project [PROJECT_ID]
  • ゾーンクラスタを使用する場合は、デフォルトのコンピューティング ゾーンを設定します。
    gcloud config set compute/zone [COMPUTE_ZONE]
  • リージョン クラスタを使用する場合は、デフォルトのコンピューティング リージョンを設定します。
    gcloud config set compute/region [COMPUTE_REGION]
  • gcloud を最新バージョンに更新します。
    gcloud components update

名前空間を作成する

このガイドのオブジェクトのための Kubernetes 名前空間を作成します。

kubectl create namespace cdn-how-to

Deployment を作成する

この Deployment マニフェストでは、ingress-gce-echo-amd64 ウェブ アプリケーションのレプリカを 2 つ実行することを宣言します。

apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: cdn-how-to
  name: my-deployment
spec:
  selector:
    matchLabels:
      purpose: demonstrate-cdn
  replicas: 2
  template:
    metadata:
      labels:
        purpose: demonstrate-cdn
    spec:
      containers:
      - name: echo-amd64
        image: gcr.io/google-samples/hello-app-cdn:1.0

このマニフェストを my-deployment.yaml という名前のファイルにコピーして、Deployment を作成します。

kubectl apply -f my-deployment.yaml

BackendConfig の作成

BackendConfig のマニフェストを次に示します。このマニフェストでは Cloud CDN のキャッシュ ポリシーを指定し、Cloud CDN の有効化を宣言します。

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  namespace: cdn-how-to
  name: my-backend-config
spec:
  cdn:
    enabled: true
    cachePolicy:
      includeHost: true
      includeProtocol: true
      includeQueryString: false

このマニフェストを my-backend-config.yaml という名前のファイルにコピーして、BackendConfig を作成します。

kubectl apply -f my-backend-config.yaml

BackendConfig を表示します。

kubectl get backendconfig my-backend-config --output yaml --namespace cdn-how-to

次のような Cloud CDN キャッシュ ポリシーが出力されます。

apiVersion: cloud.google.com/v1beta1
kind: BackendConfig
metadata:
  name: my-backend-config
  namespace: cdn-how-to
  ...
spec:
  cdn:
    cachePolicy:
      includeHost: true
      includeProtocol: true
      includeQueryString: false
    enabled: true

サービスの作成

サービスのマニフェストを次に示します。

apiVersion: v1
kind: Service
metadata:
  namespace: cdn-how-to
  name: my-service
  labels:
    purpose: demonstrate-cdn
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
spec:
  type: NodePort
  selector:
    purpose: demonstrate-cdn
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080

このマニフェストを my-service.yaml という名前のファイルに保存して、サービスを作成します。

kubectl apply -f my-service.yaml

Service を表示します。

kubectl get service my-service --namespace cdn-how-to --output yaml

出力は次のようになります。

apiVersion: v1
kind: Service
metadata:
  annotations:
    beta.cloud.google.com/backend-config: '{"ports": {"80":"my-backend-config"}}'
    ...
  labels:
    purpose: demonstrate-cdn
  name: my-service
  namespace: cdn-how-to
  ...
spec:
  clusterIP: 10.51.255.39
  externalTrafficPolicy: Cluster
  ports:
  - nodePort: 31484
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    purpose: demonstrate-cdn
  sessionAffinity: None
  type: NodePort
status:
  loadBalancer: {}

この演習では、サービスについて次の項目を把握することが重要です。

  • サービスのポート 80 は、my-backend-config という名前の BackendConfig に関連付けられます。これは、beta.cloud.google.com/backend-config アノテーションで指定されます。

  • サービスのタイプは NodePort です。これはサービスの一般的なタイプであり、Ingress に関連付けられます。

  • purpose: demonstrate-cdn のラベルが付いたポッドは、サービスのメンバーです。これは selector フィールドで指定されています。

  • TCP ポート 80 のサービスへのトラフィックは、メンバーのうちいずれかのポッドの TCP ポート 8080 にルーティングされます。これは port フィールドと targetPort フィールドで指定されています。

静的外部 IP アドレスの予約

静的外部 IP アドレスを予約します。

gcloud compute addresses create cdn-how-to-address --global

静的外部 IP アドレスを表示します。

gcloud compute addresses list --filter "name=cdn-how-to-address"

アドレスの名前と値が出力されます。

NAME                ...     ADDRESS        STATUS
cdn-how-to-address          203.0.113.1    RESERVED

Ingress の作成

Ingress のマニフェストを次に示します。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  namespace: cdn-how-to
  name: my-ingress
  annotations:
    kubernetes.io/ingress.global-static-ip-name: "cdn-how-to-address"
spec:
  rules:
  - http:
      paths:
      - path: /*
        backend:
          serviceName: my-service
          servicePort: 80

マニフェストを my-ingress.yaml という名前のファイルにコピーして、Ingress を作成します。

kubectl apply -f my-ingress.yaml

Kubernetes Ingress コントローラによる Cloud ロードバランサの構成が完了するまで 10 分間待機し、その後 Ingress を表示します。

kubectl get ingress my-ingress --output yaml --namespace cdn-how-to

出力は次のようになります。

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  ...
  name: my-ingress
  namespace: cdn-how-to
  ...
spec:
  rules:
  - http:
      paths:
      - backend:
          serviceName: my-service
          servicePort: 80
        path: /*
status:
  loadBalancer:
    ingress:
    - ip: 201.0.113.1

この演習では、Ingress について次の項目を把握することが重要です。

  • 受信トラフィックの IP アドレスは、loadBalancer:ingress: の下に一覧表示されます。

  • Ingress には、あらゆるホストから受信する HTTP リクエストに適用される 1 つのルールがあります。これは、ルールに host フィールドがないためです。そのため、デフォルトでは、ルールはすべてのホストに適用されます。

  • URL パスにかかわらず、すべての受信リクエストが同じように処理されます。これは、path の値の /* の部分で指定されます。

  • 受信リクエストは、my-service のメンバーのポッドにルーティングされます。この演習では、メンバーのポッドには purpose: demonstrate-cdn というラベルが付与されています。

  • リクエストは、my-service で指定されたターゲット ポートのポッドにルーティングされます。この演習では、ポッドのターゲット ポートは 8080 です。

ウェブアプリの表示

次の curl コマンドを 2 回入力します。

curl -v [STATIC_ADDRESS]/?cache=true

[STATIC_ADDRESS] は、静的外部 IP アドレスです。

出力にはレスポンス ヘッダーと本文が表示されます。レスポンス ヘッダーで、コンテンツがキャッシュされたことがわかります。Age ヘッダーは、コンテンツが何秒間キャッシュされたかを示します。

...
< HTTP/1.1 200 OK
< Date: Fri, 25 Jan 2019 02:34:08 GMT
< Content-Length: 70
< Content-Type: text/plain; charset=utf-8
< Via: 1.1 google
< Cache-Control: max-age=86400,public
< Age: 2716
<
Hello, world!
Version: 1.0.0
Hostname: my-deployment-7f589cc5bc-l8kr8

負荷分散ログの表示

HTTP 負荷分散の Stackdriver ログを表示すると、コンテンツがキャッシュされたことを確認できます。このログを確認する前に、アプリからのレスポンスを少なくとも 2 回リクエストしていることを確認してください。

Console

GCP Console で、[ログ] ページの [ロギング] メニューに移動します。

[ログ] ページに移動

最初のメニューで、[Cloud HTTP ロードバランサ] を選択します。

最新のログエントリを展開し、エントリの httpRequest フィールドを展開します。

httpRequest フィールドでは、cacheHittrue になっています。

httpRequest: {
cacheHit:  true
cacheLookup:  true
...

gcloud

gcloud logging read \
    'logName="projects/[PROJECT_ID]/logs/requests"' \
    --limit 2

ここで、[PROJECT_ID] はプロジェクト ID です。

出力では、キャッシュ ヒットがあったことが示されます。

httpRequest:
cacheHit: true
cacheLookup: true

制限事項

Cloud CDN と Cloud Identity-Aware Proxy を同じ HTTP(S) 負荷分散バックエンド サービスで有効化することはできません。

トラブルシューティング

BackendConfig が見つかりません

このエラーは、サービスのアノテーションでサービスポートの BackendConfig が指定されているにもかかわらず BackendConfig リソースが見つからなかった場合に発生します。これは、BackendConfig リソースがまったく作成されていない場合、誤った名前空間に作成された場合、サービス アノテーションの参照にスペルミスがあった場合に発生します。

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: error getting BackendConfig for port 80 on service “default/my-service”:
no BackendConfig for service port exists

Cloud CDN と Cloud IAP の両方が有効化されている

このエラーは、BackendConfig で Cloud IAP と Cloud CDN の両方が有効化された場合に発生します。

kubectl get event
KIND    ... SOURCE
Ingress ... loadbalancer-controller

MESSAGE
Error during sync: BackendConfig default/config-default is not valid:
iap and cdn cannot be enabled at the same time.

コンテンツがキャッシュされていない

コンテンツがキャッシュされていない場合は、アプリケーションが適切に構成されコンテンツのキャッシュが有効化されていることを確認してください。詳細については、キャッシュ可能性を参照してください。

クリーンアップ

このページの演習を完了したら、アカウントで不要な請求が発生しないように、以下の手順でリソースを削除します。

この演習で作成した Kubernetes オブジェクトを削除します。

kubectl delete ingress my-ingress --namespace cdn-how-to
kubectl delete service my-service --namespace cdn-how-to
kubectl delete backendconfig my-backend-config --namespace cdn-how-to
kubectl delete deployment my-deployment --namespace cdn-how-to
kubectl delete namespace cdn-how-to

静的外部 IP アドレスを削除します。

gcloud compute addresses delete cdn-how-to-address --global

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...

Kubernetes Engine のドキュメント