Kubernetes學習筆記(三):部署託管的Pod -- 存活探針、ReplicationController、ReplicaSet、DaemonSet、Job、CronJob

存活探針

Kubernetes能夠經過存活探針(liveness probe)檢查容器是否存活。若是探測失敗,Kubernetes將按期執行探針並從新啓動容器。
官方文檔請見:https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
存活探針分爲三種:前端

  • exec:在容器內執行任意命令,並檢查命令的退出狀態碼,爲0則成功,不然失敗。
  • httpGet:執行http get請求,http code大於等於200而且小於400表示成功,不然失敗。
  • tcp:嘗試與指定端口創建socket鏈接,創建成功則探測成功,不然失敗。

exec探針

從官網複製個yaml,可是要將image從k8s.gcr.io/busybox更改成busybox。node

-> [root@kube0.vm] [~] cat exec-liveness.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

運行而後30秒後查看nginx

-> [root@kube0.vm] [~] k create -f exec-liveness.yaml
pod/liveness-exec created

-> [root@kube0.vm] [~] k describe po liveness-exec
.......
    Liveness:       exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3
.......
Events:
  Type     Reason     Age                            From               Message
  ----     ------     ----                           ----               -------
  Normal   Scheduled  <unknown>                      default-scheduler  Successfully assigned default/liveness-exec to kube1.vm
  Normal   Pulling    <invalid>                      kubelet, kube1.vm  Pulling image "busybox"
  Normal   Pulled     <invalid>                      kubelet, kube1.vm  Successfully pulled image "busybox"
  Normal   Created    <invalid>                      kubelet, kube1.vm  Created container liveness
  Normal   Started    <invalid>                      kubelet, kube1.vm  Started container liveness
  Warning  Unhealthy  <invalid> (x3 over <invalid>)  kubelet, kube1.vm  Liveness probe failed: cat: can't open '/tmp/healthy': No such file or directory
  Normal   Killing    <invalid>                      kubelet, kube1.vm  Container liveness failed liveness probe, will be restarted

前30秒,/tmp/healthy是存在的,探針返回成功。30秒後,由於/tmp/healthy不存在了,因此一直失敗,直到失敗3次後重啓。數據庫

livenessProbe下的字段

這時候kubectl explain po.spec.containers.livenessProbe就派上了用場。express

  • exec:exec探針配置
  • httpGet:httpGet探針配置
  • tcpSocket:tcpSocket探針配置
  • initialDelaySeconds:初始延遲時間,在此時間內不進行探測,給程序預留啓動時間。
  • periodSeconds:探測週期,默認10s
  • timeoutSeconds:超時時間,默認1s
  • failureThreshold:被認爲失活的最小連續失敗次數,默認3次
  • successThreshold:失敗後被認爲存活的最小連續成功次數,默認爲1次。

這些參數在上面的kubectl describe的結果中的Liveness字段有:json

exec [cat /tmp/healthy] delay=5s timeout=1s period=5s #success=1 #failure=3

注意事項

  • 必定要檢查程序的內部,而沒有外界因素影響。
    例如,當服務器沒法鏈接到數據庫時,前端服務的探針不該返回失敗。由於問題在數據庫,重啓前端服務也沒法解決問題。
  • 無須再探針中實現重試
  • 探針要輕量

ReplicationController

ReplicationController是一種Kubernetes資源,能夠確保他的pod始終處於運行狀態。api

ReplicationController描述文件分爲三大部分:服務器

  • label selector(標籤選擇器):用於肯定ReplicationController管理哪些pod
  • replica count(副本個數):指定運行pod的數量
  • pod template(pod模板):用於建立pod

ReplicationController的目的就是建立和管理若干個pod副本,它會持續監控正在運行的pod列表,保證標籤選擇器匹配的pod數量與副本個數一致。若是少於副本數量,就要根據pod模板建立新的副本;若是多餘副本數量,就要刪除多餘的pod。app

數量少的緣由多是:socket

  • 增長了副本個數
  • pod所在的工做節點出現故障
  • pod的標籤更改了,致使pod與ReplicationController的標籤選擇器再也不匹配了。此時,若是它不被任何ReplicationController的標籤選擇器匹配,它就稱爲一個孤兒了。

數量多的緣由多是:

  • 減小了副本個數
  • 新建的pod與該ReplicationController的標籤選擇器匹配
  • 已存在的pod標籤修改後與該ReplicationController的標籤選擇器匹配

