《關於我怎麼把一年內學到的新手 IT/SRE 濃縮到 30 天筆記這檔事》 Day 08 Kubernetes - Pod & Workloads

本篇大綱

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

內文

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

Pod

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

這個是 Pod 的基礎設定:

1
2
3
4
5
6
7
8
9
10
11
12
13
# 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 刪掉

day08-01.png

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

ReplicaSet & Deployment

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

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

我們來用一張圖解釋

day08-02.png

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

day08-03.png

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

Deployment 的基礎架構如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 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。

day08-04.png

DaemonSet

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

DaemonSet 的基礎範例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 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

day08-05.png

Job & CronJob

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 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

day08-06.png

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

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

本系列內容也會同步貼到我的 iT 邦幫忙 https://ithelp.ithome.com.tw/users/20112934 歡迎來點一下追蹤,那我們就下一篇文章見啦!

Source


《關於我怎麼把一年內學到的新手 IT/SRE 濃縮到 30 天筆記這檔事》 Day 08 Kubernetes - Pod & Workloads
https://blog.yangjerry.tw/2022/09/23/it2022-day08/
作者
Jerry Yang
發布於
2022年9月23日
許可協議