使用 Redis 和 PHP 建立多層級網頁應用程式

本教學課程示範如何使用 Google Kubernetes Engine (GKE) 建構多層級網頁應用程式。

在本教學課程中,執行下列操作:

  • 設定具備外部 IP 位址和負載平衡器的網頁應用程式。
  • 建立具有單一主要 (領導者) 和多個Redis 叢集副本 (追隨者)

這個範例說明下列 Kubernetes 概念:

  • 陳述式設定 採用 YAML 資訊清單檔案
  • Deployment,這是 Kubernetes 資源,用於決定一組 Pod 複本的設定
  • 服務:為一組 Pod 建立內部和外部負載平衡器

目標

如要在 GKE 上部署及執行應用程式,請按照下列步驟操作:

  1. 設定 Redis 領導者
  2. 設定兩個 Redis follower
  3. 設定網路前端
  4. 造訪網站
  5. 擴充網站前端

下圖概略說明您完成這些目標後建立的叢集架構:

GKE 叢集架構

費用

在本文件中,您會使用下列 Google Cloud的計費元件:

如要根據預測用量估算費用,請使用 Pricing Calculator

初次使用 Google Cloud 的使用者可能符合免費試用期資格。

完成本文所述工作後,您可以刪除建立的資源,避免繼續計費,詳情請參閱「清除所用資源」。

事前準備

Cloud Shell 已預先安裝本教學課程所需的軟體,包括 kubectlgcloud CLI。如果您未使用 Cloud Shell,則必須安裝 gcloud CLI。

  1. 登入 Google Cloud 帳戶。如果您是 Google Cloud新手,歡迎 建立帳戶,親自評估產品在實際工作環境中的成效。新客戶還能獲得價值 $300 美元的免費抵免額,可用於執行、測試及部署工作負載。
  2. 安裝 Google Cloud CLI。

  3. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  4. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  5. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  6. 確認專案已啟用計費功能 Google Cloud

  7. 啟用 GKE API:

    啟用 API 時所需的角色

    如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com
  8. 安裝 Google Cloud CLI。

  9. 若您採用的是外部識別資訊提供者 (IdP),請先使用聯合身分登入 gcloud CLI

  10. 執行下列指令,初始化 gcloud CLI:

    gcloud init
  11. 建立或選取 Google Cloud 專案

    選取或建立專案所需的角色

    • 選取專案:選取專案時,不需要具備特定 IAM 角色,只要您已獲授角色,即可選取任何專案。
    • 建立專案:如要建立專案,您需要具備專案建立者角色 (roles/resourcemanager.projectCreator),其中包含 resourcemanager.projects.create 權限。瞭解如何授予角色
    • 建立 Google Cloud 專案:

      gcloud projects create PROJECT_ID

      PROJECT_ID 替換為您要建立的 Google Cloud 專案名稱。

    • 選取您建立的 Google Cloud 專案:

      gcloud config set project PROJECT_ID

      PROJECT_ID 替換為 Google Cloud 專案名稱。

  12. 確認專案已啟用計費功能 Google Cloud

  13. 啟用 GKE API:

    啟用 API 時所需的角色

    如要啟用 API,您需要具備服務使用情形管理員 IAM 角色 (roles/serviceusage.serviceUsageAdmin),其中包含 serviceusage.services.enable 權限。瞭解如何授予角色

    gcloud services enable container.googleapis.com

準備環境

如要設定環境,請按照下列步驟操作:

  1. 設定環境變數:

    export PROJECT_ID=PROJECT_ID
    export COMPUTE_LOCATION=COMPUTE_LOCATION
    

    更改下列內容:

  2. 複製 GitHub 存放區:

    git clone https://github.com/GoogleCloudPlatform/kubernetes-engine-samples
    
  3. 變更為工作目錄:

    cd kubernetes-engine-samples/quickstarts/guestbook/
    

建立 GKE 叢集

建立 Autopilot 或 Standard GKE 叢集:

Autopilot

gcloud container clusters create-auto guestbook \
    --location=${COMPUTE_LOCATION} \

標準

gcloud container clusters create guestbook \
    --location=${COMPUTE_LOCATION} \
    --num-nodes=4

連線至叢集

設定 kubectl 與叢集通訊:

gcloud container clusters get-credentials guestbook \
    --location=${COMPUTE_LOCATION}

設定 Redis 領導者

應用程式使用 Redis 儲存資料,應用程式會將資料寫入 Redis 領導者執行個體,並從多個 Redis follower 執行個體讀取資料。

  1. 下列資訊清單說明 Kubernetes 部署作業,該作業會執行單一副本 Redis 領導者 Pod:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-leader
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
            role: leader
            tier: backend
        spec:
          containers:
          - name: leader
            image: "docker.io/redis:6.0.5"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379

    將資訊清單套用至叢集:

    kubectl apply -f redis-leader-deployment.yaml
    
  2. 確認 Redis 領導者 Pod 正在執行:

    kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME                           READY     STATUS    RESTARTS   AGE
    redis-leader-343230949-qfvrq   1/1       Running   0          43s
    

    STATUS」可能需要幾分鐘的時間,才會從 Pending 變更為 Running

