GKE上使用K8s Deployment及Service
2022/10/23
建立Cluster
使用gcloud container cluster create command建立cluster
通常測試的時候我會用下面範例這些option來設定
- machine-type: 設定Compute Engine machine type, 在測試的時候可以調小一點避免費用過高
- num-nodes: 每個zone建立後的node數量(node對應的就是Compute Engine VM)
- total-max-nodes: 限制Node pool(Instance Group)內最多的node(VM)數量
- disk-size: VM的boot disk size, 因為預設為100GB滿大的, 所以在測試情況下我都會特別設定小一點
- scopes: Compute Engine accss scopes, 可用值可參考此連結
- zone/region: 依照需求設定, 使用region設定regional cluster, 或是使用zone設定zonal cluster
gcloud container clusters create [cluster-name] \
--machine-type e2-micro \
--num-nodes 2 \
--total-max-nodes 5 \
--disk-size 16 \
--scopes "storage-rw" \
--zone us-central1-a
完整建立cluster的時間會滿久的(3-5分鐘)
需要稍微等一下
連接cluster
使用gcloud container clusters get-credentials command來連接cluster
zone或region來連接zonal/regional cluster
# 連接zonal cluster
gcloud container clusters get-credentials [cluster-name] --zone [zone] --project [project-id]
# 連接regional cluster
gcloud container clusters get-credentials [cluster-name] --region [region] --project [project-id]
建立deployment
這邊使用一個我自己做的簡易node.js express web docker image來測試
這個服務執行起來container port為3000
並需要使用一個NODE_APP_PROJECTenv 來顯示專案區別用
完整範例(deployment.yml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-web
spec:
replicas: 2
selector:
# match spec.template.metadata中的labels
matchLabels:
app: nodejs-web-pod
template:
# pod的metadata
metadata:
# 設定pods label
labels:
app: nodejs-web-pod
spec:
containers:
- name: nodejs-web-container
image: docker.io/ciaochung/nodejs-web:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
env:
- name: NODE_APP_PROJECT
value: GKE Demo
spec.replicas(optional)
設定每個node中的pod的數量(預設為1)
containers imagePullPolicy(optional)
spec.template.spec.containers[].imagePullPolicy
設定該container的image更新(pull)政策
有三種方式
不過除非使用pre-pull image
不然直接使用Always即可
建立deployment
kubectl apply -f deployment.yml
建立Service
完整範例(service.yml)
apiVersion: v1
kind: Service
metadata:
name: nodejs-web-service
namespace: default
spec:
ports:
- protocol: TCP
port: 80
# pod內部的port
targetPort: 3000
# 必須match deployment中的pod label設定
selector:
app: nodejs-web-pod
type: LoadBalancer
建立service
kubectl apply -f service.yml
合併yaml使用
yaml檔案本身可使用---將多個檔案合併在同個檔案做區隔
範例(web.yml)
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-web
spec:
replicas: 2
selector:
matchLabels:
app: nodejs-web-pod
template:
metadata:
labels:
app: nodejs-web-pod
spec:
containers:
- name: nodejs-web-container
image: docker.io/ciaochung/nodejs-web:latest
imagePullPolicy: Always
ports:
- containerPort: 3000
env:
- name: NODE_APP_PROJECT
value: GKE Demo
---
apiVersion: v1
kind: Service
metadata:
name: nodejs-web-service
namespace: default
spec:
ports:
- protocol: TCP
port: 80
targetPort: 3000
selector:
app: nodejs-web-pod
type: LoadBalancer
同時建立資源
透過這個合併的yaml檔
可同時建立(或apply)多個資源
kubectl apply -f web.yml
刪除資源
刪除deployment
kubectl delete deployment [deployment-name]
# example
kubectl delete deployment nodejs-web
刪除service
kubectl delete service [service-name]
# example
kubectl delete service nodejs-web-service
同時刪除資源
透過上面提到的合併yaml檔
也可以同時刪除多個資源
kubectl delete -f web.yml
刪除cluster
cluster刪除時間會比較久一點
# 刪除zonal cluster
gcloud container clusters delete [cluster-name] --zone [zone]
# 刪除regional cluster
gcloud container clusters delete [cluster-name] --region [region]
其他
ssh進入Pod/Container
# linux
kubectl exec -it [pod-name] -- /bin/bash
# alpine
kubectl exec -it [pod-name] -- sh
更新image
kubectl set image [deployment-name] [container-name]=[image-path]:[image-tag]
# example
kubectl set image deployment.apps/nodejs-web nodejs-web-container=docker.io/ciaochung/nodejs-web:dev
要注意的是
- container-name為deployment yaml中spec.template.spec.containers[].name欄位
- image-tag一定要跟原本的版本不同, 否則將不會進行更新(例如原本使用latest更新的時候又用latest)
若有設定更換image成功
將會看到k8s建立新的Pod並刪除原始版本的Pod
使用port-forward將container的port mapping至local
# pod's port forward
kubectl port-forward [pod-name] [localhost-port]:[target-port]
# pod's port forward(example)
kubectl port-forward pod/my-pod 3000:80
# service's port forward
kubectl port-forward [service-name] [localhost-port]:[target-port]
# service's port forward(example)
kubectl port-forward service/my-service 3000:80
# 指定namespace(example)
kubectl port-forward service/my-service 3000:80 -n foobar