nginx-rc.yaml

API服務器會檢查模板中的標籤是否與selector匹配,若是不匹配是沒法建立的。能夠不指定selector,它會根據模板中的labels自動配置。

apiVersion: v1
kind: ReplicationController
metadata:
  name: nginx-rc
spec:
  replicas: 3	# 副本數量
  selector:	# pod選擇器,決定RC的操做對象
    app: nginx
  template:	# pod模板
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

使用ReplicationController

建立ReplicationController

-> [root@kube0.vm] [~] k create -f nginx-rc.yaml
replicationcontroller/nginx-rc created

查看pod,確實新建了3個pod。

-> [root@kube0.vm] [~] k get po --show-labels
NAME             READY   STATUS              RESTARTS   AGE   LABELS
nginx-rc-2c47w   0/1     ContainerCreating   0          5s    app=nginx
nginx-rc-jrcl2   0/1     ContainerCreating   0          5s    app=nginx
nginx-rc-qgchh   0/1     ContainerCreating   0          5s    app=nginx

查看ReplicationController,rc是ReplicationController的簡寫。

-> [root@kube0.vm] [~] k get rc
NAME       DESIRED   CURRENT   READY   AGE
nginx-rc   3         3         3       5m58s

查看詳情

-> [root@kube0.vm] [~] k describe rc nginx-rc
Name:         nginx-rc
Namespace:    default
Selector:     app=nginx
Labels:       app=nginx
Annotations:  <none>
Replicas:     3 current / 3 desired				# 當前數量、指望數量
Pods Status:  3 Running / 0 Waiting / 0 Succeeded / 0 Failed	# 各類狀態下的數量
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age    From                    Message
  ----    ------            ----   ----                    -------
  Normal  SuccessfulCreate  7m26s  replication-controller  Created pod: nginx-rc-2c47w
  Normal  SuccessfulCreate  7m26s  replication-controller  Created pod: nginx-rc-jrcl2
  Normal  SuccessfulCreate  7m26s  replication-controller  Created pod: nginx-rc-qgchh

能夠搞一些破壞,好比更改、刪除pod的標籤,或者乾脆刪除pod。ReplicationController會由於當前數量與指望數量不符而建立新的副本。

控制器如何建立的pod

控制器經過建立一個新的副本代替被刪除的副本時,它並無對刪除自己作出反應,而是針對由此產生的狀態——副本數量不足作出反應。
雖然控制器會當即受到pod被刪除的通知,但這並非它建立新副本的緣由。該通知會觸發控制器檢查實際的副本數量並採起相應措施。

kubectl edit

kubectl edit rc nginx-rc能夠在編輯器中打開nginx-rc的yaml配置,修改在保存後會馬上作出改變。

-> [root@kube0.vm] [~] k edit rc nginx-rc
replicationcontroller/nginx-rc edited
經過KUBE_EDITOR環境變量能夠指定用什麼編輯器打開。

kubectl scale

可使用kubectl scale命令進行擴縮容。

-> [root@kube0.vm] [~] k scale rc nginx-rc --replicas=6
replicationcontroller/nginx-rc scaled

以上操做會修改spec.replicas字段,就像經過kubectl edit修改同樣。

刪除ReplicationController

使用 kubectl delete 刪除ReplicationController時,pod也會被刪除。但因爲pod是被ReplicationController建立的而不是它的組成部分,因此能夠經過指定--cascade=false而不刪除pod。

注意事項

  • pod永遠不會被從新安置到另外一個節點。
  • 雖然一個pod沒有綁定在ReplicationController上,但該pod在metadata.ownerReferences引用它。

ReplicaSet

ReplicationController最終將要被棄用,代替它的是ReplicaSet。它們的行爲徹底相同,可是ReplicaSet的選擇器更具備表達力。

nginx-rs.yaml

讓咱們來看一個ReplicaSet的描述文件:

apiVersion: apps/v1	# api版本與ReplicationController不一樣
kind: ReplicaSet
metadata:
  name: nginx-rs
spec:
  replicas: 3
  selector:		# ReplicaSet的pod選擇器有matchLabels和matchExpressions,與ReplicationController的是類似的,但更強大
    matchLabels:
      app: nginx
  template:		# 模板內容是一致的
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

主要區別在於pod選擇器。ReplicaSet的建立於ReplicationController同樣,縮寫是rs,就再也不贅敘了。

matchExpressions

