本文舉例說明如何在僅使用 VMware 適用的 Google Distributed Cloud 軟體建立的使用者叢集中部署應用程式。
事前準備
在本例中,您需要使用套裝 MetalLB 負載平衡的使用者叢集。如需建立使用 MetalLB 的基本使用者叢集,請參閱「建立基本叢集」的操作說明。
您可以使用 Google Cloud 控制台,或在管理員工作站上使用指令列工具 kubectl 部署應用程式。
控制台
在控制台中,前往「Google Kubernetes Engine clusters overview」(Google Kubernetes Engine 叢集總覽) 頁面。
在叢集清單中,按一下使用者叢集,並確認您已登入叢集。
如果您尚未登入使用者叢集,請按照「透過 Google Cloud 控制台管理叢集」中的操作說明登入。
容器
在「New container」(新增容器) 下方,選取「Existing container image」(現有容器映像檔)。
在「Image path」(映像檔路徑) 中輸入
us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0。按一下「繼續」。
設定
在「Deployment name」(部署作業名稱) 中輸入
my-deployment。在「Namespace」部分輸入
default。輸入以下兩個標籤:
- Key 1:
app,Value 1:metrics - 鍵 2:
department,值 2:sales
- Key 1:
在「Kubernetes cluster」(Kubernetes 叢集) 下拉式選單中,選取您的叢集。
按一下「繼續」。
揭露
勾選「Expose deployment as a new service」(以新 Service 的形式公開 Deployment)。
在「Port 1」(通訊埠 1) 輸入
80。在「Target port 1」(目標通訊埠 1) 中輸入
8080。hello-app容器預設會監聽 TCP 通訊埠 8080,因此這是適當的值。您可以查看應用程式的 Dockerfile 和原始碼,瞭解這項設定。在「Protocol 1」(通訊協定 1) 部分,選取「
TCP」。在「Service type」(服務類型) 部分,選取「
LoadBalancer」。
按一下頁面底部的「部署」按鈕。
查看 Deployment 和 Service 詳細資料
Deployment 準備就緒後, Google Cloud 控制台的「Kubernetes workloads」(Kubernetes 工作負載) 區段會開啟「Deployment details」(Deployment 詳細資料) 頁面。在這個頁面中,您可以查看 Deployment 及其三個 Pod 的詳細資料。
在「Exposing services」(公開服務) 下方,按一下公開 Deployment 的 Service 名稱。在本練習中,名稱為
my-deployment-service。「Service details」(服務詳細資料) 頁面隨即開啟。在這個頁面中,您可以查看 Service 的詳細資料。舉例來說,您可以看到任何具有
app: metrics和department: sales標籤的 Pod 都是 Service 的成員。請注意,my-deployment中的 Pod 具有這些標籤。
您也可以看到「Load balancer IP」(負載平衡器 IP) 的值。叢集負載平衡器會自動設定負載平衡器 IP。
轉送 Service
假設叢集外部的用戶端在 TCP 通訊埠 80 上,向負載平衡器 IP 傳送要求。要求會轉送至叢集負載平衡器。負載平衡器會將要求轉送至 TCP 通訊埠 8080 上的成員 Pod。請注意,my-deployment 中的每個 Pod 都有一個容器,用於監聽 TCP 通訊埠 8080。
測試 Service
前往可轉送負載平衡器 IP 的機器。
如要呼叫 Service,請在瀏覽器中輸入負載平衡器 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」(工作負載) 頁面。
在部署項目清單中,選取 my-deployment。
按一下頁面頂端的「刪除」圖示 。這麼做會刪除 Deployment 和公開的 Service。
指令列
連線至管理員工作站
建立與管理員工作站的 SSH 連線。請在管理員工作站執行下列步驟。
建立 Deployment
以下是部署的資訊清單:
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 檔案路徑。
取得 Deployment 的基本資訊:
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 類型的 Service
如要向叢集外的用戶端公開 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 具有 clusterIP 和 loadBalancerIP。此外,還有 port 和 targetPort。
clusterIP 與本練習無關。loadBalancerIP 是叢集外部用戶端可用來呼叫 Service 的 IP 位址。
舉例來說,請查看上述輸出內容中顯示的值。也就是說,假設您的 Service 具有 loadBalancerIP = 203.0.113.1、port = 80 和 targetPort = 8080。
用戶端向 203.0.113.1 的 TCP 通訊埠 80 傳送要求。要求會轉送至叢集負載平衡器。負載平衡器會將要求轉送至 TCP 通訊埠 8080 上的成員 Pod。
呼叫 Service:
curl LOAD_BALANCER_IP
輸出結果會顯示一則 Hello, world! 訊息:
curl 203.0.113.1 Hello, world! Version: 2.0.0 Hostname: my-deployment-dbd86c8c4-9wpbv
刪除 Service
刪除 Service:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete service my-service
確認 Service 已刪除:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get services
輸出內容不會再顯示 my-service。
刪除部署作業
刪除 Deployment:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG delete deployment my-deployment
確認 Deployment 已刪除:
kubectl --kubeconfig USER_CLUSTER_KUBECONFIG get deployments
輸出內容不會再顯示 my-deployment。