Cloud CDN

本頁面說明使用 BackendConfig 自訂資源,在 Google Kubernetes Engine 中設定 Cloud CDN (Cloud CDN) 的方法。

總覽

在 GKE 叢集中,HTTP(S) 負載平衡會處理傳入流量。HTTP(S) 負載平衡是 Cloud Load Balancing 的元件。HTTP(S) 負載平衡器通常是由 GKE 輸入控制器設定,該控制器會從 Kubernetes Ingress 物件取得設定資訊。輸入會與一或多個服務物件建立關聯。每個 Service 物件都會保留轉送資訊,用以將傳入要求導向特定 Pod 和通訊埠。

從 Kubernetes 1.10.5-gke.3 版開始,您可以為負載平衡器提供額外的設定,方法是建立 Service 通訊埠與名為 BackendConfig自訂資源之間的關聯。

GKE Ingress 控制器會讀取 BackendConfig 中的設定資訊,並據此設定負載平衡器。BackendConfig 會保留 Cloud Load Balancing 專屬的設定資訊。Kubernetes Ingress 與 Service 資源不提供供應商專屬功能 (如 Cloud CDN) 的設定方法,但 BackendConfig 會提供設定方法。

以下大致說明如何在這個練習中設定 BackendConfig:

  1. 建立 BackendConfig。
  2. 建立 Service,將 Service 的其中一個通訊埠與 BackendConfig 建立關聯。
  3. 建立 Ingress,將 Ingress 與 (Service、通訊埠) 組合建立關聯。

事前準備

如要準備這項工作,請執行下列步驟:

  • 確認您已啟用 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
  • 閱讀 [Cloud CDN 總覽]。

  • 閱讀 [Cloud CDN 快取] 相關資訊。

  • 閱讀 Kubernetes IngressService 資源相關資訊。

  • 熟悉 BackendConfig 自訂資源。

建立命名空間

為本指南中的物件建立 Kubernetes 命名空間:

kubectl create namespace cdn-how-to

建立部署

這個部署資訊清單宣告您要執行 ingress-gce-echo-amd64 網路應用程式的兩個備用資源:

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 的檔案,然後建立部署:

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

建立 Service

以下是 Service 的資訊清單:

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 的檔案,然後建立 Service:

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: {}

就本練習而言,以下是 Service 需要注意的重要事項:

  • Service 的通訊埠 80 與名為 my-backend-config 的 BackendConfig 相關聯。這是由 beta.cloud.google.com/backend-config 註解所指定。

  • 服務具有 NodePort 類型。這是要與 Ingress 建立關聯的 Service 所需要的類型。

  • 具有標籤 purpose: demonstrate-cdn 的任何 Pod 都是 Service 的成員。這是由 selector 欄位所指定。

  • 導向 TCP 通訊埠 80 上服務的流量會轉送到其中一個成員 Pod 中的 TCP 通訊埠 8080。這是由 porttargetPort 欄位所指定。

預留靜態外部 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 負載平衡器,然後查看 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 要求。這是因為規則中沒有任何 host 欄位。因此根據預設,這個規則會套用到所有主機。

  • 不論網址路徑為何,系統對所有傳入要求都視為相同。這是透過 path/* 指定。

  • 傳入要求會轉送到做為 my-service 成員的 Pod。在本練習中,成員 Pod 具有標籤 purpose: demonstrate-cdn

  • 系統會將要求轉送到 my-service 指定的目標通訊埠上的 Pod。在本練習中,Pod 目標通訊埠為 8080。

查看網路應用程式

輸入這個 curl 指令兩次:

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 記錄來確認內容是否已快取。在檢查記錄前,請確保您已請求至少兩次來自應用程序的回應。

主控台

在 GCP 主控台中,前往「記錄」選單中的「記錄」頁面。

前往記錄頁面

在第一個下拉式選單中,選取 [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

如果 Service 註解已指定 Service 通訊埠的 BackendConfig,卻找不到實際的 BackendConfig 資源,就會發生這個錯誤。如果您尚未建立 BackendConfig 資源、在錯誤的命名空間中建立 BackendConfig 資源,或是在 Service 註解中拼錯參照名稱,都會發生這種情況。

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 說明文件