示例:使用 Redis 部署 PHP Guestbook 應用程式

本教程展示瞭如何使用 Kubernetes 和 Docker 構建和部署一個簡單的(非生產環境可用)多層 Web 應用程式。此示例包含以下元件:

  • 一個單例項 Redis 用於儲存留言條目。
  • 多個 Web 前端例項。

目標

  • 啟動一個 Redis leader。
  • 啟動兩個 Redis follower。
  • 啟動留言簿前端。
  • 公開並檢視前端服務。
  • 清理。

準備工作

你需要一個 Kubernetes 叢集,並且 kubectl 命令列工具必須配置為與你的叢集通訊。建議在至少有兩個不是控制平面主機的節點的叢集上執行本教程。如果你還沒有叢集,可以使用 minikube 建立一個,或者使用這些 Kubernetes 遊樂場之一:

你的 Kubernetes 伺服器版本必須是 v1.14 或更高。

要檢查版本,請輸入 kubectl version

啟動 Redis 資料庫

留言簿應用程式使用 Redis 來儲存其資料。

建立 Redis Deployment

下面包含的清單檔案指定了一個 Deployment 控制器,它執行一個單副本 Redis Pod。

# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
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
  1. 在你下載清單檔案的目錄中啟動一個終端視窗。

  2. redis-leader-deployment.yaml 檔案應用 Redis Deployment

    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
    
  3. 查詢 Pod 列表以驗證 Redis Pod 是否正在執行

    kubectl get pods
    

    響應應類似於以下內容:

    NAME                           READY   STATUS    RESTARTS   AGE
    redis-leader-fb76b4755-xjr2n   1/1     Running   0          13s
    
  4. 執行以下命令檢視 Redis leader Pod 的日誌

    kubectl logs -f deployment/redis-leader
    

建立 Redis leader 服務

留言簿應用程式需要與 Redis 通訊以寫入資料。你需要應用一個 Service 來代理到 Redis Pod 的流量。Service 定義了訪問 Pod 的策略。

# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
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
  1. 從以下 redis-leader-service.yaml 檔案應用 Redis Service

    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
    
  2. 查詢 Service 列表以驗證 Redis Service 是否正在執行

    kubectl get service
    

    響應應類似於以下內容:

    NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
    kubernetes     ClusterIP   10.0.0.1     <none>        443/TCP    1m
    redis-leader   ClusterIP   10.103.78.24 <none>        6379/TCP   16s
    

設定 Redis follower

儘管 Redis leader 是一個單一的 Pod,但你可以透過新增一些 Redis follower(或副本)來使其高可用並滿足流量需求。

# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
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
  1. 從以下 redis-follower-deployment.yaml 檔案應用 Redis Deployment

    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
    
  2. 透過查詢 Pod 列表來驗證兩個 Redis follower 副本是否正在執行

    kubectl get pods
    

    響應應類似於以下內容:

    NAME                             READY   STATUS    RESTARTS   AGE
    redis-follower-dddfbdcc9-82sfr   1/1     Running   0          37s
    redis-follower-dddfbdcc9-qrt5k   1/1     Running   0          38s
    redis-leader-fb76b4755-xjr2n     1/1     Running   0          11m
    

建立 Redis follower 服務

留言簿應用程式需要與 Redis follower 通訊以讀取資料。為了使 Redis follower 可被發現,你必須設定另一個 Service

# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
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
  1. 從以下 redis-follower-service.yaml 檔案應用 Redis Service

    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
    
  2. 查詢 Service 列表以驗證 Redis Service 是否正在執行

    kubectl get service
    

    響應應類似於以下內容:

    NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP    3d19h
    redis-follower   ClusterIP   10.110.162.42   <none>        6379/TCP   9s
    redis-leader     ClusterIP   10.103.78.24    <none>        6379/TCP   6m10s
    

設定並公開留言簿前端

現在你已經啟動並運行了留言簿的 Redis 儲存,接下來啟動留言簿 Web 伺服器。與 Redis follower 一樣,前端也使用 Kubernetes Deployment 進行部署。

留言簿應用程式使用 PHP 前端。它配置為與 Redis follower 或 leader 服務通訊,具體取決於請求是讀取還是寫入。前端公開了一個 JSON 介面,並提供了一個基於 jQuery-Ajax 的使用者體驗。

建立留言簿前端 Deployment

# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
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
  1. frontend-deployment.yaml 檔案應用前端 Deployment

    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
    
  2. 查詢 Pod 列表以驗證三個前端副本是否正在執行

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

    響應應類似於以下內容:

    NAME                        READY   STATUS    RESTARTS   AGE
    frontend-85595f5bf9-5tqhb   1/1     Running   0          47s
    frontend-85595f5bf9-qbzwm   1/1     Running   0          47s
    frontend-85595f5bf9-zchwc   1/1     Running   0          47s
    

建立前端 Service

