使用 Redis 和 PHP 建立留言板

本教學課程示範如何使用 GKE 建構簡易的多層級網路應用程式。

本教學課程說明如何在具有負載平衡器的外部 IP 上設定留言板網路服務,以及如何以單一主要執行個體與多個工作站執行 Redis 叢集。

本範例將會強調幾個重要的 GKE 概念:

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

目標

如要在 GKE 部署及執行留言板應用程式,必須完成下列操作:

  1. 設定 Redis 主要執行個體
  2. 設定 Redis 工作站
  3. 設定留言板網路前端
  4. 造訪留言板網站
  5. 擴充留言板網路前端

事前準備

請依照下列步驟啟用 Kubernetes Engine API:
  1. 造訪 Google Cloud Platform 主控台的 Kubernetes Engine 頁面
  2. 建立或選取專案。
  3. 等待 API 和相關服務完成啟用。這可能需要幾分鐘的時間。
  4. 請確認您已啟用 Google Cloud Platform 專案的計費功能。

    瞭解如何啟用計費功能

請安裝下列指令列工具,我們將在本教學課程中使用這些工具:

  • gcloud 可用於建立及刪除 Kubernetes Engine 叢集。gcloud 包含在 Google Cloud SDK 中。
  • kubectl 可用於管理 Kubernetes,這是 Kubernetes Engine 使用的叢集自動化調度管理系統。您可以使用 gcloud 來安裝 kubectl
    gcloud components install kubectl

設定 gcloud 指令列工具的預設設定

為了節省您在 gcloud 指令列工具輸入專案 IDCompute Engine 區域選項的時間,建議您採用以下預設設定:
gcloud config set project [PROJECT_ID]
gcloud config set compute/zone us-central1-b

下載設定檔

造訪 Kubernetes GitHub 存放區以下載本教學課程所用的設定檔:

建立 GKE 叢集

首先建立 GKE 叢集,以便您在這個叢集上執行留言板應用程式和 Redis 服務。

建立名稱為 guestbook 且有 2 個節點的容器叢集:

gcloud container clusters create guestbook --num-nodes=2

您可以使用下列指令列出專案中的叢集,或是取得單一叢集的詳細資料:

gcloud container clusters list
gcloud container clusters describe guestbook

步驟 1:設定 Redis 主要執行個體

留言板應用程式使用 Redis 儲存資料,將資料寫入 Redis 主要執行個體,並讀取多個 Redis 工作站 (從屬) 執行個體中的資料。首先要部署 Redis 主要執行個體。

使用名稱為 redis-master-deployment 的資訊清單檔案來部署 Redis 主要執行個體。這個資訊清單檔案會指定部署控制器,以執行單一備用資源 Redis 主要執行個體 Pod:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-master
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: redis
        role: master
        tier: backend
    spec:
      containers:
      - name: master
        image: k8s.gcr.io/redis:e2e  # or just image: redis
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        ports:
        - containerPort: 6379

執行下列指令以部署 Redis 主要執行個體:

kubectl create -f redis-master-deployment.yaml

確認 Redis 主要執行個體 Pod 正在執行 kubectl get pods

kubectl get pods
輸出:
NAME                           READY     STATUS    RESTARTS   AGE
redis-master-343230949-qfvrq   1/1       Running   0          43s

複製上述指令輸出內容中的 Pod 名稱並執行下列指令,以查看 Redis 主要執行個體 Pod 中的記錄:

kubectl logs -f [POD_NAME]

建立 redis-master 服務

留言板應用程式需要與 Redis 主要執行個體通訊來寫入資料。您必須建立服務以代理 Redis 主要執行個體 Pod 的流量。

服務是 Kubernetes 抽象層,可定義邏輯上的一組 Pod 和存取這些 Pod 的政策。服務是有效的具名負載平衡器,會代理送向一或多個 Pod 的流量。在設定服務時,您可以根據 Pod 標籤向服務告知要代理的 Pod。

查看 redis-master-service.yaml 資訊清單檔案如何描述 Redis 主要執行個體的服務資源:

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

這個資訊清單檔案會建立具有一組標籤選取器且名稱為 redis-master 的服務。這些標籤符合在上一步驟中部署的標籤集。因此,這項服務會將網路流量轉送至步驟 1 建立的 Redis 主要執行個體 Pod。

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

