k8s的五种控制器
一、k8s的五種控制器
1.k8s的控制器類型
Kubernetes中內建了很多controller(控制器),這些相當于一個狀態機,用來控制Pod的具體狀態和行為
1、Deployment:適合無狀態的服務部署2、StatefullSet:適合有狀態的服務部署3、DaemonSet:一次部署,所有的node節點都會部署,例如一些典型的應用場景:運行集群存儲 daemon,例如在每個Node上運行 glusterd、ceph 在每個Node上運行日志收集 daemon,例如 fluentd、 logstash 在每個Node上運行監控 daemon,例如 Prometheus Node Exporter 4、Job:一次性的執行任務5、Cronjob:周期性的執行任務二、Deployment控制器
1. Deployment概述
Deployment對象,顧名思義,是用于部署應用的對象。它使Kubernetes中最常用的一個對象,它為ReplicaSet和Pod的創建提供了一種聲明式的定義方法,從而無需像前兩篇文章中那樣手動創建ReplicaSet和Pod對象(使用Deployment而不直接創建ReplicaSet是因為Deployment對象擁有許多ReplicaSet沒有的特性,例如滾動升級和回滾)。
通過Deployment對象,你可以輕松的做到以下事情:
- 創建ReplicaSet和Pod
- 滾動升級(不停止舊服務的狀態下升級)和回滾應用(將應用回滾到之前的版本)
- 平滑地擴容和縮容
- 暫停和繼續Deployment
2. Deployment的創建
以下列的deploy.yml文件為例,使用以下命令創建一個nginx的
Deployment:
--record參數可以記錄當前版本的Deployment都執行過哪些命令。
創建完成后立即執行get命令可以查看這個Deployment:
[root@master ~]# kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 2m14s [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-74d589986c-kxcvx 1/1 Running 0 2m11s nginx-deployment-74d589986c-s277p 1/1 Running 0 2m11s nginx-deployment-74d589986c-zlf8v 1/1 Running 0 2m11sNAME代表Deployment的名字,DESIRED代表這個Deployment期望的副本數量,CURRENT代表當前已經創建了的副本數量,UP-TO-DATE代表已經更新完成的副本數量,AVAILABLE代表對于當前用戶可用的副本數量,AGE代表當前Deployment已經運行的時長。
等待幾秒鐘,再次運行get命令,可以查看到變化:
[root@master ~]# kubectl get deployments NAME READY UP-TO-DATE AVAILABLE AGE nginx-deployment 3/3 3 3 3m4s通過kubectl get rs來查看系統中ReplicaSet對象,由此可以看出Deployment會自動創建一個ReplicaSet對象。
[root@master ~]# kubectl get rs NAME DESIRED CURRENT READY AGE nginx-deployment-74d589986c 3 3 3 4m29s通過kubectl get pods --show-labels命令來查看當前系統中的Pod對象,可以成功觀察到nginx-deployment創建的3個Pod。
[root@master ~]# kubectl get pods --show-labels NAME READY STATUS RESTARTS AGE LABELS nginx-deployment-74d589986c-kxcvx 1/1 Running 0 3m55s app=nginx,pod-template-hash=74d589986c nginx-deployment-74d589986c-s277p 1/1 Running 0 3m55s app=nginx,pod-template-hash=74d589986c nginx-deployment-74d589986c-zlf8v 1/1 Running 0 3m55s app=nginx,pod-template-hash=74d589986c3. Deployment的更新
假如我們現在想要讓 nginx pod 使用 nginx:1.9.1 的鏡像來代替原來的 nginx的鏡像,運行以下命令:
[root@master ~]# kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1 deployment.apps/nginx-deployment image updated或者我們可以使用 edit 命令來編輯 Deployment,將image從nginx改寫成 nginx:1.9.1。
kubectl edit deployment/nginx-deployment查看更新進度:
[root@master ~]# kubectl rollout status deployment/nginx-deployment Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination... deployment "nginx-deployment" successfully rolled outDeployment更新時會創建一個新的ReplicaSet,然后將新的ReplicaSet中的Pod慢慢擴容到指定的副本數,將舊的ReplicaSet慢慢縮容到0。因此,更新時總能夠確保舊的服務不會停止,這就是滾動更新。
4. Deployment的回滾
當我們像上文一樣更新了Deployment之后,我們發現nginx:1.9.1的鏡像不是很穩定,因此想要修改回nginx:1.7.9的版本,此時我們不需要手動更改Deployment文件,而是利用Deployment的回滾功能。
使用rollout history命令查看Deployment的版本(revision):
[root@master ~]# kubectl rollout history deployment/nginx-deployment deployment.apps/nginx-deployment REVISION CHANGE-CAUSE 1 kubectl create --filename=deploy.yml --record=true 2 kubectl create --filename=deploy.yml --record=true因為我們創建 Deployment 的時候使用了 —recored 參數可以記錄命令,我們可以很方便的查看每次 revison 的變化。
查看單個 revision 的詳細信息:
[root@master ~]# kubectl rollout history deployment/nginx-deployment --revision=2 deployment.apps/nginx-deployment with revision #2 Pod Template:Labels: app=nginxpod-template-hash=658d7f4b4bAnnotations: kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=trueContainers:nginx:Image: nginx:1.9.1Port: 80/TCPHost Port: 0/TCPEnvironment: <none>Mounts: <none>Volumes: <none>現在,可以使用rollout undo命令回滾到前一個revision:
[root@master ~]# kubectl rollout undo deployment/nginx-deployment deployment.apps/nginx-deployment rolled back[root@master ~]# kubectl describe deployment/nginx-deployment Name: nginx-deployment Namespace: default CreationTimestamp: Fri, 24 Dec 2021 22:24:10 +0800 Labels: <none> Annotations: deployment.kubernetes.io/revision: 3kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true Selector: app=nginx Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template:Labels: app=nginxContainers:nginx:Image: nginxPort: 80/TCPHost Port: 0/TCPEnvironment: <none>Mounts: <none>Volumes: <none>也可以使用–to-revision參數指定某個歷史版本:
[root@master ~]# kubectl rollout undo deployment/nginx-deployment --to-revision=2 deployment.apps/nginx-deployment rolled back[root@master ~]# kubectl describe deployment/nginx-deployment Name: nginx-deployment Namespace: default CreationTimestamp: Fri, 24 Dec 2021 22:24:10 +0800 Labels: <none> Annotations: deployment.kubernetes.io/revision: 4kubernetes.io/change-cause: kubectl create --filename=deploy.yml --record=true Selector: app=nginx Replicas: 3 desired | 3 updated | 4 total | 3 available | 1 unavailable StrategyType: RollingUpdate MinReadySeconds: 0 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template:Labels: app=nginxContainers:nginx:Image: nginx:1.9.1Port: 80/TCPHost Port: 0/TCPEnvironment: <none>Mounts: <none>Volumes: <none>你可以通過設置 .spec.revisonHistoryLimit 項來指定 deployment 最多保留多少 revison 歷史記錄。默認的會保留所有的 revision;如果將該項設置為 0,Deployment 就不允許回退了。
只有 Deployment 的 rollout 被觸發才會創建一個 revision!注意!當且僅當 Deployment 的 Pod template被更改,例如更新 template 中的 label 和容器鏡像時,才會觸發一個rollout,從而為Deployment創建出一個新的 revision。
rollout命令的更多用法:
- history(查看歷史版本)
- pause(暫停Deployment)
- resume(恢復暫停的Deployment)
- status(查看資源狀態)
- undo(回滾版本)
三、Replicaset控制器
1.Replicaset概述
ReplicaSet是kubernetes中的一種副本控制器,簡稱rs,主要作用是控制由其管理的pod,使pod副本的數量始終維持在預設的個數。它的主要作用就是保證一定數量的Pod能夠在集群中正常運行,它會持續監聽這些Pod的運行狀態,在Pod發生故障時重啟pod,pod數量減少時重新運行新的 Pod副本。官方推薦不要直接使用ReplicaSet,用Deployments取而代之,Deployments是比ReplicaSet更高級的概念,它會管理ReplicaSet并提供很多其它有用的特性,最重要的是Deployments支持聲明式更新,聲明式更新的好處是不會丟失歷史變更。所以Deployment控制器不直接管理Pod對象,而是由 Deployment 管理ReplicaSet,再由ReplicaSet負責管理Pod對象。
2.Replicaset工作原理
Replicaset核心作用在于用戶創建指定數量的pod副本,并確保pod副本一直處于滿足用戶期望的數量, 起到多退少補的作用,并且還具有自動擴容縮容等制。
Replicaset控制器主要由三個部分組成:
1、用戶期望的pod副本數:用來定義由這個控制器管控的pod副本有幾個
2、標簽選擇器:選定哪些pod是自己管理的,如果通過標簽選擇器選到的pod副本數量少于我們指定的數量,需要用到下面的組件
3、pod資源模板:如果集群中現存的pod數量不夠我們定義的副本中期望的數量怎么辦,需要新建pod,這就需要pod模板,新建的pod是基于模板來創建的。
3.Replicaset使用案例
#編寫一個ReplicaSet資源清單 [root@k8s-master1 ~]# cat replicaset.yml --- apiVersion: apps/v1 kind: ReplicaSet metadata:name: frontendlabels:app: nginxtier: frontend spec:replicas: 3selector:matchLabels:tier: frontendtemplate:metadata:labels:tier: frontendspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresent[root@master ~]# kubectl apply -f replicaset.yaml replicaset.apps/frontend created [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE frontend-7rrp6 1/1 Running 0 9s frontend-drmcf 1/1 Running 0 9s frontend-qnlz6 1/1 Running 0 9s [root@master ~]# kubectl get rs NAME DESIRED CURRENT READY AGE frontend 3 3 3 41s四、DaemonSet控制器
1.DaemonSet 簡介
DaemonSet:服務守護進程,它的主要作用是在Kubernetes集群的所有節點中運行我們部署的守護進程,相當于在集群節點上分別部署Pod副本,如果有新節點加入集群,Daemonset會自動的在該節點上運行我們需要部署的Pod副本,相反如果有節點退出集群,Daemonset也會移除掉部署在舊節點的Pod副本。
2. DaemonSet的主要特征:
- 這個 Pod 運行在 Kubernetes 集群里的每一個節點(Node)上;
- 每個節點上只會運行一個這樣的 Pod 實例;
- 如果新的節點加入 Kubernetes 集群后,該 Pod 會自動地在新節點上被創建出來;
- 而當舊節點被刪除后,它上面的 Pod 也相應地會被回收掉。
3.Daemon Pods的調度特性
默認情況下,Pod被分配到具體哪一臺Node上運行是由Scheduler(負責分配調度Pod到集群內的Node上,它通過監聽ApiServer,查詢還未分配Node的Pod,然后根據調度策略為這些Pod分配Node)決定的。但是,DaemonSet對象創建的Pod卻擁有一些特殊的特性:
- Node的 unschedulable屬性會被DaemonSet Controller忽略。
- 即使Scheduler還未啟動,DaemonSet Controller也能夠創建并運行Pod。
Daemon Pods支持taints and tolerations, 但是這些Pods在創建時就默認容忍下列effect為NoExecute的taints(未設置tolerationSeconds):
| node.kubernetes.io/not-ready | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. |
| node.kubernetes.io/unreachable | NoExecute | 1.13+ | DaemonSet pods will not be evicted when there are node problems such as a network partition. |
| node.kubernetes.io/disk-pressure | NoSchedule | 1.8+ | … |
| node.kubernetes.io/memory-pressure | NoSchedule | 1.8+ | … |
| node.kubernetes.io/unschedulable | NoSchedule | 1.12+ | DaemonSet pods tolerate unschedulable attributes by default scheduler. |
| node.kubernetes.io/network-unavailable | NoSchedule | 1.12+ | DaemonSet pods, who uses host network, tolerate network-unavailable attributes by default scheduler. |
4. DaemonSet常用場景:
- 網絡插件的 Agent 組件,如(Flannel,Calico)需要運行在每一個節點上,用來處理這個節點上的容器網絡;
- 存儲插件的 Agent 組件,如(Ceph,Glusterfs)需要運行在每一個節點上,用來在這個節點上掛載F遠程存儲目錄;
- 監控系統的數據收集組件,如(Prometheus Node Exporter,Cadvisor)需要運行在每一個節點上,負責這個節點上的監控信息搜集。
- 日志系統的數據收集組件,如(Fluent,Logstash)需要運行在每一個節點上,負責這個節點上的日志信息搜集。
5.創建一個DaemonSet對象
下面的描述文件創建了一個運行著nginx鏡像的DaemonSet對象:
[root@master kubenetres]# vi daemonset.yml --- apiVersion: apps/v1 kind: DaemonSet metadata:name: fluentd-elasticsearchnamespace: kube-systemlabels:app: fluentd-logging spec:selector:matchLabels:name: fluentd-elasticsearchtemplate:metadata:labels:name: fluentd-elasticsearchspec:tolerations:- key: node-role.kubernetes.io/mastereffect: NoSchedulecontainers:- name: fluentd-elasticsearchimage: quay.io/fluentd_elasticsearch/fluentd:v2.5.2resources:limits:memory: 200Mirequests:cpu: 100mmemory: 200MivolumeMounts:- name: varlogmountPath: /var/log- name: varlibdockercontainersmountPath: /var/lib/docker/containersreadOnly: trueterminationGracePeriodSeconds: 30volumes:- name: varloghostPath:path: /var/log- name: varlibdockercontainershostPath:path: /var/lib/docker/containers[root@master ~]# kubectl get pod -n kube-system NAME READY STATUS RESTARTS AGE coredns-6d8c4cb4d-6n2xc 1/1 Running 2 (53m ago) 3d1h coredns-6d8c4cb4d-hjznw 1/1 Running 2 (53m ago) 3d1h etcd-master.example.com 1/1 Running 8 (53m ago) 3d1h fluentd-elasticsearch-6sgnt 1/1 Running 0 44s fluentd-elasticsearch-chfhc 1/1 Running 0 42s kube-apiserver-master.example.com 1/1 Running 9 (53m ago) 3d1h kube-controller-manager-master.example.com 1/1 Running 8 (53m ago) 3d1h kube-flannel-ds-67kht 1/1 Running 3 (53m ago) 3d1h kube-flannel-ds-hr47p 1/1 Running 2 (53m ago) 3d1h kube-flannel-ds-k678m 1/1 Running 2 (53m ago) 3d1h kube-proxy-44zx6 1/1 Running 2 (53m ago) 3d1h kube-proxy-knkbm 1/1 Running 2 (53m ago) 3d1h kube-proxy-n875j 1/1 Running 3 (53m ago) 3d1h kube-scheduler-master.example.com 1/1 Running 8 (53m ago) 3d1h五、Job控制器
1.Job Controller
Job Controller負責根據Job Spec創建Pod,并持續監控Pod的狀態,直至其成功結束。如果失敗,則根據restartPolicy(只支持OnFailure和Never,不支持Always)決定是否創建新的Pod再次重試任務。
Job負責批量處理短暫的一次性任務 (short lived one-off tasks),即僅執行一次的任務,它保證批處理任務的一個或多個Pod成功結束。
Kubernetes支持以下幾種Job:
- 非并行Job:通常創建一個Pod直至其成功結束
- 固定結束次數的Job:設置.spec.completions,創建多個Pod,直到.spec.completions個Pod成功結束
- 帶有工作隊列的并行Job:設置.spec.Parallelism但不設置.spec.completions,當所有Pod結束并且至少一個成功時,Job就認為是成功
根據.spec.completions和.spec.Parallelism的設置,可以將Job劃分為以下幾種pattern:
| 一次性Job | 數據庫遷移 | 創建一個Pod直至其成功結束 | 1 | 1 |
| 固定結束次數的Job | 處理工作隊列的Pod | 依次創建一個Pod運行直至completions個成功結束 | 2+ | 1 |
| 固定結束次數的并行Job | 多個Pod同時處理工作隊列 | 依次創建多個Pod運行直至completions個成功結束 | 2+ | 2+ |
| 并行Job | 多個Pod同時處理工作隊列 | 創建一個或多個Pod直至有一個成功結束 | 1 | 2+ |
2.job的使用
[root@master ~]# vi job.yml --- apiVersion: batch/v1 kind: Job metadata:name: myjob spec:template:spec:containers:- name: myjobimage: busyboxcommand: ["echo", "hello k8s job"]restartPolicy: Never[root@master ~]# kubectl apply -f job.yml job.batch/myjob created [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE myjob-gq27p 0/1 Completed 0 37s#查看這個 pod的任務 [root@master ~]# kubectl get job NAME COMPLETIONS DURATION AGE myjob 1/1 19s 5m11s#查看這個 pod的日志 [root@master ~]# kubectl logs myjob-gq27p hello k8s job六、 CronJob控制器
CronJob 可以用來執行基于時間計劃的定時任務,類似于Linux/Unix系統中的 crontable (opens new window)。
CronJob 執行周期性的重復任務時非常有用,例如備份數據、發送郵件等。CronJob 也可以用來指定將來某個時間點執行單個任務,例如將某項任務定時到系統負載比較低的時候執行。
一個 CronJob 對象就像 crontab (cron table) 文件中的一行。 它用Cron格式進行編寫, 并周期性地在給定的調度時間執行 Job。
注意:
所有 CronJob 的 schedule: 時間都是基于kube-controller-manager. 的時區。
如果你的控制平面在 Pod 或是裸容器中運行了 kube-controller-manager, 那么為該容器所設置的時區將會決定 Cron Job 的控制器所使用的時區。
為 CronJob 資源創建清單時,請確保所提供的名稱是一個合法的DNS 子域名. 名稱不能超過 52 個字符。 這是因為 CronJob 控制器將自動在提供的 Job 名稱后附加 11 個字符,并且存在一個限制, 即 Job 名稱的最大長度不能超過 63 個字符。
CronJob 用于執行周期性的動作,例如備份、報告生成等。 這些任務中的每一個都應該配置為周期性重復的(例如:每天/每周/每月一次); 你可以定義任務開始執行的時間間隔。
下面的 CronJob 示例清單會在每分鐘打印出當前時間和問候消息:
[root@master kubenetres]# vi cronjob.yml --- apiVersion: batch/v1beta1 kind: CronJob metadata:name: hello spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboximagePullPolicy: IfNotPresentcommand:- /bin/sh- -c- date; echo Hello nihaorestartPolicy: OnFailure創建pod查看
[root@master ~]# kubectl apply -f cronjob.yml Warning: batch/v1beta1 CronJob is deprecated in v1.21+, unavailable in v1.25+; use batch/v1 CronJob cronjob.batch/hello created#等一分鐘查看 [root@master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE hello-27339330-kkfxv 0/1 Completed 0 2s#查看日志 [root@master ~]# kubectl logs hello-27339330-kkfxv Fri Dec 24 15:30:00 UTC 2021 Hello nihao總結
- 上一篇: springboot自动创建Oracle
- 下一篇: [DB] From Leng,Oracl