建立 Redis 領導者服務

網頁應用程式需要與 Redis 領導者通訊來寫入資料。您可以建立服務,將流量代理至 Redis 領導者 Pod。

Service 是 Kubernetes 抽象層,可定義邏輯上的一組 Pod 和存取這些 Pod 的政策。建立 Service 時,您可以根據 Pod 標籤說明要代理的 Pod。

  1. 下列資訊清單說明 Redis 領導者的 Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-leader
      labels:
        app: redis
        role: leader
        tier: backend
    spec:
      ports:
      - port: 6379
        targetPort: 6379
      selector:
        app: redis
        role: leader
        tier: backend

    這個資訊清單包含一組標籤選取器。這些標籤與上一步中部署的標籤集相符。因此,這項服務會將網路流量轉送至上一步建立的 Redis 領導者 Pod。

    資訊清單的 ports 區段會宣告單一通訊埠對應。服務會針對與指定 selector 標籤相符的容器,將 port: 6379 的流量轉送至該容器的 targetPort: 6379。部署中使用的 containerPort 必須與 targetPort 相符,才能將流量轉送至部署。

    將資訊清單套用至叢集:

    kubectl apply -f redis-leader-service.yaml
    
  2. 確認 GKE 是否已建立服務:

    kubectl get service
    

    輸出結果會與下列內容相似:

    NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes     10.51.240.1     <none>        443/TCP    42s
    redis-leader   10.51.242.233   <none>        6379/TCP   12s
    

設定 Redis 追隨者

雖然 Redis 領導者為單一 Pod,但透過新增幾個 Redis 追隨者或副本,即可大幅提升 Redis 領導者的可用性並滿足流量需求。

  1. 下列資訊清單說明 Redis follower Pod 的部署:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis-follower
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: redis
      template:
        metadata:
          labels:
            app: redis
            role: follower
            tier: backend
        spec:
          containers:
          - name: follower
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-redis-follower:v2
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 6379
  2. 將資訊清單套用至叢集:

    kubectl apply -f redis-follower-deployment.yaml
    
  3. 確認兩個 Redis follower 副本正在執行:

    kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME                              READY   STATUS    RESTARTS   AGE
    redis-follower-76588f55b7-bnsq6   1/1     Running   0          27s
    redis-follower-76588f55b7-qvtws   1/1     Running   0          27s
    redis-leader-dd446dc55-kl7nl      1/1     Running   0          119s
    

    STATUS」可能需要幾分鐘的時間,才會從 Pending 變更為 Running

建立 Redis follower 服務

網路應用程式必須與 Redis 追隨者通訊來讀取資料。如要開放 Redis 追隨者以供偵測,則必須設定服務。

  1. 下列資訊清單說明 Redis follower 的 Service:

    apiVersion: v1
    kind: Service
    metadata:
      name: redis-follower
      labels:
        app: redis
        role: follower
        tier: backend
    spec:
      ports:
        # the port that this service should serve on
      - port: 6379
      selector:
        app: redis
        role: follower
        tier: backend

    這個資訊清單指定 Service 在通訊埠 6379 上執行。Service 的 selector 欄位與上一步驟中建立的 Redis follower Pod 相符。

    將資訊清單套用至叢集:

    kubectl apply -f redis-follower-service.yaml
    
  2. 確認 GKE 已建立 Service:

    kubectl get service
    

    輸出結果會與下列內容相似:

    NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes     10.51.240.1     <none>        443/TCP    1m
    redis-leader   10.51.242.233   <none>        6379/TCP   49s
    redis-follower 10.51.247.238   <none>        6379/TCP   3s
    

設定應用程式網頁前端

現在您已為應用程式準備好 Redis 儲存空間,請啟動網路伺服器。與 Redis 追隨者一樣,前端是使用 Kubernetes Deployment 部署。

