Kubernetes Controller詳解



運行容器化應用是Kubernetes最重要的核心功能。為滿足不同的業務需要,Kubernetes提供了多種Controller,主要包括Deployment、DaemonSet、Job、CronJob等。
1、創建資源的兩種方式
創建資源主要有通過命令行配置參數和通過配置文件這兩種方式。
通過命令行主要是使用kubectl命令來進行創建,主要可能用到的是kubectl run和kubectl create,具體的用法我們可以在命令后面加上–-help參數來查看幫助文檔。
這種方式的好處就是簡單快捷,部署的速度比較快,但是遇到要求比較復雜多樣的資源部署,后面就要附帶一大串參數,容易出錯,所以這種方式一般來說比較適用於小規模的簡單資源部署或者是上線前的簡單測試
通過配置文件則主要是json格式或yaml格式的文件,好處是可以詳細配置各種參數,保留的配置文件還可以用到其他的集群上進行大規模的部署操作,缺點就是部署比較麻煩,並且需要一定的門檻(要求對json或yaml有一定的了解)
配置文件主要是通過kubectl apply -f和kubectl create -f來進行配置。
2、Deployment
2.1 cli部署
我們先使用命令行(cli)創建一個deployment,名字(NAME)是nginx-clideployment,使用的鏡像(image)版本為1.17,創建的副本(replicas)數量為3。
kubectl run nginx-clideployment --image=nginx:1.17 --replicas=3
我們查看一下部署是否成功:

這里的kubectl get rs中的rs其實就是ReplicaSet(RS)
我們還可以發現ReplicaSet的命名就是在我們指定的NAME后面加上了一串哈希數值。
- .
想要查看更詳細的pod情況,我們可以這樣:
kubectl get pod -o wide

這里我們可以發現三個pod被k8s自動的分配到了三個節點上而實現集群中的負載均衡(LB),而這里的IP是創建pod的時候進行隨機分配的,我們並不能預知。
如果想要查看某一個pod部署之后的情況,我們可以這樣:
kubectl describe pods nginx-clideployment-5696d55d9d-gdtrt
如果我們只是輸入nginx-clideployment的話就會把所有相關的nginx-clideployment都列出來。

這里的信息很多,我們可以看到namespace是使用的默認default(一般都是default,除非是數十人以上在同時使用這個集群,否則一般不建議新建namespace來區分pod,大多數情況下使用label即可區分各類pod。)
Controlled By:則說明了這個deployment是由ReplicaSet控制的。
Conditions:則表明了當前的pod狀況

Volumes稱之為卷,這個概念我們暫時還沒有接觸到,等到我們的宿主機需要與容器內的服務進行數據交互的時候再進行了解。
Events則相當於log,記錄了pod運行的所有情況,如果遇到了運行不正常的情況,我們也可以查看這里來了解詳情。

2.2 yaml配置文件部署
接下來我們嘗試使用yaml文件來進行部署,新建一個文件,命名為nginx-yamldeployment.yml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: nginx-yamldeployment
spec:
replicas: 5
template:
metadata:
labels:
app: web_server
spec:
containers:
- name: nginx
image: nginx:1.17.1
apiVersion是當前配置格式的版本。
kind是要創建的資源類型,這里是Deployment。
metadata是該資源的元數據,name是必需的元數據項。
spec部分是該Deployment的規格說明。
replicas 指明副本數量,默認為1。
template 定義Pod的模板,這是配置文件的重要部分。
metadata定義Pod的元數據,至少要定義一個label。label的key和value可以任意指定。
spec 描述Pod的規格,此部分定義Pod中每一個容器的屬性,name和image是必需的。
接下來我們使用kubectl apply指令進行部署。
kubectl apply -f nginx-yamldeployment.yml


我們可以看到這里是已經運行正常了,那么如果我們想要修改這個deployment的屬性,比如說副本數量從5改為6,那么我們可以直接編輯剛剛的nginx-yamldeployment.yml文件,然后再執行kubectl apply -f nginx-yamldeployment.yml,但是如果文件找不到了,我們可以使用另外的方法:
kubectl edit deployments.apps nginx-yamldeployment
這樣子我們就能直接編輯這個deployment的yaml配置文件,編輯的操作方式和vim相同,修改完成后會自動生效。

我們修改保存退出后,可以看到這里已經生效了。

對於使用命令行創建的deployment,我們可以使用命令行來進行修改,也可以直接kubectl edit來編輯對應的yaml配置文件。

