本文主要內容:node
一、Kubernetes如何管理Pod?api
二、Kubernetes Control Plane組件有哪幾種?做用效果是什麼?app
1、Kubernetes如何管理Pod學習
Kubernetes中的Pod根據建立方式的不一樣,能夠分爲兩種:一種是直接建立的Pod,好比本身寫了一個Pod的yaml文件,經過kubectl create命令建立的Pod;一種是經過控制器,也就是Control Plane建立的Pod。spa
對於第一種Pod,也就是本身建立的Pod,建立完成以後由它所在的Node節點上的Kubelet管理。第二種Pod由控制器Control Plane管理。rest
Kubelet管理Podcode
Kubelet管理Pod的手段很簡單,就是重啓大法。每一個Pod建立時,均可以給配置存活探針,以下所示,建立Pod以後Kubernetes會每隔一段時間調用一次這個存活探針,也就是請求,若是執行失敗或者沒有響應,Kubelet則重啓Pod對象
... spec: containers: - image:xxx livenessProbe: httpGet: / port: 8080
Kubernetes提供了三種探針類型,上面示例中的是httpGet(返回的狀態碼是2xx或3xx則會被認定成功),還有兩種是TCP套接字探針和Exec探針。經常使用的通常都是HttpGet類型。blog
注意,若是不設置存活探針,kubelet只會根據容器進程是否存在來判斷進程是否健康,也就是沒有了健康檢查應有的效果(由於好比OOM這樣的異常發生時,JVM進程仍然運行),因此存活探針基本是一個必須的配置項。進程
在存活探針的配置項livenessProbe的同一級,還能夠配置探針的其餘屬性,好比delay、timeout、period等,還有一個參數叫初始延遲initialDelaySeconds通常來講也須要配置上。若是不配置初始延遲參數,探針將在容器啓動時就探測容器,這很容易失敗,由於應用還沒完成啓動。配置這個參數就能有效避免這種狀況的發生。
到此爲止,都是在講Pod出異常以後的重啓處理,但若是Pod所在的Node節點出異常致使宕機呢?此時Node節點上的kubelet也就掛了,從而那些咱們本身建立的依賴於Kubelet管理的Pod也就完全GG了。
遇到這種狀況該怎麼辦呢?這時候Kubernetes Control Plane就能夠發揮做用了。
Control Plane管理Pod
Kubernetes的控制器,也就是Control Plane組件,有不少種,好比ReplicationController、ReplicationSet、DaemonSet、Job等。
在建立這些控制器的時候,會指定對應非副本數,控制器建立完成以後就會檢測實際運行的pod數是否跟副本數一致,若是實際運行的少了(Pod出異常掛掉了或者Pod所在的節點掛了),控制器會根據配置的模板建立新的Pod;若是實際運行的多了,則會刪掉多餘的Pod。總之控制器會控制實際運行的Pod數與配置的副本數目一致。
固然,若是這些控制器所屬Pod的探針存活檢測異常,仍是由Pod所在節點的kubelet來重啓容器。即kubelet負責重啓,控制器負責建立/刪除。
2、Kubernetes Control Plane的組件有哪些?做用各是什麼?
下面分別對五種Control Plane的做用進行說明,其實除此以外還有兩種最經常使用的Deployment和StatefulSet,這兩種會在後面着重學習。
一、ReplicationController
ReplicationController顧名思義,副本的控制器。它主要由三部分組成: 標籤選擇器(label selector)、副本個數(replica count)、pod模板(pod template)。ReplicationController的yaml配置示例以下:
apiVersion: v1 kind: ReplicationController metadata: name: kubia spec: replicas: 3 # 副本數 selector: # 標籤選擇器 app: kubia template: # pod模板 metadata: labels: app: kubia spec: containers: - name: kubia image: xxx/kubia port: - containerPort:8080
標籤選擇器用戶查詢並監控全部擁有這個標籤的Pod;而副本數則用戶控制跟標籤選擇器匹配上的Pod的數量;若是Pod數量少於副本數,則會按照Pod模板建立新的Pod。因此這裏的標籤選擇器必需要與pod模板中的標籤一致,固然也能夠不指定標籤選擇器,此時會默認按照pod模板中的標籤來選擇。
從上面就能夠知道很重要的一點:Kubernetes是經過標籤與標籤選擇器實現的控制器與Pod的歸屬關係。
具體操做的指令以下,不少操做跟操做其餘對象沒什麼差異:
kubectl create -f kubia-rc.yaml # 根據yaml文件建立ReplicationController kubectl get rc # 查看ReplicationController kubectl delete pod kubia-xxx # 刪掉一個pod後再用get pod會看到正在建立新pod
kubectl delete rc kubia # 刪除kubia這個rc,此時連它所對應的Pod也都會被刪掉
kubectl delete rc kubia --cascade=false # 刪除kubia這個rc,但它所對應的Pod會被保留下來 kubectl describe rc kubia # 查看ReplicationController的詳細信息
kubectl label pod kubia-xxx app=kulet --overwrite # 改變pod的標籤,此時rs會建立一個新Pod來達到3個的副本數
kubectl get pods -L app # 查看pod的標籤
kubectl edit rc kubia # 進入修更名爲kubia的rc的頁面,修改後會當即生效,若是改了pod模板,只會對今後之後新建立的pod有效,不會影響已有pod
kubectl scale rc kubia --replicas=4 # 將副本數置爲4,此時若是實際pod數少了則會新建
注意,若是是一個Node節點不可用致使的Pod失效,Kubernetes會等待一段時間(幾分鐘)來等待Node的恢復,若是幾分鐘後仍未恢復,纔會建立新Pod來代替以前失效的Pod。
二、ReplicationSet
ReplicationSet是ReplicationController的升級版,前者rs擁有rc全部的功能,並且還有更富表達力的標籤選擇器,因此後者如今徹底能夠棄之不用。
ReplicationSet的yaml示例:
apiVersion: apps/v1beta2 kind: ReplicationSet metadata: name: kubia spec: replicas: 3 # 副本數 selector: # 標籤選擇器 matchLabels: app: kubia template: # pod模板 metadata: labels: app: kubia spec: containers: - name: kubia image: xxx/kubia port: - containerPort:8080
對比ReplicationController能夠看到有兩處有區別:一是apiVersion再也不是v1了(此處的apps是api組,後面的v1beta2是實際的api版本),二是選擇器那裏中間又加了一級matchLabels。
上面全部對ReplicationController的指令均可以用於ReplicationSet,只需將rc替換爲rs便可。
下面着重看看ReplicationSet對於標籤選擇器的升級:
1)、matchLabels
具體用法已經在上面的yaml示例中體現了,它的做用跟ReplicationController中的標籤選擇器相同,即徹底匹配key和value(容許有其餘的標籤)。
2)matchExpressions
使用方式以下:
selector: matchExpressions: - key: app operator: In values: - kubia # 表示標籤的值必須是kubia
matchExpressions下面必須有key和operator標籤,而value標籤有仍是無取決於operator的值。operator有以下幾種:
In: 此時須要有values標籤,表示pod必須有與其中一個指定的values匹配的標籤
NotIn:此時須要有values標籤,表示pod必須的標籤與任何指定的values不匹配
Exists:不須要values標籤,表示pod必須包含指定key的標籤,不關注value
DoesNotExist:不須要values標籤,表示pod不得包含有指定key的標籤
須要注意的是,selector下面能夠指定多個標籤表達式,即matchLabels和matchExpressions能夠有一個也能夠有多個也能夠混合,此時這多個match的關係是與的關係,即都爲true的pod才知足要求。通常不建議設置多個。
三、DaemonSet
該控制器能夠達到一種效果,即在每一個Node節點上建立一個Pod。若是Node有增長或減小,相應的Pod也增長減小。DaemonSet的yaml配置以下所示:
apiVersion: apps/v1beta2 kind: DaemonSet metadata: name: kubia-monitor spec: selector: # 標籤選擇器 matchLabels: app: kubia-monitor template: # pod模板 metadata: labels: app: kubia-monitor spec: nodeSelector: # 節點選擇器 disk: ssd containers: - name: kubia-monitor image: xxx/kubia-monitor port: - containerPort:8080
能夠看到,DaemonSet不須要設置副本數,由於每一個Node節點只有一個Pod。在上面的配置中,還多了一個節點選擇器nodeSelector,它是用於控制只在知足節點選擇器的節點上建立Pod,即對節點作一個過濾。注意,DaemonSet對Pod的建立是繞過了調度器的,因此即便對節點設置了不可調度,只要知足DaemonSet的節點選擇器,則仍然能夠在上面建立一個Pod。
對DaemonSet的create、get、describe、delete等操做與其餘控制器相同,就不在此贅述了,只需將對應的描述改爲ds便可。
四、Job
上面介紹的三種控制器都是啓動後一直運行的,而Job是用於執行一次性任務的,執行完以後就會被自動刪掉。Job的yaml文件示例以下:
apiVersion: batch/v1 #Job屬於batch API組,版本爲v1 kind: Job metadata: name: kubia-job spec: template: # pod模板 metadata: labels: app: kubia-job spec: restartPolicy: OnFailure # 設置重啓策略 containers: - name: main image: xxx/kubia-job port: - containerPort:8080
着重看一下重啓策略 restartPolicy。重啓策略一共有三種:Always(老是重啓,即執行完成以後會再次啓動,一直這樣進行下去)、OnFailure(失敗重啓)、Never(不重啓,即便執行失敗)。通常來講只會用
後二者,不會用Always。
Job執行完以後,經過kubectl get pod是沒法查看到它的,須要用 kubectl get pod -a ,狀態是Completed。
Job還支持運行屢次和並行執行,配置方式以下:
apiVersion: batch/v1 kind: Job metadata: name: kubia-job spec: completions: 5 parallelism: 2 template: # pod模板 ...
completions配置的數目,表示要執行多少次。若是未配置parallelism,則默認並行度是1,即同一時間只有一個Pod在運行,運行完這個Pod再建立第二個,一直運行完5個爲止。
若如上所示,配置了parallelism=2,則同一時間會有兩個Pod在運行,其中一個執行完以後再建立一個,一直執行完5個爲止。
在Job運行時更改parallelism的指令:
kubectl scale job kubia-job --replicas=3
能夠看到,跟擴容指令相同。
爲應對異常狀況,Job還有兩個屬性配置:
spec.activeDeadlineSeconds: 設置超時時間,Job實例運行時間超過這個配置時間,會被標記爲失敗,pod被終止運行。
spec.backoffLimit:重試次數,未配置時默認爲6次。
五、CronJob
熟悉定時任務的,應該不難猜到,該類型的控制器用於精確控制Pod按期執行的。配置的yaml以下所示:
apiVersion: batch/v1beta1 kind: CronJob metadata: name: kubia-cronjob spec: schedule: "0,15,30,45 * * * *" startingDeadlineSeconds: 15 #表示若是離預約時間15s後還未啓動Job,則本次任務不會執行 jobTemplate: metadata: labels: app: kubia-cronjob spec: restartPolicy: OnFailure # 設置重啓策略 containers: - name: main image: xxx/kubia-cronjob port: - containerPort:8080
CronJob建立後,會在每一個指定的cron表達式時間點建立一個新的Job。但有點坑的地方在於,它可能一會兒建立兩個Job,也可能一個不建立。因此須要在業務側進行兼容,一方面是能夠冪等,另外一方面後面運行的任務需將前面未運行的任務未作的事情給作了。
本文到這裏就結束了,下一節將一塊兒學習Kubernetes中的服務。