iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0

本篇大綱

這篇將會開始介紹在 K8s 組出服務必備的元素,第一篇來講的是 Pod & Workloads。

內文

接下來的三篇內,會簡介每個 Kubernetes 裡面組出基礎服務所需的元件。

Pod

Pod 是 K8s 的最小單位,每個 Pod 內部可能會有一個或多個 Container,而一個 Pod 會對應到一個應用程式,同一個 Pod 中的 Containers 則會共享相同的網路資源(如:IP地址、主機名稱等)。

這個是 Pod 的基礎設定:

# 1. Save as `nginx-pod.yaml`
# 2. In bash, `kubectl apply -f nginx-pod.yaml`
# 3. If you want to remove, `kubectl delete -f nginx-pod.yaml`
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

想要實作可以看上面的三行敘述:

  1. 這上面內容儲存為 nginx-pod.yaml
  2. kubectl apply -f nginx-pod.yaml 套用進 K8s 裡面
  3. 如果想要移除此 Pod,輸入 kubectl delete -f nginx-pod.yaml 就可以讓 K8s 刪掉

https://ithelp.ithome.com.tw/upload/images/20220923/20112934DsRgl38NZ6.png

通常實際在部署的時候也不會用 Pod,而是會用下面的那幾種 Workloads 來做,這邊只是先說 K8s 的基礎單位,之後要做 Debug 的時候優先都從 Pod 找起。

ReplicaSet & Deployment

ReplicaSet 跟 Deployment 可以合併介紹,Deployment 也是基於 ReplicaSet 實作而成的。

ReplicaSet 就是一組重複多個 Pod 組合而成,會有這樣的需求是為了要分攤運算

我們來用一張圖解釋

https://ithelp.ithome.com.tw/upload/images/20220923/20112934LL2nV9ykJZ.png

今天上述的圖看起來架構沒有問題,但如果流量突然提高,只有一個 Pod 其實就很容易掛掉,就算你給單個的 Pod 資源較多,但回應速度還是會很慢,因此我們就會需要 ReplicaSet 來分攤流量。

https://ithelp.ithome.com.tw/upload/images/20220923/20112934MaEMwGsZGW.png

Deployment 又是為了什麼而產生的呢?因為 ReplicaSet 不能做 Image 替換,Deployment 可以,這樣就可以做到 Rolling update,可以讓服務不斷線的情況下滾動升級。

Deployment 的基礎架構如下:

# 1. Save as `nginx-deploy.yaml`
# 2. In bash, `kubectl apply -f nginx-deploy.yaml`
# 3. If you want to remove, `kubectl delete -f nginx-deploy.yaml`
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

這裡要注意的是,.spec.selector.matchLabels 必須跟 .spec.template.metadata.labels 相同,不然會被系統 Reject,雖然不一定要跟原本 Deployment .metadata.labels 相同,但方便起見還是設定相同。

StatefulSet

大部分的應用程式都是 Stateless,但如果需要有狀態管理,StatefulSet 會是比較適用的情境。

這樣說感覺有點抽象,但可以用以下資訊來判斷是否要用到 StatefulSet:

  • 需要穩定 & 唯一的網路識別(Pod reschedule 後的 Pod name & hostname 都不會變動)
  • 需要穩定的儲存(Pod reschedule 還是能取得相同資料,通常用 Persistent Volume Claim 解決就好,PVC 將會在 Day 10 會介紹)
  • 部署或 Scale 上需要有順序產生(.spec.podManagementPolicy 預設 OrderedReady,也可以改成 Parallel 同時產生)

依照以上這些判斷,其實可以知道,如果想要用 Pod 來組 MongoDB Cluster 或 MySQL Cluster,Deployment 是不適合套用這個情境,StatefulSet 會是較佳的解決方式。

因為這裡還沒有介紹 PVC,這裡會寫沒有 .spec.volumeClaimTemplates 的版本

# 1. Save as `nginx-sts.yaml`
# 2. In bash, `kubectl apply -f nginx-sts.yaml`
# 3. If you want to remove, `kubectl delete -f nginx-sts.yaml`
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: "nginx-sts"
spec:
  selector:
    matchLabels:
      app: "nginx-sts"
  serviceName: "nginx-sts"
  replicas: 3
  template:
    metadata:
      labels:
        app: "nginx-sts"
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: k8s.gcr.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web

kubectl apply 進去以後,系統會依照編號產生 Pod。

https://ithelp.ithome.com.tw/upload/images/20220923/20112934HAytNDRVxV.png

DaemonSet

DaemonSet 會把 Pod 部署在每一個節點上,也就是在後台跑的程式,通常會應用在需要監控的情形,像是 Node metric、Logs collections。

DaemonSet 的基礎範例如下:

# 1. Save as `nginx-ds.yaml`
# 2. In bash, `kubectl apply -f nginx-ds.yaml`
# 3. If you want to remove, `kubectl delete -f nginx-ds.yaml`
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  labels:
    app: nginx-daemonset
spec:
  selector:
    matchLabels:
      app: nginx-daemonset
  template:
    metadata:
      labels:
        app: nginx-daemonset
    spec:
      tolerations:
      # 預設 DaemonSet 是不會把 Pod 放到 Control plane (Master node) 上
      # 加了 tolerations 這幾行設定就可以放到 Control plane 上面了
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: nginx-daemonset
        image: nginx:alpine
        resources:
          limits:
            cpu: 250m
            memory: 512Mi
          requests:
            cpu: 250m
            memory: 512Mi

https://ithelp.ithome.com.tw/upload/images/20220923/20112934NlVTQCmtBE.png

Job & CronJob

Job 就代表只有一次性的工作,我目前看過 Job 會出現的情形就是 GitLab 升級檢查的時候,會做 Pre-check 的工作,他們有規定版本升級步驟,為了確保升級、Migrate 可以順利進行。

# 1. Save as `pi-job.yaml`
# 2. In bash, `kubectl apply -f pi-job.yaml`
# 3. If you want to remove, `kubectl delete -f pi-job.yaml`
apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100 # 100 秒以後,此 Pod 將會被自動清除,沒有設定就不會清除
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

https://ithelp.ithome.com.tw/upload/images/20220923/20112934AbhR6AATen.png

CronJob 就是定時工作,如果 Application 本身會產生 Caches 需要清理,或者每天檢查更新版本,這些都可以放在 CronJob 進行。

如果想要再找其他的相關範例,可以去 K8s 官方文件來去閱讀。

本系列內容也會同步貼到我的 Blog https://blog.yangjerry.tw 歡迎來我的 Blog 點一下 RSS 追蹤,那我們就下一篇文章見啦!

Source


上一篇
Day 07 使用 Kubespray 建立自己的 K8S(二)
下一篇
Day 09 Kubernetes - Namespace & Service
系列文
關於我怎麼把一年內學到的新手 IT/SRE 濃縮到 30 天筆記這檔事30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言