3、DaemonSet
我們先來看一下官網對DaemonSet的解釋:
DaemonSet 確保全部(或者某些)節點上運行一個 Pod 的副本。當有節點加入集群時,也會為他們新增一個 Pod 。 當有節點從集群移除時,這些 Pod 也會被回收。刪除 DaemonSet 將會刪除它創建的所有 Pod。
使用 DaemonSet 的一些典型用法:
運行集群存儲 daemon,例如在每個節點上運行 glusterd、ceph。
在每個節點上運行日志收集 daemon,例如fluentd、logstash。
在每個節點上運行監控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。
一個簡單的用法是在所有的節點上都啟動一個 DaemonSet,將被作為每種類型的 daemon 使用。 一個稍微復雜的用法是單獨對每種 daemon 類型使用多個 DaemonSet,但具有不同的標志,和/或對不同硬件類型具有不同的內存、CPU要求。
實際上,k8s本身的一些系統組件服務就是以DaemonSet的形式運行在各個節點上的。

4、Job
4.1 部署job
Job創建一個或多個Pod並確保指定數量的Pod成功終止。當pod成功完成后,Job會跟蹤成功的完成情況。達到指定數量的成功完成時,Job完成。
刪除Job將清理它創建的Pod。
一個簡單的例子是創建一個Job對象,以便可靠地運行一個Pod並成功完成指定任務。如果第一個Pod失敗或被刪除(例如由於節點硬件故障或節點重啟),Job對象將啟動一個新的Pod。
我們還可以使用Job並行運行多個Pod。
直接照搬官網的解釋可能會有些難以理解,我們來運行一個例子就能很好的說明情況了。
我們先新建一個job的配置文件,命名為pijob.yml,這個任務是將pi計算到小數點后兩千位,然后再打印出來。我們運行一下看看。

apiVersion: batch/v1
kind: Job
metadata:
name: pi
spec:
template:
spec:
containers:
- name: pi
image: perl
command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"]
restartPolicy: Never
backoffLimit: 4

我們查看它的詳細情況
kubectl describe jobs/pi

這里可以看到,運行了37s后成功計算出結果。

查看pod也可以看到它的狀態是Completed,說明已經完成了。

查看創建的pod的名稱

pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath='{.items[*].metadata.name}')
echo $pods

查看pod的運行結果

kubectl logs $pods

4.2 job運行錯誤
我們現在來看一下運行失敗的情況,我們把command里面的路徑改錯,使得它無法正常運行。

注意這里的restartPolicy: Never意味着pod運行失敗了也不會重啟。但是這個時候job會檢測到運行失敗,然后再新建一個pod來執行這個任務。
backoffLimit: 4意味着最多只會新建4個pod,避免一直失敗一直新建從而耗盡系統資源。

我們查看event可以看到,確實是由於路徑修改錯誤而導致無法正常運行。

接下來我們把restartPolicy: 改為 OnFailure
這時候我們可以看到並沒有啟動多個pod,二是對發生錯誤的pod進行重啟操作。

4.3 job並行化
在多線程早已普及的今天,很多任務我們都可以使用並行化來進行加速運行,這里也不例外。
我們在配置文件中的spec中加入 completions: 和parallelism: 。

圖中表示需要運行12個,每次並行運行6個。

從圖中我們可以看到確實是每次運行6個(運行時間相同說明同時開始運行)。
等待一段時候之后,我們再次查看而已看到任務已經順利完成了。

5、CronJob
熟悉linux的同學一定不會對cron感到陌生,因為cron就是用來管理linux中的定時任務的工具,所以CronJob我們可以理解為定時版的Job,其定時任務的編寫格式也和Cron相似。關於Cron可以點擊這里查看小七之前的博客。
需要注意的是,CronJob的時間以啟動該CronJob任務的Master節點的時間為准。
Cronjob只負責創建與其計划相匹配的Job,而Job則負責管理它所代表的Pod。也就是說,CronJob只負責創建Job,具體的管理操作還是由Job來負責。
這里是CronJob的官方文檔。
我們新建一個hellocronjob.yml來查看一下它的工作情況

apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure
這個定時任務的操作就是每分鍾輸出一次時間和Hello from the Kubernetes cluster。

查看cronjob的運行狀態

kubectl get cronjobs.batch
kubectl get jobs.batch --watch

我們隨便查看其中的一個log可以看到輸出的結果:

更多交流,入群:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM