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)

ref

設定每個node中的pod的數量(預設為1)

 

containers imagePullPolicy(optional)

ref

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

ref

# 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

 

要注意的是

  1. container-name為deployment yaml中spec.template.spec.containers[].name欄位
  2. image-tag一定要跟原本的版本不同, 否則將不會進行更新(例如原本使用latest更新的時候又用latest)

 

若有設定更換image成功

將會看到k8s建立新的Pod並刪除原始版本的Pod

update-image.png

 

使用port-forward將container的port mapping至local

ref

# 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