---
lang: zh-tw
title: Kubernetes Workloads
tags: K8s
---
# Workloads
+ Pods
+ Controllers
## What is a Pod?
+ Pod 是可以在Kubernetes中被建立和管理的最小可部署單位
### Using Pods
+ Pod 在Cluster中主要有兩種用法
|||
| -------- | -------- |
|單容器|最常見的使用方法|
|多容器|封裝多個緊密關聯且需要共用資源的容器組成|
1. 可以將Pod看作單個容器的包裝器,Kubernetes直接管理Pod,而不是容器
2. 只有在容器的關聯緊密時才使用多個容器運行在一個Pod
3. 每個Pod都只運行給特定的應用
4. 水平擴展應該使用多個Pod,每個應用使用一個Pod,稱為Replication
5. 通常使用一種Workload resource和對應的Controller建立和管理一組Pod Replication
6. Workloads能處理Replica的管理、上線,並在Pod故障時建立可替換的Pod
### Storage in Pods
+ 一個Pod可以設置一組共用的Storage Volume
+ Volume 允許Pod 中的容器重新啟動保留持久化資料
+ Pod 中的所有容器都可以訪問該共用Volume,從而共用資料
### Pod networking
+ Kubernetes為每個Pod都分配了唯一的IP位址,稱為Pod IP
+ Pod內每個容器共用Pod IP
+ Pod內的容器間可以用`localhost`溝通
### Pod 資源配置
+ Kubernetes裡,通常以千分之一的CPU配額為最小單位,用m來表示
+ 通常一個容器的CPU配額被定義為100~ 300m,即佔用0.1~0.3個CPU
+ 記憶體配額與CPU相似,單位是bytes
+ 資源配額限定需要設定以下兩個參數
|||
| -------- | -------- |
|requests|資源的最小需求量|
|limits |資源的最大允許量|
+ [Pod Template](/QzphVaWxTYCw2x-3JSK3tQ?view)
## Controller
+ ReplicaSet
+ ReplicationController
+ Deployment
+ StatefulSet
+ DaemonSet
+ Job and CronJob
+ Horizontal Pod Autoscaler
### [ReplicaSet](/rn63_NYCS9qC0F2VgEyaiw?view)
+ 目的是维護一組在任何時候都處於運行的Pod
+ 創建新的Pod會使用腳本內的Pod Template
+ 如果要使用`rolling update`請使用Deployment
+ 主要被Deployment 用來協調Pod 建立、刪除和更新
### ReplicationController
+ 可縮寫為"rc"
+ 確保有特定數量的Pod 處於運行狀態
+ 建立的Pod在失敗、被刪除或被終止時會自動替換
+ 會監控跨多個Node的多個Pod
1. ReplicaSet, ReplicationController,都集中於Deployment管理,都被Deployment用作協調Pod建立、刪除和更新的機制。
2. 建議使用Deployment而不是直接使用ReplicaSet,除非需要自定義更新流程或不需要更新
### [Deployment](/ykmB_w6CQcaDJDqqgk13IQ?view)

