k8s-pod的生命週期

1.pod資源-spec.containershtml

- name:鏡像運行起來以後叫容器,該字段爲容器名node

image:鏡像名字nginx

imagePullPolicy:表示從哪拉取鏡像,docker

Always:無論本地有沒有鏡像,都要從倉庫中下載鏡像,也就是說,即便本地有鏡像了,也不使用本地鏡像,而是從倉庫下載;vim

Never:歷來不從倉庫下載鏡像,也就是說本地有鏡像就用,沒有就算了;api

IfNotPresent:若是本地存在就直接使用,不存在才從倉庫下載,默認的策略是:當鏡像標籤版本是latest,則策略是Always;其他都是IfNotPresent.bash

指定策略爲ifNotPresent,即便image指定的版本是latest,每次啓動容器,也不會從倉庫從新下載鏡像.app

ports:指定暴露容器端口號,能夠指定多個端口,以下:frontend

spec:
  containers: 
  - name: myapp
    image: ikubernetes/myapp:v1
    ports:
    - name: http
      containerPort: 80
    - name: https
      containerPort: 443

在yaml中,docker field name和k8s field name的對應關係:tcp

docker field    k8s field

ENTRYPOINT     command

CMD         args

args:至關於dockerfile裏面的cmd
command:至關於docker裏面的entrypoint
執行命令的優先級:
若是沒有提供command和args,則用docker中的默認啓動命令;
若是提供了command,則鏡像中的CMD和ENTRYPOINT都不生效;
若是沒有提供command,提供了args,則CMD沒用了,將args當成參數傳給ENTRYPOINT;
若是提供了command和args,則鏡像中的CMD和ENTRYPOINT都不生效;

2.標籤

  一個標籤能夠對應多個資源,一個資源也能夠有多個標籤,它們是多對多的關係;一個資源擁有多個標籤,能夠實現不一樣維度的管理;標籤是key=value格式的,key最大63個字符,只能是字母、數字、_、-、.五種類型的組合,只能以字母或數字開頭結尾.

kubectl get pods --show-labels
# 用-l過濾標籤中有app的pod
kubectl get pods -l app --show-labels
#  用-L顯示pod中的標籤哪些有app,哪些有run
kubectl get pods -L app,run
# 多加一個標籤
kubectl label pods pod-demo release=haha
# 修改標籤
kubectl label pods pod-demo release=stable --overwrite

3.標籤選擇器

等值關係:=、==、!=
kubectl get pods -l release=stable,app=myapp --show-labels
集合關係:KEY in (VALUE1,VALUE2….)、KEY notin (VALUE1,VALUE2….)、KEY、!KEY
kubectl get pods -l "release notin (stable,haha)"

許多資源支持內嵌字段定義其使用的標籤選擇器:
matchLabels:直接給定鍵值;
matchExpressions:基於給定的表達式來定義使用標籤選擇器,
{key:"KEY",operator:"OPERATOR",values:[VAL1,VAL2,...]}

常見操做符(operator):In、NotIn:values字段的值必須爲非空列表;
Exists、NotExists:values字段的值必須爲空列表.

# nodes對象也有標籤
kubectl get nodes --show-labels
# 給node1節點打個disktype=ssd的標籤
kubectl label nodes k8s-node1 disktype=ssd
nodeSelector:節點選擇器,能夠指定pod運行在哪一個節點上 
nodeName:能夠直接指定運行節點
在maniteste/pod-demo.yaml文件spec字段中添加這兩行,便可改變pod的運行節點
spec:
  ...
  nodeSelector:
    disktype: ssd

4.annotations:資源註釋

與label不一樣的地方在於,它不能用於挑選資源對象,僅用於爲對象提供"元數據"
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    mowang.com/create_by: "cluster admin"

5.Pod生命週期

  在一個pod中,能夠運行多個容器,但一般在一個pod裏面運行一個容器,容器在建立以前,有多個初始化容器(init container)用來進行初始化環境,init container執行完,它就退出了,接下來是主容器(main container)開始啓動,主容器啓動時也要初始化主容器裏面的環境,在主容器剛啓動時,用戶能夠手動嵌入一個操做叫post start;在主容器結束前,也能夠作一個收尾操做pre stop,用來在主容器結束前作一個清理.

Pod生命週期中的重要行爲:初始化容器、容器探測

liveness probe--存活性探測:用於斷定主容器是否處於存活狀態;

readiness probe--就緒性探測:用於斷定容器中的主進程是否準備就緒以及可否對外提供服務.

在post start後,先作存活性探測,再作就緒性探測,Pod的狀態:Pending(掛起,沒有匹配到可運行節點),Running,Failed,Success,Unknown.

