部署應用程式

本文提供範例,說明如何使用 Google Distributed Cloud (僅限軟體) for VMware 建立使用者叢集,並在其中部署應用程式。

事前準備

以這裡的範例來說,您需要使用隨附 MetalLB 負載平衡的使用者叢集。如要瞭解如何建立使用 MetalLB 的基本使用者叢集,請參閱建立基本叢集

您可以使用管理工作站上的 Google Cloud 主控台或指令列工具 kubectl 部署應用程式。

控制台

  1. 在控制台中,前往「Google Kubernetes Engine clusters overview」(Google Kubernetes Engine 叢集總覽) 頁面。

    前往 GKE 叢集

  2. 在叢集清單中,按一下使用者叢集,並確認您已登入該叢集。

    如果尚未登入使用者叢集,請按照「透過 Google Cloud 控制台管理叢集」一文中的操作說明登入。

容器

  1. 在「New container」(新增容器) 下方,選取「Existing container image」(現有容器映像檔)

  2. 在「Image path」(圖片路徑) 中輸入 us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0

  3. 按一下「繼續」

設定

  1. 在「Deployment name」(部署作業名稱) 中輸入 my-deployment

  2. 在「Namespace」(命名空間) 中輸入 default

  3. 輸入這兩個標籤:

    • 鍵 1app值 1metrics
    • 鍵 2department值 2 sales
  4. 在「Kubernetes cluster」(Kubernetes 叢集) 下拉式選單中,選取叢集。

  5. 按一下「繼續」

Expose

  1. 勾選「Expose deployment as a new service」(以新 Service 的形式公開 Deployment)

  2. 在「Port 1」(通訊埠 1) 中輸入 80

  3. 在「Target port 1」(目標通訊埠 1) 中輸入 8080。這是適當的值,因為 hello-app 容器預設會監聽 TCP 通訊埠 8080。您可以查看應用程式的 Dockerfile 和原始碼,確認這項設定。

  4. 在「通訊協定 1」中選取 TCP

  5. 在「服務類型」部分選取 LoadBalancer

按一下頁面底部的「部署」按鈕。

查看部署作業和服務詳細資料

  1. 部署作業就緒後, Google Cloud 控制台的「Kubernetes workloads」(Kubernetes 工作負載) 區段會開啟「Deployment details」(部署作業詳細資料) 頁面。在這個頁面中,您可以查看部署作業及其三個 Pod 的詳細資料。

  2. 在「Exposing services」(公開服務) 下方,按一下公開 Deployment 的 Service 名稱。在本練習中,名稱為 my-deployment-service

  3. 「服務詳細資料」頁面隨即開啟。這個頁面會顯示「服務」的詳細資料。舉例來說,您可以看到任何具有 app: metricsdepartment: sales 標籤的 Pod 都是 Service 的成員。請注意,my-deployment 中的 Pod 具有這些標籤。

您也可以看到「負載平衡器 IP」的值。叢集負載平衡器已自動設定負載平衡器 IP。

本服務的轉接

假設叢集外部的用戶端透過 TCP 通訊埠 80,將要求傳送至負載平衡器 IP 位址。要求會轉送至叢集負載平衡器。負載平衡器會將要求轉送至 TCP 通訊埠 8080 上的成員 Pod。請注意,my-deployment 中的每個 Pod 都有一個監聽 TCP 通訊埠 8080 的容器。

測試服務

前往負載平衡器 IP 可路由傳輸的機器。

如要呼叫服務,請在瀏覽器中輸入負載平衡器 IP,或使用 curl 等指令。例如:

curl [LOAD_BALANCER_IP]:80

輸出內容會顯示 Hello, world! 訊息。例如:

curl 203.0.113.1:80
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

刪除 Deployment

前往控制台「Kubernetes Engine」專區的「工作負載」頁面。

前往「Workloads」(工作負載) 頁面

在「Deployments」清單中,選取 my-deployment

按一下頁面頂端的「刪除」。這項操作會一併刪除 Deployment 和公開的 Service。

指令列

連線至管理工作站

取得管理工作站的 SSH 連線。在管理員工作站上執行下列步驟。

可建立部署作業

以下是部署的資訊清單:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  selector:
    matchLabels:
      app: metrics
      department: sales
  replicas: 3
  template:
    metadata:
      labels:
        app: metrics
        department: sales
    spec:
      containers:
      - name: hello
        image: "us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0"

將資訊清單複製到名為「my-deployment.yaml」的檔案,然後建立 Deployment:

kubectl apply --kubeconfig USER_CLUSTER_KUBECONFIG -f my-deployment.yaml

其中 USER_CLUSTER_KUBECONFIG 是指使用者叢集的 kubeconfig 檔案路徑。

取得部署項目的基本資訊:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment

輸出內容顯示 Deployment 有三個 Pod,而且全部可用:

NAME            READY   UP-TO-DATE   AVAILABLE   AGE
my-deployment   3/3     3            3           27s

列出 Deployment 中的 Pod:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get pods