上面描述文件的選擇器使用matchExpressions能夠改成:

selector:
    matchExpressions:
      - key: app
        operator: In
        values:
          - nginx

每一個表達式都必須包含key、operator(運算符),有可能包含values(取決於運算符),運算符有如下四種:

  • In:Label的值必須與values中的一個相等
  • NotIn:Label的值不能與values中的任何一個相等
  • Exists:Pod必須包含一個指定名稱的標籤,values無所謂
  • DoesNotExists:Pod不得包含指定名稱的標籤,values不能指定

DaemonSet

DaemonSet與ReplicaSet的不一樣在於,DaemonSet可讓pod在集羣的每一個節點上運行,有且只有一個。

若是節點下線,DaemonSet不會在其餘地方重建pod;若是集羣新加入了一個節點,DaemonSet會馬上部署一個新的pod。若是有人刪除了pod,DaemonSet會創建一個新的。

這些pod一般用於執行系統級別或基礎結構相關的工做,如日誌收集和資源監控。典型的例子就是Kubernetes本身的kube-proxy。

若是想讓DaemonSet只在特定節點運行pod,須要經過pod模板中的nodeSelector屬性指定。

DaemonSet中沒有指望副本數的概念,它不須要。由於它的工做是確保有一個匹配它選擇器的pod在節點上運行。

nginx-ds.yaml

可能這裏用繼續用nginx做爲例子不太恰當,但目前咱們關注的重點是DaemonSet,繼續吧。。。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-ds
spec:			# 去掉了replicas,由於不須要
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      nodeSelector:	# 添加了一個節點的標籤選擇器,選擇只部署地區在在北京的節點上
        region: "beijing"
      containers:
        - name: nginx
          image: nginx
          ports:
            - containerPort: 80

建立DaemonSet

先給kube1.vm打個標籤

-> [root@kube0.vm] [~] k label node kube1.vm region=beijing
node/kube1.vm labeled

-> [root@kube0.vm] [~] k get node -L region
NAME       STATUS   ROLES    AGE   VERSION   REGION
kube0.vm   Ready    master   40h   v1.17.3
kube1.vm   Ready    <none>   40h   v1.17.3   beijing
kube2.vm   Ready    <none>   40h   v1.17.3

提交描述文件

-> [root@kube0.vm] [~] k create -f nginx-ds.yaml
daemonset.apps/nginx-ds created

-> [root@kube0.vm] [~] k get ds,po -o wide
NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE   CONTAINERS   IMAGES   SELECTOR
daemonset.apps/nginx-ds   1         1         1       1            1           region=beijing   52s   nginx        nginx    app=nginx

NAME                 READY   STATUS    RESTARTS   AGE   IP            NODE       NOMINATED NODE   READINESS GATES
pod/nginx-ds-5z95c   1/1     Running   0          52s   10.244.1.24   kube1.vm   <none>           <none>

給kube2.vm也打個標籤

-> [root@kube0.vm] [~] k label node kube2.vm region=beijing
node/kube2.vm labeled

-> [root@kube0.vm] [~] k get ds,po -o wide
NAME                      DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR    AGE    CONTAINERS   IMAGES   SELECTOR
daemonset.apps/nginx-ds   2         2         1       2            1           region=beijing   113s   nginx        nginx    app=nginx

NAME                 READY   STATUS              RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
pod/nginx-ds-5z95c   1/1     Running             0          113s   10.244.1.24   kube1.vm   <none>           <none>
pod/nginx-ds-b46lb   0/1     ContainerCreating   0          3s     <none>        kube2.vm   <none>           <none>

Job

Job能夠運行一種pod,在該pod內的進程成功結束時,再也不重啓。一旦任務完成,pod就被認爲處於完成狀態。

好比可使用在將一些數據導出到其餘地方,這個工做可能會持續幾個小時。

咱們基於busybox鏡像,sleep一段時間用於模擬這個操做。

job.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: job
spec:
  template:			# 沒有指定selector,會根據pod標籤中自動建立
    metadata:
      labels:
        app: job
    spec:
      restartPolicy: OnFailure	# 執行遇到異常則重啓,默認爲Always。
      containers:
        - name: sleepbusybox
          image: busybox
          command: ["/bin/sh","-c","sleep 60;echo this is busybox"]

restartPolicy表示pod的重啓策略,默認Always,其餘兩項爲OnFailure和Never。

運行查看

建立job

