一、Pod控制器
Pod 的分類
1.自主式 Pod
Pod 退出後不會被創建
2.控制器管理的 Pod
在控制器的生命週期裏,始終要維持 Pod 的副本數目
3.控制器類型
Replication Controller和ReplicaSet Deployment DaemonSet StatefulSet Job CronJob HPA全稱Horizontal Pod Autoscaler Replication Controller和ReplicaSet ReplicaSet (RS)是下一代的 Replication Controller(RC),官方推薦使用ReplicaSet。
ReplicaSet 和 Replication Controller 的唯一區別是選擇器的支持,ReplicaSet 支持新的基於集合的選擇器需求。
ReplicaSet 確保任何時間都有指定數量的 Pod 副本在運行。
雖然 ReplicaSets 可以獨立使用,但今天它主要被Deployments 用作協調 Pod 創建、刪除和更新的機制。
1>Deployment
Deployment 爲 Pod 和 ReplicaSet 提供了一個申明式的定義方法。
.典型的應用場景:
用來創建Pod和ReplicaSet 滾動更新和回滾 擴容和縮容 暫停與恢復
2>DaemonSet
DaemonSet 確保全部(或者某些)節點上運行一個 Pod 的副本。當有節點加入集羣時, 也會爲他們新增一個 Pod 。當有節點從集羣移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的所有 Pod。
DaemonSet 的典型用法:
在每個節點上運行集羣存儲 DaemonSet,例如 glusterd、ceph。 在每個節點上運行日誌收集 DaemonSet,例如 fluentd、logstash。 在每個節點上運行監控 DaemonSet,例如 Prometheus Node Exporter、zabbix agent等 一個簡單的用法是在所有的節點上都啓動一個 DaemonSet,將被作爲每種類型的 daemon 使用。
一個稍微複雜的用法是單獨對每種 daemon 類型使用多個 DaemonSet,但具有不同的標誌, 並且對不同硬件類型具有不同的內存、CPU 要求。
3>StatefulSet
StatefulSet 是用來管理有狀態應用的工作負載 API 對象。實例之間有不對等關係,以及實例對外部數據有依賴關係的應用,稱爲“有狀態應用”
StatefulSet 用來管理 Deployment 和擴展一組 Pod,並且能爲這些 Pod 提供序號和唯一性保證。
StatefulSets 對於需要滿足以下一個或多個需求的應用程序很有價值:
穩定的、唯一的網絡標識符。 穩定的、持久的存儲。 有序的、優雅的部署和縮放。 有序的、自動的滾動更新。 Job 執行批處理任務,僅執行一次任務,保證任務的一個或多個Pod成功結束。
4>CronJob
Cron Job 創建基於時間調度的 Jobs。
一個 CronJob 對象就像 crontab (cron table) 文件中的一行,它用 Cron 格式進行編寫,並週期性地在給定的調度時間執行 Job。
HPA 根據資源利用率自動調整service中Pod數量,實現Pod水平自動縮放。
二、Pod控制器使用示例
ReplicaSet舉例
1.編輯以下yaml文件:
[root@server1 ~]# vim rs.yaml
[root@server1 ~]# cat rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-example
spec:
replicas: 2 #啓動pod的副本數
selector: #定義選擇器爲標籤選擇器。
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx #定義容器的標籤
spec: #定義容器
containers:
- name: nginx
image: nginx
2.運行
以上使用的控制器的RS,RS控制器通過pod的標籤(matchLabels)來控制pod的數量,使用apply命令可以實現創建,更新pod,而create命令創建後若需要更新只能刪除之後再創建,因此建議使用apply:
[root@server1 ~]# kubectl apply -f rs.yaml
replicaset.apps/replicaset-example created
[root@server1 ~]# kubectl apply -f rs.yaml
replicaset.apps/replicaset-example unchanged
3.查看狀態:
查看狀態:
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
replicaset-example-p6sv6 1/1 Running 0 34s
replicaset-example-s5jps 1/1 Running 0 34s
[root@server1 ~]# kubectl get rs #獲取rs的信息
NAME DESIRED CURRENT READY AGE
replicaset-example 2 2 2 36s
[root@server1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
replicaset-example-p6sv6 1/1 Running 0 38s 10.244.1.14 server2 <none> <none>
replicaset-example-s5jps 1/1 Running 0 38s 10.244.2.21 server3 <none> <none>
可以看出一且正常,接下來進行pod的拉伸與壓縮:
4.拉伸副本數:
[root@server1 ~]# vim rs.yaml
[root@server1 ~]# cat rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-example
spec:
replicas: 4 #拉伸爲4個
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
[root@server1 ~]# kubectl apply -f rs.yaml
replicaset.apps/replicaset-example configured
5.查看pod數:
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
replicaset-example-p6sv6 1/1 Running 0 97s
replicaset-example-s5jps 1/1 Running 0 97s
replicaset-example-wzclz 1/1 Running 0 21s
replicaset-example-zk4mb 1/1 Running 0 21s
已經被拉伸成了4個。
6.縮減:
[root@server1 ~]# vim rs.yaml
[root@server1 ~]# cat rs.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: replicaset-example
spec:
replicas: 2 #縮減爲2個
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
[root@server1 ~]# kubectl apply -f rs.yaml
replicaset.apps/replicaset-example configured
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
replicaset-example-p6sv6 1/1 Running 0 2m6s
replicaset-example-s5jps 1/1 Running 0 2m6s
可以看出刪除的是剛剛創建的那兩個pod。
7.更改一個pod 的標籤:
[root@server1 ~]# kubectl label pod replicaset-example-s5jps app=myapp --overwrite #將標籤強制更改爲myapp
pod/replicaset-example-s5jps labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-example-p6sv6 1/1 Running 0 3m56s app=nginx
replicaset-example-s5jps 1/1 Running 0 3m56s app=myapp
replicaset-example-w98nk 1/1 Running 0 26s app=nginx
可以看出現在有3個pod,兩個標籤爲nginx一個爲myapp,RS控制器的工作原理就是維持標籤爲nginx的pod個數有2個,因此當我們更改一個pod的標籤後,RS又會給我們創建一個標籤爲nginx的pod,而當我們將標籤爲myapp的pod刪除後RS控制器不會有操作:
[root@server1 ~]# kubectl delete pod replicaset-example-s5jps
pod "replicaset-example-s5jps" deleted
[root@server1 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-example-p6sv6 1/1 Running 0 5m8s app=nginx
replicaset-example-w98nk 1/1 Running 0 98s app=nginx
8.再更改驗證:
[root@server1 ~]# kubectl label pod replicaset-example-p6sv6 app=myapp --overwrite #首先保證3個pod
pod/replicaset-example-p6sv6 labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-example-p6sv6 1/1 Running 0 6m4s app=myapp
replicaset-example-w98nk 1/1 Running 0 2m34s app=nginx
replicaset-example-x2lq9 1/1 Running 0 26s app=nginx
[root@server1 ~]# kubectl label pod replicaset-example-p6sv6 app=nginx --overwrite
pod/replicaset-example-p6sv6 labeled
[root@server1 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-example-p6sv6 1/1 Running 0 6m23s app=nginx
replicaset-example-w98nk 1/1 Running 0 2m53s app=nginx
replicaset-example-x2lq9 0/1 Terminating 0 45s app=nginx
[root@server1 ~]# kubectl get pod --show-labels
NAME READY STATUS RESTARTS AGE LABELS
replicaset-example-p6sv6 1/1 Running 0 6m25s app=nginx
replicaset-example-w98nk 1/1 Running 0 2m55s app=nginx
以上實驗可以看出,當集羣裏有3個標籤是nginx的pod的時候,RS控制器又會幫我們將最後創建的pod刪除。
實驗後刪除:
[root@server1 ~]# kubectl delete -f rs.yaml
replicaset.apps "replicaset-example" deleted
Deployment控制器示例
1.編輯yaml文件:
Deployment控制器示例 編輯yaml文件:
[root@server1 ~]# vim deployment.yaml
[root@server1 ~]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
2.創建pod:
[root@server1 ~]# kubectl apply -f deployment.yaml
deployment.apps/deployment-nginx created
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-nginx-56d786cd98-kx5pw 1/1 Running 0 23s
deployment-nginx-56d786cd98-qgcjl 1/1 Running 0 23s
[root@server1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deployment-nginx-56d786cd98 2 2 2 28s
[root@server1 ~]# kubectl get deployments.apps #查看deployments
NAME READY UP-TO-DATE AVAILABLE AGE
deployment-nginx 2/2 2 2 32s
以上運行結果可以看出deployments底層也是由RS實現的,接下來
3.進行拉伸:
[root@server1 ~]# vim deployment.yaml
[root@server1 ~]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
labels:
app: nginx
spec:
replicas: 4 #拉伸爲4個
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
[root@server1 ~]# kubectl apply -f deployment.yaml
deployment.apps/deployment-nginx configured
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-nginx-56d786cd98-942dh 1/1 Running 0 26s
deployment-nginx-56d786cd98-kx5pw 1/1 Running 0 108s
deployment-nginx-56d786cd98-qgcjl 1/1 Running 0 108s
deployment-nginx-56d786cd98-zb8s8 1/1 Running 0 26s
可以看出已經拉伸爲4個。接下來進行
4.滾動更新:
[root@server1 ~]# vim deployment.yaml
[root@server1 ~]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v2 #更新到v2
ports:
- containerPort: 80
[root@server1 ~]# kubectl apply -f deployment.yaml
deployment.apps/deployment-nginx configured
[root@server1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
deployment-nginx-868855d887-2zh45 1/1 Running 0 2m39s 10.244.2.26 server3 <none> <none>
deployment-nginx-868855d887-87m22 1/1 Running 0 2m34s 10.244.1.20 server2 <none> <none>
deployment-nginx-868855d887-hb6mv 1/1 Running 0 2m39s 10.244.1.19 server2 <none> <none>
deployment-nginx-868855d887-v8ndt 1/1 Running 0 2m33s 10.244.2.27 server3 <none> <none>
[root@server1 ~]# curl 10.244.2.26
Hello MyApp | Version: v2 | Pod Name
可以看出更新時控制器新建一個rs,然後再新建4個pod,原來的rs依然存在,爲了方便我們
5.進行回滾:
[root@server1 ~]# vim deployment.yaml
[root@server1 ~]# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: deployment-nginx
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: ikubernetes/myapp:v1
ports:
- containerPort: 80
[root@server1 ~]# kubectl apply -f deployment.yaml
deployment.apps/deployment-nginx configured
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-nginx-56d786cd98-78m7z 0/1 ContainerCreating 0 4s
deployment-nginx-56d786cd98-8hnns 1/1 Running 0 9s
deployment-nginx-56d786cd98-lcvzw 1/1 Running 0 9s
deployment-nginx-56d786cd98-xkjhq 0/1 ContainerCreating 0 3s
deployment-nginx-868855d887-2zh45 1/1 Running 0 3m22s
deployment-nginx-868855d887-hb6mv 1/1 Terminating 0 3m22s
deployment-nginx-868855d887-v8ndt 1/1 Terminating 0 3m16s
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-nginx-56d786cd98-78m7z 1/1 Running 0 26s
deployment-nginx-56d786cd98-8hnns 1/1 Running 0 31s
deployment-nginx-56d786cd98-lcvzw 1/1 Running 0 31s
deployment-nginx-56d786cd98-xkjhq 1/1 Running 0 25s
可以看出原來v1版本的rs被重新啓用,再原來的rs下面新建4個pod。當然我門也可以使用kubectl delete rs --all命令刪除不用的rs(注意:正在使用的rs不會刪除):
[root@server1 ~]# kubectl delete rs --all
replicaset.apps "deployment-nginx-56d786cd98" deleted
replicaset.apps "deployment-nginx-868855d887" deleted
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
deployment-nginx-56d786cd98-6r589 1/1 Running 0 21s
deployment-nginx-56d786cd98-hvz24 1/1 Running 0 21s
deployment-nginx-56d786cd98-k62lj 1/1 Running 0 21s
deployment-nginx-56d786cd98-ss97z 1/1 Running 0 21s
[root@server1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
deployment-nginx-56d786cd98 4 4 4 24s #正在使用的RS不會刪除
實驗後刪除:
[root@server1 ~]# kubectl delete -f deployment.yaml
deployment.apps "deployment-nginx" deleted
DaemonSet舉例
1.編輯yaml
DaemonSet控制器保證每個節點上都運行一個pod:
[root@server1 ~]# vim daemonset.yaml
[root@server1 ~]# cat daemonset.yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: daemonset-example
labels:
app: zabbix-agent
spec:
selector:
matchLabels:
name: zabbix-agent
template:
metadata:
labels:
name: zabbix-agent
spec:
containers:
- name: zabbix-agent
image: zabbix/zabbix-agent
2.創建pod:
[root@server1 ~]# kubectl apply -f daemonset.yaml
daemonset.apps/daemonset-example created
[root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
daemonset-example-ctbgh 1/1 Running 0 6m5s
daemonset-example-mdqzk 1/1 Running 0 6m5s
[root@server1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-example-ctbgh 1/1 Running 0 7m16s 10.244.2.32 server3 <none> <none>
daemonset-example-mdqzk 1/1 Running 0 7m16s 10.244.1.25 server2 <none> <none>
可以看出我們的每個節點(server3和server2)上都運行了一個pod
3.刪除一個pod:
[root@server1 ~]# kubectl delete pod daemonset-example-ctbgh
pod "daemonset-example-ctbgh" deleted
[root@server1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-example-998ck 0/1 ContainerCreating 0 8s <none> server3 <none> <none>
daemonset-example-mdqzk 1/1 Running 0 8m22s 10.244.1.25 server2 <none> <none>
[root@server1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
daemonset-example-998ck 1/1 Running 0 24s 10.244.2.33 server3 <none> <none>
daemonset-example-mdqzk 1/1 Running 0 8m38s 10.244.1.25 server2 <none> <none>
可以看出刪除後DaemonSet控制器又會幫我們創建pod,以保證每個節點運行一個pod。
實驗後刪除:
[root@server1 ~]# kubectl delete -f daemonset.yaml
daemonset.apps "daemonset-example" deleted
Job控制器舉例
1.編輯yaml
Job控制器只運行一次
[root@server1 ~]# vim job.yaml
[root@server1 ~]# cat job.yaml
apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl #利用perl計算圓周率
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4 #容器啓動失敗重啓4次之後不再重啓。
2.創建
kubectl apply -f job.yaml
由於Job只運行一次,因此運行完後狀態爲Completed,我們可以查看日誌獲取結果:
可以看出計算成功。
實驗後刪除:
[root@server1 ~]# kubectl delete -f job.yaml
job.batch "pi" deleted
CronJob控制器舉例
CronJob控制器用於定時執行任務:
[root@server1 ~]# vim cronjob.yaml
[root@server1 ~]# cat cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: cronjob-example
spec:
schedule: "* * * * "
jobTemplate:
spec:
template:
spec:
containers:
- name: cronjob
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from k8s cluster #輸出信息
restartPolicy: OnFailure
Crontab
其中schedule字段與crontab裏面的寫法相同," * * "表示每分鐘執行任務。
1.創建pod:
[root@server1 ~]# kubectl apply -f cronjob.yaml
cronjob.batch/cronjob-example created
root@server1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
cronjob-example-1587387120-ngt6n 0/1 ContainerCreating 0 16s
[root@server1 ~]# kubectl get pod #等待一分鐘
NAME READY STATUS RESTARTS AGE
cronjob-example-1587387120-ngt6n 0/1 Completed 0 60s
cronjob-example-1587387180-hbwzb 0/1 ContainerCreating 0 9s
可以看出每分鐘運行一個pod,查看日誌獲取輸出信息:
[root@server1 ~]# kubectl logs cronjob-example-1587387120-ngt6n
Mon Apr 20 12:52:30 UTC 2020
Hello from k8s cluster
[root@server1 ~]# kubectl logs cronjob-example-1587387180-hbwzb
Mon Apr 20 12:53:35 UTC 2020
Hello from k8s cluster
可以看出輸出也是每分鐘輸出一次,也可以使用以下命令查看cronjob的信息:
[root@server1 ~]# kubectl get cronjobs
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob-example * * * * * False 1 16s 3m10s
[root@server1 ~]# kubectl get job -w #查看job信息並且持續輸出
NAME COMPLETIONS DURATION AGE
cronjob-example-1587387120 1/1 20s 2m23s
cronjob-example-1587387180 1/1 35s 92s
cronjob-example-1587387240 1/1 20s 32s
實驗後刪除
[root@server1 ~]# kubectl delete -f cronjob.yaml
cronjob.batch "cronjob-example" deleted