輸出內容會顯示 Deployment 有三個執行中的 Pod:

NAME                             READY   STATUS    RESTARTS   AGE
my-deployment-54944c8d55-4srm2   1/1     Running   0          6s
my-deployment-54944c8d55-7z5nn   1/1     Running   0          6s
my-deployment-54944c8d55-j62n9   1/1     Running   0          6s

取得 Deployment 的詳細資訊:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployment my-deployment --output yaml

輸出內容會顯示 Deployment 規格和狀態的詳細資料:

kind: Deployment
metadata:
  ...
  generation: 1
  name: my-deployment
  namespace: default
  ...
spec:
  ...
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: metrics
      department: sales
  ...
    spec:
      containers:
      - image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
        imagePullPolicy: IfNotPresent
        name: hello
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3
  conditions:
  ‑ lastTransitionTime: "2019-11-11T18:44:02Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  ‑ lastTransitionTime: "2019-11-11T18:43:58Z"
    lastUpdateTime: "2019-11-11T18:44:02Z"
    message: ReplicaSet "my-deployment-54944c8d55" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3

描述您的部署作業:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG describe deployment my-deployment

輸出內容會顯示 Deployment 的詳細資料,包括相關聯的 ReplicaSet

Name:                   my-deployment
Namespace:              default
CreationTimestamp:      Mon, 11 Nov 2019 10:43:58 -0800
Labels:                 
...
Selector:               app=metrics,department=sales
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=metrics
           department=sales
  Containers:
    hello:
    Image:        us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    Port:         
    Host Port:    
    Environment:  
    Mounts:       
  Volumes:        
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  
NewReplicaSet:   my-deployment-54944c8d55 (3/3 replicas created)

建立 LoadBalancer 類型的服務

如要向叢集外部的用戶端公開發布 Deployment,其中一種方法是建立類型為 LoadBalancer 的 Kubernetes Service

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

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: metrics
    department: sales
  type: LoadBalancer
  ports:
  ‑ port: 80
    targetPort: 8080

針對本練習的目的,以下是 Service 需要瞭解的重要事項:

  • 任何具有 app: metrics 標籤和 department: sales 標籤的 Pod 都是 Service 的成員。請注意,my-deployment 中的 Pod 具有這些標籤。

  • 當用戶端將要求傳送至 TCP 通訊埠 80 上的 Service 時,要求會轉送到 TCP 通訊埠 8080 上的成員 Pod。

  • 每個成員 Pod 都必須有一個正在監聽 TCP 通訊埠 8080 的容器。

根據預設,hello-app 容器會監聽 TCP 通訊埠 8080。您可以查看應用程式的 Dockerfile 和程式碼,確認這點。

將資訊清單儲存到名為 my-service.yaml 的檔案,然後建立 Service:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG apply -f my-service.yaml

其中 USER_CLUSTER_KUBECONFIG 是指使用者叢集的 kubeconfig 檔案路徑。

建立 Service 時,Google Distributed Cloud 會自動在叢集負載平衡器上設定 loadBalancerIP 位址。

查看 Service:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get service my-service --output yaml

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

kind: Service
metadata:
  ...
  name: my-service
  namespace: default
  ...
spec:
  allocateLoadBalancerNodePorts: true
  clusterIP: 10.96.1.39
  clusterIPs:
  - 10.96.1.39
  externalTrafficPolicy: Cluster
  internalTrafficPolicy: Cluster
  ipFamilies:
  - IPv4
  ipFamilyPolicy: SingleStack
  ports:
  - nodePort: 31184
    port: 80
    protocol: TCP
    targetPort: 8080
  selector:
    app: metrics
    department: sales
  sessionAffinity: None
  type: LoadBalancer
status:
  loadBalancer:
    ingress:
    - ip: 203.0.113.1

從上述輸出內容中,您可以看到 Service 具有 clusterIPloadBalancerIP。此外,它還包含 porttargetPort

clusterIP與本練習無關。loadBalancerIP 是叢集外部用戶端可用來呼叫服務的 IP 位址。

舉例來說,請使用上述輸出內容中顯示的值。也就是說,假設您的服務具有 loadBalancerIP = 203.0.113.1、port = 80 和 targetPort = 8080。

用戶端會將要求傳送至 TCP 通訊埠 80 上的 203.0.113.1。要求會路由至叢集負載平衡器。負載平衡器會將要求轉送至 TCP 通訊埠 8080 上的成員 Pod。

呼叫您的服務:

curl LOAD_BALANCER_IP

輸出結果會顯示一則 Hello, world! 訊息:

curl 203.0.113.1
Hello, world!
Version: 2.0.0
Hostname: my-deployment-dbd86c8c4-9wpbv

刪除服務

刪除服務:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service

確認服務已刪除:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services

輸出內容不再顯示 my-service

刪除部署作業

刪除部署作業:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment

確認 Deployment 已刪除:

kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments

輸出內容不再顯示 my-deployment

後續步驟

建立 Service 和 Ingress