執行下列指令來啟動 Redis 主要執行個體的服務:

kubectl create -f redis-master-service.yaml

確認服務已建立:

kubectl get service
輸出:
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    42s
redis-master   10.51.242.233   <none>        6379/TCP   12s

步驟 2:設定 Redis 工作站

雖然 Redis 主要執行個體為單一 pod,但透過新增幾個 Redis 工作站備用資源,即可大幅提升 Redis 主要執行個體的可用性並滿足流量需求。

查看 redis-slave-deployment.yaml 資訊清單檔案如何描述 Redis 工作站 pod 的部署:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis-slave
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: redis
        role: slave
        tier: backend
    spec:
      containers:
      - name: slave
        image: gcr.io/google_samples/gb-redisslave:v1
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access an environment variable to find the master
          # service's host, comment out the 'value: dns' line above, and
          # uncomment the line below:
          # value: env
        ports:
        - containerPort: 6379

部署負責達成資訊清單檔案中宣告的設定。例如,此資訊清單檔案為 Redis 工作站定義了兩個備用資源。如果沒有任何正在執行的備用資源,部署便會在您的容器叢集上啟動兩個備用資源。如果執行中的備用資源超過兩個,則系統會終止部分備用資源以符合指定的設定。

在本範例中,部署物件指定兩個備用資源。如要建立 Redis 工作站部署,請執行:

kubectl create -f redis-slave-deployment.yaml

查詢 Pod 清單,確認兩個 Redis 工作站備用資源皆處於運作中的狀態。

kubectl get pods
輸出:
NAME                           READY     STATUS    RESTARTS   AGE
redis-master-343230949-qfvrq   1/1       Running   0          17m
redis-slave-132015689-dp23k    1/1       Running   0          2s
redis-slave-132015689-xq9v0    1/1       Running   0          2s

建立 redis-slave 服務

留言板應用程式需要與 Redis 工作站通訊來讀取資料。如要開放 Redis 工作站以供偵測,則必須設定服務。服務會向一組 Pod 提供透明化負載平衡。

redis-slave-service.yaml 定義 Redis 工作站的服務設定:

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

此檔案定義了在通訊埠 6379 上運作且名稱為 redis-slave 的服務。請注意,服務的 selector 欄位需與上一步驟中建立的 Redis 工作站 Pod 相符。

執行下列指令以建立 redis-slave 服務:

kubectl create -f redis-slave-service.yaml

確認服務已建立:

kubectl get service
輸出:
NAME           CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
kubernetes     10.51.240.1     <none>        443/TCP    1m
redis-master   10.51.242.233   <none>        6379/TCP   49s
redis-slave    10.51.247.238   <none>        6379/TCP   3s

步驟 3:設定留言板網路前端

您現在已經啟動並執行留言板的 Redis 儲存空間,可以開始使用留言板網路前端。與 Redis 工作站一樣,這是由部署代管的複製應用程式。

本教學課程使用簡易的 PHP 前端,且設定為與 Redis 工作站或主要執行個體服務進行通訊,視收到的要求為讀取或寫入而定。PHP 採用簡易的 JSON 介面,並提供以 jQuery-Ajax 為基礎的使用者體驗。

查看 frontend-deployment.yaml 資訊清單檔案如何描述留言板網路伺服器的部署:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: frontend
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: guestbook
        tier: frontend
    spec:
      containers:
      - name: php-redis
        image: gcr.io/google-samples/gb-frontend:v4
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
        env:
        - name: GET_HOSTS_FROM
          value: dns
          # If your cluster config does not include a dns service, then to
          # instead access environment variables to find service host
          # info, comment out the 'value: dns' line above, and uncomment the
          # line below:
          # value: env
        ports:
        - containerPort: 80

如要建立留言板網路前端部署,請執行:

kubectl create -f frontend-deployment.yaml

查詢可識別網路前端的標籤清單,確認三個備用資源皆處於運作中的狀態:

kubectl get pods -l app=guestbook -l tier=frontend
輸出:
NAME                      READY     STATUS    RESTARTS   AGE
frontend-88237173-5p257   1/1       Running   0          40s
frontend-88237173-84036   1/1       Running   0          40s
frontend-88237173-j3rvr   1/1       Running   0          40s