你應用的 Redis 服務只能在 Kubernetes 叢集內部訪問,因為 Service 的預設型別是 ClusterIPClusterIP 為 Service 指向的 Pods 集合提供一個單獨的 IP 地址。此 IP 地址只能在叢集內部訪問。

如果你希望客人能夠訪問你的留言簿,你必須將前端服務配置為外部可見,以便客戶端可以從 Kubernetes 叢集外部請求該服務。然而,即使服務使用 ClusterIP,Kubernetes 使用者也可以使用 kubectl port-forward 訪問該服務。

# SOURCE: https://cloud.google.com/kubernetes-engine/docs/tutorials/guestbook
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
  #type: LoadBalancer
  ports:
    # the port that this service should serve on
  - port: 80
  selector:
    app: guestbook
    tier: frontend
  1. frontend-service.yaml 檔案應用前端 Service

    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
    
  2. 查詢 Service 列表以驗證前端 Service 是否正在執行

    kubectl get services
    

    響應應類似於以下內容:

    NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
    frontend         ClusterIP   10.97.28.230    <none>        80/TCP     19s
    kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP    3d19h
    redis-follower   ClusterIP   10.110.162.42   <none>        6379/TCP   5m48s
    redis-leader     ClusterIP   10.103.78.24    <none>        6379/TCP   11m
    

透過 kubectl port-forward 檢視前端服務

  1. 執行以下命令將本地機器上的埠 8080 轉發到服務上的埠 80

    kubectl port-forward svc/frontend 8080:80
    

    響應應類似於以下內容:

    Forwarding from 127.0.0.1:8080 -> 80
    Forwarding from [::1]:8080 -> 80
    
  2. 在瀏覽器中載入頁面 https://:8080 以檢視你的留言簿。

透過 LoadBalancer 檢視前端服務

如果你使用 type: LoadBalancer 部署了 frontend-service.yaml 清單,你需要找到 IP 地址才能檢視你的留言簿。

  1. 執行以下命令獲取前端服務的 IP 地址。

    kubectl get service frontend
    

    響應應類似於以下內容:

    NAME       TYPE           CLUSTER-IP      EXTERNAL-IP        PORT(S)        AGE
    frontend   LoadBalancer   10.51.242.136   109.197.92.229     80:32372/TCP   1m
    
  2. 複製外部 IP 地址,並在瀏覽器中載入頁面以檢視你的留言簿。

擴充套件 Web 前端

你可以根據需要進行擴容或縮容,因為你的伺服器被定義為使用 Deployment 控制器的服務。

  1. 執行以下命令來增加前端 Pod 的數量

    kubectl scale deployment frontend --replicas=5
    
  2. 查詢 Pod 列表以驗證正在執行的前端 Pod 數量

    kubectl get pods
    

    響應應類似於以下內容:

    NAME                             READY   STATUS    RESTARTS   AGE
    frontend-85595f5bf9-5df5m        1/1     Running   0          83s
    frontend-85595f5bf9-7zmg5        1/1     Running   0          83s
    frontend-85595f5bf9-cpskg        1/1     Running   0          15m
    frontend-85595f5bf9-l2l54        1/1     Running   0          14m
    frontend-85595f5bf9-l9c8z        1/1     Running   0          14m
    redis-follower-dddfbdcc9-82sfr   1/1     Running   0          97m
    redis-follower-dddfbdcc9-qrt5k   1/1     Running   0          97m
    redis-leader-fb76b4755-xjr2n     1/1     Running   0          108m
    
  3. 執行以下命令來減少前端 Pod 的數量

    kubectl scale deployment frontend --replicas=2
    
  4. 查詢 Pod 列表以驗證正在執行的前端 Pod 數量

    kubectl get pods
    

    響應應類似於以下內容:

    NAME                             READY   STATUS    RESTARTS   AGE
    frontend-85595f5bf9-cpskg        1/1     Running   0          16m
    frontend-85595f5bf9-l9c8z        1/1     Running   0          15m
    redis-follower-dddfbdcc9-82sfr   1/1     Running   0          98m
    redis-follower-dddfbdcc9-qrt5k   1/1     Running   0          98m
    redis-leader-fb76b4755-xjr2n     1/1     Running   0          109m
    

清理

刪除 Deployments 和 Services 也會刪除任何正在執行的 Pods。使用標籤可以透過一個命令刪除多個資源。

  1. 執行以下命令刪除所有 Pods、Deployments 和 Services。

    kubectl delete deployment -l app=redis
    kubectl delete service -l app=redis
    kubectl delete deployment frontend
    kubectl delete service frontend
    

    響應應類似於以下內容:

    deployment.apps "redis-follower" deleted
    deployment.apps "redis-leader" deleted
    deployment.apps "frontend" deleted
    service "frontend" deleted
    
  2. 查詢 Pod 列表以驗證沒有 Pod 正在執行

    kubectl get pods
    

    響應應類似於以下內容:

    No resources found in default namespace.
    

下一步

最後修改於 2023 年 8 月 24 日下午 6:38 PST:使用 code_sample 簡碼代替 code 簡碼 (e8b136c3b3)