這個網頁應用程式使用 PHP 前端,並設定為與 Redis follower 或 leader 服務通訊,視要求是讀取或寫入而定。前端會公開 JSON 介面,並提供以 jQuery Ajax 為基礎的 UI。

  1. 下列資訊清單說明網路伺服器的 Deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
    spec:
      replicas: 3
      selector:
        matchLabels:
            app: guestbook
            tier: frontend
      template:
        metadata:
          labels:
            app: guestbook
            tier: frontend
        spec:
          containers:
          - name: php-redis
            image: us-docker.pkg.dev/google-samples/containers/gke/gb-frontend:v5
            env:
            - name: GET_HOSTS_FROM
              value: "dns"
            resources:
              requests:
                cpu: 100m
                memory: 100Mi
            ports:
            - containerPort: 80

    資訊清單檔案指定了環境變數 GET_HOSTS_FROM=dns。 將設定提供給網路前端應用程式時,前端應用程式會使用主機名稱 redis-followerredis-leader 執行 DNS 查詢。DNS 查詢會找出您在先前步驟中建立的服務 IP 位址。這個概念稱為 DNS 服務探索。

    將資訊清單套用至叢集:

    kubectl apply -f frontend-deployment.yaml
    
  2. 確認備用資源正在執行:

    kubectl get pods -l app=guestbook -l tier=frontend
    

    輸出結果會與下列內容相似:

    NAME                        READY   STATUS    RESTARTS   AGE
    frontend-7b78458576-8kp8s   1/1     Running   0          37s
    frontend-7b78458576-gg86q   1/1     Running   0          37s
    frontend-7b78458576-hz87g   1/1     Running   0          37s
    

在外部 IP 位址公開前端

根據目前的設定,您在先前的步驟中建立的 redis-followerredis-leader 服務只能在 GKE 叢集中存取,因為服務的預設類型為 ClusterIP

ClusterIP Service 會為 Service 所指向的一組 Pod 提供單一 IP 位址。這個 IP 位址只能在叢集中存取。

如要讓外部存取網路前端服務,您可以根據需求在服務設定中指定 type: LoadBalancertype: NodePort

以下資訊清單說明 LoadBalancer 類型的 Service:

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  type: LoadBalancer
  ports:
    # the port that this service should serve on
  - port: 80
  selector:
    app: guestbook
    tier: frontend

ports 區段底下的通訊埠宣告會指定 port: 80,並且不會指定 targetPort。如果省略 targetPort 屬性,該屬性會預設為 port 欄位的值。在這種情況下,這項服務會將通訊埠 80 的流量轉送至 frontend 部署中容器的通訊埠 80。

將資訊清單套用至叢集:

kubectl apply -f frontend-service.yaml

建立 frontend Service 後,GKE 會建立負載平衡器和外部 IP 位址。這些資源需要計費

前往應用程式網站

如要存取應用程式網站,請取得 frontend 服務的外部 IP 位址:

kubectl get service frontend

輸出結果會與下列內容相似:

NAME       CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
frontend   10.51.242.136   109.197.92.229     80:32372/TCP   1m

建立負載平衡器時,EXTERNAL-IP 欄可能會顯示 <pending>。這可能需要幾分鐘的時間。如果看到 Does not have minimum availability 等錯誤訊息,請稍候幾分鐘。GKE 會重新建立節點來進行變更,因此發生這項暫時性錯誤。

複製 IP 位址,並在瀏覽器中開啟該頁面:

在 GKE 上執行的網頁應用程式

請嘗試輸入訊息,然後按一下「提交」,新增一些留言。您輸入的訊息會顯示在前端。這則訊息表示資料已透過您建立的服務成功新增至 Redis。

擴充網站前端

假設您的應用程式在運作一段時間後突然爆紅。您認為在前端新增更多網路伺服器會是個不錯的主意。您可以增加 Pod 數量來達成這個目標。

  1. 向上擴充 frontend Pod 數量:

    kubectl scale deployment frontend --replicas=5
    

    輸出結果會與下列內容相似:

    deployment.extensions/frontend scaled
    
  2. 確認正在執行的副本數量:

    kubectl get pods
    

    輸出結果會與下列內容相似:

    NAME                             READY     STATUS    RESTARTS   AGE
    frontend-88237173-3s3sc          1/1       Running   0          1s
    frontend-88237173-twgvn          1/1       Running   0          1s
    frontend-88237173-5p257          1/1       Running   0          23m
    frontend-88237173-84036          1/1       Running   0          23m
    frontend-88237173-j3rvr          1/1       Running   0          23m
    redis-leader-343230949-qfvrq     1/1       Running   0          54m
    redis-follower-132015689-dp23k   1/1       Running   0          37m
    redis-follower-132015689-xq9v0   1/1       Running   0          37m
    

    您可以使用相同指令縮減 frontend Pod 數量,只要將 5 換成 1 即可。

清除所用資源

為避免因為本教學課程所用資源,導致系統向 Google Cloud 收取費用,請刪除含有相關資源的專案,或者保留專案但刪除個別資源。

刪除專案

    刪除 Google Cloud 專案:

    gcloud projects delete PROJECT_ID

刪除個別資源

如果您使用現有專案,但不想刪除專案,請刪除個別資源。

  1. 刪除 frontend 服務:

    kubectl delete service frontend
    
  2. 刪除 GKE 叢集:

    gcloud container clusters delete guestbook
    

後續步驟