上述的資訊清單檔案指定了環境變數 GET_HOSTS_FROM=dns。將這個設定提供給留言板網路前端應用程式時,將使用主機名稱 redis-slaveredis-master,並執行 DNS 查詢來尋找先前步驟中所建各個服務的 IP 位址。這個概念稱為 DNS 服務探索。

在外部 IP 位址公開前端

由於服務類型是 ClusterIP,因此,必須在容器叢集中才能存取您在先前步驟中建立的 redis-slaveredis-master 服務。ClusterIP 提供單一 IP 位址,供服務所指向的一組 Pod 使用。這個 IP 位址只能在叢集中存取。

然而,您需要向外公開留言板網路前端服務。也就是說,您想要讓用戶端可在容器叢集的外部要求服務。為了達成這個目的,您必須在服務設定中指定 type: LoadBalancer。指定這項設定的 frontend-service.yaml 資訊清單檔案如下所示:

apiVersion: v1
kind: Service
metadata:
  name: frontend
  labels:
    app: guestbook
    tier: frontend
spec:
  # if your cluster supports it, uncomment the following to automatically create
  # an external load-balanced IP for the frontend service.
  # type: LoadBalancer
  ports:
  - port: 80
  selector:
    app: guestbook
    tier: frontend

建立 frontend 服務後,GKE 會建立負載平衡器和外部 IP 位址。請注意,這些資源需要計費。在 ports 區段底下的通訊埠宣告會指定 port: 80,並且不會指定 targetPort。如果省略 targetPort 屬性,該屬性會預設為 port 值。在這種情況下,這項服務會將通訊埠 80 的流量轉送至 frontend 部署中容器的通訊埠 80。

如要建立服務,首先在 frontend-service.yaml 檔案中將下列這行取消註解:

type: LoadBalancer

然後執行下列指令以建立服務:

kubectl create -f frontend-service.yaml

步驟 4:造訪留言板網站

如要存取留言板服務,您需要執行下列指令,找出剛剛所設服務的外部 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 欄中的 IP,並在您的瀏覽器中載入頁面。

在 GKE 上執行的留言板

恭喜!請嘗試新增一些留言板項目。

步驟 5:擴充網站前端

假設您的留言板應用程式在運作一段時間後突然爆紅。您認為在前端新增更多網路伺服器會是個不錯的主意。這個想法可以輕鬆實現,因為您將伺服器定義為使用部署控制器的服務。

執行下列指令以擴充 frontend Pod 的數量:

kubectl scale deployment frontend --replicas=5

部署的設定會更新為指定目前應有 5 個備用資源正在運作中,而且部署會調整運作中的 Pod 數量以符合設定。如要確認,請執行下列指令:

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-master-343230949-qfvrq   1/1       Running   0          54m
redis-slave-132015689-dp23k    1/1       Running   0          37m
redis-slave-132015689-xq9v0    1/1       Running   0          37m

當您的網站又回到默默無名的時候,您可以採用同樣的方式,縮減網路伺服器 Pod 的數量。

清除所用資源

如要避免系統向您的 Google Cloud Platform 帳戶收取您在本教學課程中使用資源的相關費用:

步驟 6:清除

完成本教學課程之後,請按照步驟移除下列資源,以免您的帳戶產生不必要的費用:

  1. 刪除服務:此步驟會取消分配為 frontend 服務所建立的 Cloud 負載平衡器:

    kubectl delete service frontend

  2. 等待針對 frontend 服務佈建的負載平衡器刪除完成:當您執行 kubectl delete 時,系統會在背景中以非同步的方式刪除負載平衡器。查看下列指令的輸出,等待負載平衡器刪除作業完成:

    gcloud compute forwarding-rules list

  3. 刪除容器叢集:此步驟會刪除構成容器叢集的資源,例如運算執行個體、磁碟和網路資源。

    gcloud container clusters delete guestbook

後續步驟

本頁內容對您是否有任何幫助?請提供意見:

傳送您對下列選項的寶貴意見...

這個網頁
Kubernetes Engine 教學課程