建立pod的大體流程:

  apiserver會將建立請求的目標狀態保存到etcd,接着請求scheduler進行調度,將調度結果保存到etcd中,目標節點上的kubelet經過apiserver拿到用戶提交的建立清單,根據清單在當前節點上建立並運行這個Pod,並將結果返回給apiserver,再把結果存到etcd中.

健康檢查分三個層次:1.直接執行命令;2.向tcp鏈接請求;3.向http發get請求.

6.livenessProbe--存活狀態探測

# 探針類型
kubectl explain pod.spec.containers.livenessProbe
exec	<Object>
httpGet	<Object>
tcpSocket	<Object>
failureThreshold:表示探測失敗次數,默認是3,探測3次失敗,才認爲是真失敗了;
periodSeconds:週期間隔時長,默認10s探測一次;
timeoutSeconds:超時時間,表示發出探測,對方始終沒有響應,須要等多久,默認等1s;
initialDelaySeconds:默認是容器一啓動就開始探測,可是此時容器可能還沒啓動完,此時探測確定是失敗的,
因此initialDelaySeconds表示容器啓動多長時間後纔開始探測. 

ExecAction舉例:
vim liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 3600"]
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/healthy"]
      initialDelaySeconds: 2
      periodSeconds: 3
initialDelaySeconds:延遲幾秒探測
periodSeconds:探測週期,多長時間探測一次
kubectl create -f liveness-exec.yaml 
能夠看到restart次數會隨着時間增加

liveness-HTTPGetAction舉例
vim liveness-httpGet.yaml
apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    livenessProbe:
      httpGet:
         port: http
         path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3

kubectl create -f liveness-httpGet.yaml
kubectl exec -it liveness-httpget-pod  -- /bin/sh
rm -rf  /usr/share/nginx/html/index.html

 當刪除pod裏面的index.html以後,liveness監測到文件被刪除了,容器就會重啓,容器會從新初始化,裏面就會又生成index.html文件,因此只重啓一次,restarts次數爲1.

7.readlinessProbe--準備就緒型探針

readiness-HTTPGetAction舉例

vim readiness-httget.yaml
apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    readinessProbe:
      httpGet:
         port: http
         path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3

進入容器刪除index.html,ready變成0/1,可是status是runing的,說明nginx進程正常,但index.html丟失,則斷定nginx沒有就緒.

poststart示例

postStart:若是執行操做失敗了,容器將被終止而且重啓,而重啓與否是由重啓策略決定;

preStop:容器在終止前要當即執行的命令,等這些命令執行完了,容器才能終止.

vim poststart-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: poststart-pod
  namespace: default
spec:
  containers:
  - name: busybox-httpd
    image: busybox:latest
    imagePullPolicy: IfNotPresent
    lifecycle:
       postStart:
         exec:
           command: ["/bin/sh","-c","echo Home_Page >> /tmp/index.html"]
    #command: ['/bin/sh','-c','sleep 3600']
    command: ["/bin/httpd"]
    args: ["-f","-h /tmp"]  # -f是前臺,-h是家目錄

容器啓動後默認執行的命令,但容器啓動不能依賴於postStart執行的結果
kubectl create -f  poststart-pod.yaml 

restartPolicy--容器的重啓策略

一旦pod中的容器掛了,重啓容器,有以下策略:

Always:表示容器掛了老是重啓,這是默認策略,很耗費資源,因此Always是這麼作的:

第一次掛了當即重啓,若是再掛了就延時10s重啓,第三次掛了就等20s重啓...以此類推

OnFailures:狀態是Failure時才重啓,正常退出則不重啓;

Never:表示容器掛了不予重啓;

容器的終止策略

k8s會給容器30s的時間進行終止,若是30s後還沒終止,就會強制終止.
kill -l
kill -15 pid  SIGTERM
系統會發送一個SIGTERM的信號給對應的程序.當程序接收到該signal後,將會發生如下的事情:
a.程序馬上中止;
b.當程序釋放相應資源後再中止;
c.程序可能仍然繼續運行.
大部分程序接收到SIGTERM信號後,會先釋放本身的資源,而後在中止.可是也有程序能夠在接受到信號量後,
作一些其餘的事情,而且這些事情是能夠配置的.
若是程序正在等待IO,可能就不會立馬作出相應,也就是說:SIGTERM多半是會被阻塞的、忽略的.
kill -9 pid 強行終止 SIGKILL

 

參考博客:http://blog.itpub.net/28916011/viewspace-2213957/

相關文章
相關標籤/搜索