使用 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. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. Install the Google Cloud CLI.

  3. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  4. To initialize the gcloud CLI, run the following command:

    gcloud init
  5. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  6. Make sure that billing is enabled for your Google Cloud project.

  7. Enable the GKE API:

    gcloud services enable container.googleapis.com
  8. Install the Google Cloud CLI.

  9. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  10. To initialize the gcloud CLI, run the following command:

    gcloud init
  11. Create or select a Google Cloud project.

    • Create a Google Cloud project:

      gcloud projects create PROJECT_ID

      Replace PROJECT_ID with a name for the Google Cloud project you are creating.

    • Select the Google Cloud project that you created:

      gcloud config set project PROJECT_ID

      Replace PROJECT_ID with your Google Cloud project name.

  12. Make sure that billing is enabled for your Google Cloud project.

  13. Enable the GKE API:

    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 領導者服務

Web 應用程式需要與 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 追隨者或領導者服務進行通訊。前端會公開 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 類型的服務:

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 帳戶收取本教學課程中所用資源的相關費用,請刪除含有該項資源的專案,或者保留專案但刪除個別資源。

刪除專案

    Delete a Google Cloud project:

    gcloud projects delete PROJECT_ID

刪除個別資源

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

  1. 刪除 frontend 服務:

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

    gcloud container clusters delete guestbook
    

後續步驟