-> [root@kube0.vm] [~] k create -f job.yaml
job.batch/job created

60秒內查看:

-> [root@kube0.vm] [~] k get job,pod
NAME            COMPLETIONS   DURATION   AGE
job.batch/job   0/1           14s        14s

NAME            READY   STATUS    RESTARTS   AGE
pod/job-4sfv4   1/1     Running   0          14s

60秒後查看:

-> [root@kube0.vm] [~] k get job,pod
NAME            COMPLETIONS   DURATION   AGE
job.batch/job   1/1           68s        71s

NAME            READY   STATUS      RESTARTS   AGE
pod/job-4sfv4   0/1     Completed   0          71s

使用jsonpath獲取 pod name 查看log

-> [root@kube0.vm] [~] k logs $(k get po --selector=app=job --output=jsonpath={.items..metadata.name})
this is busybox

completions與parallelism

job描述文件下的spec有兩個字段:

  • completions:job要確保完成多少個pod,默認爲1。
  • parallelism:最多並行運行多少個pod,默認爲1。

job-batch.yaml

apiVersion: batch/v1
kind: Job
metadata:
  name: job-batch
spec:
  completions: 5
  parallelism: 2
  template:
    # 與job.yaml相同

activeDeadlineSeconds

job.spec.activeDeadlineSeconds屬性來限制Job在集羣中的存活時間,超過此值,全部的pod都被終止。Job的status變爲 type: Failed,reason: DeadlineExceeded

CronJob

與Linux的crontab相似,使pod能夠在特定時間運行,或者週期運行。

cronjob.yaml

這個描述文件是個套娃。。

CronJob包含job的模板,也就是jobTemplate;job裏還包含pod的模板,也就是template。

schedule字段中的值是"分 小時 每個月第幾天 月份 星期幾",詳情請參考Linux crontab。

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cron-job
spec:
  schedule: "*/3 * * * * "	# 每三分鐘運行一次
  jobTemplate:			# job的模板
    spec:
      template:			# pod的模板
        metadata:
          labels:
            app: job-in-cron
        spec:
          restartPolicy: OnFailure
          containers:
            - name: sleepbusybox
              image: busybox
              command: ["/bin/sh","-c","sleep 60;echo this is busybox"]

運行

建立cron-job

-> [root@kube0.vm] [~] k create -f cronjob.yaml
cronjob.batch/cron-job created

等了幾分鐘

-> [root@kube0.vm] [~] k get all
NAME                            READY   STATUS      RESTARTS   AGE
pod/cron-job-1590053040-pqhhh   0/1     Completed   0          97s

NAME                            COMPLETIONS   DURATION   AGE
job.batch/cron-job-1590053040   1/1           68s        97s

NAME                     SCHEDULE       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/cron-job   */3 * * * *    False     0        105s            4m39s

又等了幾分鐘

-> [root@kube0.vm] [~] k get all
NAME                            READY   STATUS              RESTARTS   AGE
pod/cron-job-1590053040-pqhhh   0/1     Completed           0          3m4s
pod/cron-job-1590053220-whflp   0/1     ContainerCreating   0          3s

NAME                            COMPLETIONS   DURATION   AGE
job.batch/cron-job-1590053040   1/1           68s        3m4s
job.batch/cron-job-1590053220   0/1           3s         3s

NAME                     SCHEDULE       SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/cron-job   */3 * * * *    False     1        12s             6m6s

能夠看到就當前的描述文件而言,cron-job每次建立一個job,job建立一個pod的運行。

startingDeadlineSeconds

cronjob.spec.startingDeadlineSeconds規定pod必須預約時間以後的startingDeadlineSeconds秒內運行,超過此時間則不運行,並將其顯示未Failed。

小結

  • 使用存活探針檢查容器是否存活。
  • ReplicationController建立並管理Pod,但並非綁定關係。它始終保持指望數量的副本正在運行。
  • ReplicationController將被棄用,ReplicaSet擁有更強的標籤選擇器。
  • DaemonSet會在每一個節點上保持運行有且只有一個Pod,能夠經過nodeSelector讓其只在特定節點運行。
  • Job建立Pod運行完成後,Pod爲爲Completed狀態。completions與parallelism指定須要完成的數量與並行度。
  • restartPolicy:默認Always,還有OnFailure、Never。
  • CronJob建立Job,Job建立Pod。
  • 命令:edit、scale
相關文章
相關標籤/搜索