+ 可縮寫為`deploy`
+ Deployment為Pod和ReplicaSet提供更新能力
+ Deployment管理多個ReplicaSet原因在於Deployment支援回滾機制
+ 部署新的Deployment設定時,Kubernetes會依據新設定重新生成一個ReplicaSet並保留舊設定
+ 未來有需要就能直接用舊的ReplicaSet回滾到先前狀態
+ 透過擴展Deployment增加服務承載量
+ 命名規格:[Deployment_name]-[ReplicaSet_String]-[Pod_String]
+ 能確保服務的Pod數量(replicas)能滿足設定的值以及支援Rolling Update
+ Deployment支援Rollback的機制
### [StatefulSet](/ZhmvgaP7Sv-Fl-AVf5fuHw?view)
+ 可縮寫為`sts`
+ 用來管理有狀態的服務或應用
+ 用來管理Deployment和擴展一組Pod
+ 每個Pod提供序號和唯一性保證
+ 適合部署需要唯一持久身份和穩定主機名稱的應用
### StatefulSet 應用場景
+ 穩定、唯一的網路識別碼
+ 穩定、持久的Storage
+ 有順序的Deploy, Scale
+ 有順序、自動`Rolling Update`
例如MySQL, MongoDB, Zookeeper
### StatefulSet 使用限制
+ Pod的Storage必須是PersistentVolume
+ 刪除或收縮不會刪除關聯的Volume
+ StatefulSet需要Headless Service負責Pod的網路識別
+ 刪除StatefulSet時,StatefulSet不保證Pod會终止,因此為了StatefulSet的Pod可以有順序和graceful終止,在刪除之前可以將StatefulSet的replicas設為0
### [DaemonSet](/PK6JPx3lRSGKCZv1EWXYWg?view)
+ 確保全部或特定Node運行一個Pod的副本
+ Node加入Cluster時,也會為它新增一個Pod
+ Node從Cluster移除時,這些Pod也會被回收
+ 刪除DaemonSet將會刪除它建立的所有Pod
### DaemonSet 典型用法
+ 在每個Node上運行Cluster Storage Daemon
+ 在每個Node上運行Logs Collection Daemon
+ 在每個Node上運行Node Monitoring Daemon
### 與Deployments差異
| | |
| ---------- | ---- |
| Deployment | 無狀態的服務使用 |
| DaemonSet | Pod 副本運行在全部或特定Node<br />並需要優先於其它Pod啟動時 |
Deployment:
建議為無狀態服務使用,比如前端服務。對這些服務而言,副本的數量進行擴展收容、Rolling Update,比精確控制Pod運行在某個Node上要重要。
### Job and CronJob
| | |
| -------- | ---- |
| Job |建立單一工作的Job,完成後即結束|
| CronJob |建立基於時間調度的Job<br />週期性的在指定的時間執行|
#### Job
+ Pod成功終止時,立即視Job為完成狀態
+ Job完成時不會再建立新的Pod
+ 已有的Pod不會被刪除
+ 被保留的Pod可以查看Log以更檢查錯誤
#### CronJob
+ CronJob就像crontab文件中的一行
+ 用Cron格式編寫,周期性的在指定的時間執行Job
+ 時間都是基於kube-controller-manager的時區
+ CronJob僅負責建立與它調度時間匹配的Job,Job又負責管理它代表的Pod
### Horizontal Pod Autoscaler
+ Pod水平自動擴充,簡稱HPA
+ apiVersion: autoscaling/v1
+ HPA不適用於無法擴展收容的控制器,如DaemonSet
+ 透過度量指標對目標Pod進行擴展收容
|||
| -------- | -------- |
|CPUUtilizationPercentage|Pod CPU使用率的平均值|
|應用自定的度量指標|如:服務在每秒內對應的請求數(TPS或QPS)|
1. 透過追蹤分析RC控制的所有目標Pod的負載變化情況,來確定是否需要針對性調整目標Pod的備份數
## 實作 Deployments
```yaml=
apiVersion: apps/v1
kind: Deployment
metadata:
name: hostnames
spec:
replicas: 3
selector:
matchLabels:
app: hostnames
template:
metadata:
labels:
app: hostnames
spec:
containers:
- name: hostnames
image: mirrorgooglecontainers/serve_hostname
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
ports:
- containerPort: 9376
protocol: TCP
```
1. apiVersion: 元件版本號
2. kind: 元件的屬性,常見有`Pod`, `Node`, `Deployment`, `Service`, `Namespace`, `StatefulSet`, `DaemonSet`等
3. metadata.name: 建立名為`hostnames-deployemnt`的pod
4. spec.replicas: Deployment創建三個Pod副本,預設是1
5. spec.selector: 指令這個Deployment的規則適用哪些Pod
6. spec.selector: 定義Deployment 如何找到要管理的Pods,matchLabels是{key, value}
7. `teamplate`包含以下字段
7-1. Pod標記為`app: hostnames`
7-2. `.template.spec`指令Pods運行一個容器
7-3. 創建一個容器並用`name`定段命名
Apply Deployment
kubectl apply -f ./endpoints-deployment.yaml
Check Deployment Status
kubectl get deploy
Check ReplicaSet
kubectl get rs
Check Pods Status
kubectl get pod
Update System with zero downtime rollout
kubectl edit deployment hostnames-deployment
kubectl rollout history deployment hostnames-deployment #查看所有版本
kubectl rollout undo deployment hostnames-deployment #恢復上一版
kubectl rollout undo deployment hostnames-deployment --to-revision=2 #指令版本
Gain more information of Deployment
kubectl descirbe deployment
Scale Deployment
kubectl scale deployment hostnames-deployment --replicas=5
kubectl autoscale deployment hostnames-deployment --min=3 --max=5 --cpu-percent=80
Pause, Resume Deployment
kubectl rollout pause deployment hostnames-deployment
kubectl set images deployment hostnames-deployment ${container name}=${image name:tag}
kubectl set resources deployment hostnames-deployment -c=hostnames --limits=cpu=200m,memory=512Mi
kubectl rollout resume deployment hostnames-deployment
### Kubernetes Dashboard
Install the Dashboard application into our cluster
kubectl apply -f ./k8s-dashboard.yaml
Check the resources it created based on the new namespace created
kubectl get all -n kubernetes-dashboard
Start a kubectl proxy
kubectl proxy
Enter the URL on your browser
http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/
Create a new ServiceAccount
kubectl apply -f k8s-dashboard-service-account.yaml
Create a ClusterRoleBinding for the ServiceAccount
kubectl apply -f k8s-dashboard-clusterrolebinding.yaml
Get the Token for the ServiceAccount
kubectl -n kubernetes-dashboard describe secret $(kubectl -n kubernetes-dashboard get secret | grep admin-user | awk '{print $1}')