html
Pod
中封裝着應用的容器(有的狀況下是好幾個容器),存儲、獨立的網絡IP
,管理容器如何運行的策略選項。Pod
表明着部署的一個單位:kubernetes
中應用的一個實例,可能由一個或者多個容器組合在一塊兒共享資源。node
Docker
是kubernetes
中最經常使用的容器運行時,可是Pod
也支持其餘容器運行時。nginx在
Kubernetes
集羣中Pod
有以下兩種方式:web
一個Pod中運行一個容器。「每一個
Pod
中一個容器」的模式是最多見的用法;在這種使用方式中,你能夠把Pod
想象成單個容器的封裝,Kubernetes
管理的是Pod
而不是直接管理容器。vim在一個Pod中同時運行多個容器。一個
Pod
也能夠同時封裝幾個須要緊密耦合互相協做的容器,它們之間共享資源。這些在同一個Pod
中的容器能夠互相協做成爲一個service
單位——一個容器共享文件,另外一個「sidecar」
容器來更新這些文件。Pod
將這些容器的存儲資源做爲一個實體來管理。api
Pod
中共享的環境包括Linux
的namespace
、cgroup
和其餘可能的隔絕環境,這一點跟Docker
容器一致。在Pod
的環境中,每一個容器可能還有更小的子隔離環境。服務器
Pod
中的容器共享IP
地址和端口號,它們之間能夠經過localhost
互相發現。它們之間能夠經過進程間通訊,例如SystemV
信號或者POSIX
共享內存。不一樣Pod
之間的容器具備不一樣的IP
地址,不能直接經過IPC
通訊。網絡
Pod
中的容器也有訪問共享volume
的權限,這些volume
會被定義成pod
的一部分並掛載到應用容器的文件系統中。tcp就像每一個應用容器,
pod
被認爲是臨時(非持久的)實體。在Pod
的生命週期中討論過,pod
被建立後,被分配一個惟一的ID(UID)
,調度到節點上,並一致維持指望的狀態直到被終結(根據重啓策略)或者被刪除。若是node
死掉了,分配到了這個node
上的pod
,在通過一個超時時間後會被從新調度到其餘node
節點上。一個給定的pod
(如UID
定義的)不會被「從新調度」到新的節點上,而是被一個一樣的pod
取代,若是指望的話甚至能夠是相同的名字,可是會有一個新的UID
。ide
注意在一個
Pod
中同時運行多個容器是一種比較高級的用法。只有當你的容器須要緊密配合協做的時候才考慮用這種模式。例如,你有一個容器做爲web
服務器運行,須要用到共享的volume
,有另外一個「sidecar」
容器來從遠端獲取資源更新這些文件,以下圖所示:
網絡:每一個
pod
都會被分配一個惟一的IP
地址。Pod
中的全部容器共享網絡空間,包括IP
地址和端口。Pod
內部的容器可使用localhost
互相通訊。Pod
中的容器與外界通訊時,必須分配共享網絡資源(例如使用宿主機的端口映射)。存儲:能夠爲一個
Pod
指定多個共享的Volume
。Pod
中的全部容器均可以訪問共享的volume
。Volume
也能夠用來持久化Pod
中的存儲資源,以防容器重啓後文件丟失。
注意:重啓
Pod
中的容器跟重啓Pod
不是一回事。Pod
只提供容器的運行環境並保持容器的運行狀態,重啓容器不會形成Pod
重啓。
Pod
不會自愈。若是Pod
運行的Node
故障,或者是調度器自己故障,這個Pod
就會被刪除。一樣的,若是Pod
所在Node
缺乏資源或者Pod
處於維護狀態,Pod
也會被驅逐。Kubernetes
使用更高級的稱爲Controller
的抽象層,來管理Pod
實例。雖然能夠直接使用Pod
,可是在Kubernetes
中一般是使用Controller
來管理Pod
的。
Controller
能夠建立和管理多個Pod
,提供副本管理、滾動升級和集羣級別的自愈能力。例如,若是一個Node
故障,Controller
就能自動將該節點上的Pod
調度到其餘健康的Node
上。
不管是手動建立仍是經過
Deployment
等控制器建立,Pod
對象老是應該處於其生命進程中如下幾個相位(phase
)之一。
掛起(
Pending
):API Server
建立了pod
資源對象已存入etcd
中,但它還沒有被調度完成,或者仍處於從倉庫下載鏡像的過程當中。運行中(
Running
):Pod
已經被調度至某節點,而且全部容器都已經被kubelet
建立完成。成功(
Succeeded
):Pod
中的全部容器都已經成功終止而且不會被重啓失敗(
Failed
):Pod
中的全部容器都已終止了,而且至少有一個容器是由於失敗終止。即容器以非0
狀態退出或者被系統禁止。未知(
Unknown
):Api Server
沒法正常獲取到Pod
對象的狀態信息,一般是因爲沒法與所在工做節點的kubelet
通訊所致。
API Server
嘗試着將Pod
對象的相關信息存入etcd
中,待寫入操做執行完成,API Server
即會返回確認信息至客戶端。
API Server
開始反映etcd
中的狀態變化。全部的
kubernetes
組件均使用「watch」
機制來跟蹤檢查API Server
上的相關的變更。
kube-scheduler
(調度器)經過其「watcher」
覺察到API Server
建立了新的Pod
對象但還沒有綁定至任何工做節點。
kube-scheduler
爲Pod
對象挑選一個工做節點並將結果信息更新至API Server
。調度結果信息由
API Server
更新至etcd
存儲系統,並且API Server
也開始反映此Pod
對象的調度結果。
Pod
被調度到的目標工做節點上的kubelet
嘗試在當前節點上調用Docker
啓動容器,並將容器的結果狀態返回送至API Server
。
API Server
將Pod
狀態信息存入etcd
系統中。在
etcd
確認寫入操做成功完成後,API Server
將確認信息發送至相關的kubelet
,事件將經過它被接受。
1)初始化容器必須運行完成直至結束,若某初始化容器運行失敗,那麼
kubernetes
須要重啓它直到成功完成。(注意:若是pod
的spec.restartPolicy
字段值爲「Never
」,那麼運行失敗的初始化容器不會被重啓。)2)每一個初始化容器都必須按定義的順序串行運行。
容器探測(
container probe
)是Pod
對象生命週期中的一項重要的平常任務,它是kubelet
對容器週期性執行的健康狀態診斷,診斷操做由容器的處理器(handler
)進行定義。Kubernetes
支持三種處理器用於Pod
探測:
ExecAction
:在容器內執行指定命令,並根據其返回的狀態碼進行診斷的操做稱爲Exec
探測,狀態碼爲0
表示成功,不然即爲不健康狀態。
TCPSocketAction
:經過與容器的某TCP
端口嘗試創建鏈接進行診斷,端口可以成功打開即爲正常,不然爲不健康狀態。
HTTPGetAction
:經過向容器IP
地址的某指定端口的指定path
發起HTTP GET
請求進行診斷,響應碼爲2xx
或3xx
時即爲成功,不然爲失敗。任何一種探測方式均可能存在三種結果:
「Success」(成功)
、「Failure」(失敗)
、「Unknown」(未知)
,只有success
表示成功經過檢測。
容器探測分爲兩種類型:
存活性探測(livenessProbe):用於斷定容器是否處於「運行」(
Running
)狀態;一旦此類檢測未經過,kubelet
將殺死容器並根據重啓策略(restartPolicy
)決定是否將其重啓;未定義存活檢測的容器的默認狀態爲「Success
」。就緒性探測(readinessProbe):用於判斷容器是否準備就緒並可對外提供服務;未經過檢測的容器意味着其還沒有準備就緒,端點控制器(如
Service
對象)會將其IP
從全部匹配到此Pod
對象的Service
對象的端點列表中移除;檢測經過以後,會再將其IP
添加至端點列表中。
若是但願容器在探測失敗時被殺死並從新啓動,那麼請指定一個存活探針,並指定
restartPolicy
爲Always
或OnFailure
。若是要僅在探測成功時纔開始向
Pod
發送流量,請指定就緒探針。在這種狀況下,就緒探針可能與存活探針相同,可是spec
中的就緒探針的存在乎味着Pod
將在沒有接收到任何流量的狀況下啓動,而且只有在探針探測成功纔開始接收流量。若是但願容器可以自行維護,能夠指定一個就緒探針,該探針檢查與存活探針不一樣的端點。
注意:若是隻想在
Pod
被刪除時可以排除請求,則不必定須要使用就緒探針;在刪除Pod
時,Pod
會自動將自身置於未完成狀態,不管就緒探針是否存在。當等待Pod
中的容器中止時,Pod
仍處於未完成狀態。
Always:但凡
Pod
對象終止就將其重啓,默認值OnFailure:僅在
Pod
對象出現錯誤時方纔將其重啓Never:從不重啓
[root@k8s-master ~]# vim manfests/liveness-exec.yaml apiVersion: v1 kind: Pod metadata: name: liveness-exec-pod namespace: default labels: test: liveness-exec 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: 1 periodSeconds: 3 [root@k8s-master ~]# kubectl create -f manfests/liveness-exec.yaml #建立pod pod/liveness-exec-pod created [root@k8s-master ~]# kubectl get pods #查看pod NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 0 6s #等待一段時間後再次查看其狀態 [root@k8s-master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-exec-pod 1/1 Running 2 2m46s
host <string>:請求的主機地址,默認爲Pod IP,也能夠在httpHeaders中使用「Host:」來定義。 httpHeaders <[]Object>:自定義的請求報文首部。 port <string>:請求的端口,必選字段。 path <string>:請求的HTTP資源路徑,即URL path。 scheme <string>:創建鏈接使用的協議,僅可爲HTTP或HTTPS,默認爲HTTP。
[root@k8s-master ~]# vim manfests/liveness-httpget.yaml apiVersion: v1 kind: Pod metadata: name: liveness-http namespace: default labels: test: liveness spec: containers: - name: liveness-http-demo image: nginx:1.12 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Healthz > /usr/share/nginx/html/healthz"] livenessProbe: httpGet: path: /healthz port: http scheme: HTTP [root@k8s-master ~]# kubectl create -f manfests/liveness-httpget.yaml #建立pod pod/liveness-http created [root@k8s-master ~]# kubectl get pods #查看pod NAME READY STATUS RESTARTS AGE liveness-http 1/1 Running 0 7s [root@k8s-master ~]# kubectl describe pods/liveness-http #查看liveness-http詳細信息 ...... Containers: liveness-http-demo: ...... Port: 80/TCP Host Port: 0/TCP State: Running Started: Mon, 09 Sep 2019 15:43:29 +0800 Ready: True Restart Count: 0 ......
[root@k8s-master ~]# kubectl exec pods/liveness-http -it -- /bin/sh #進入到上面建立的pod中 # rm -rf /usr/share/nginx/html/healthz #刪除healthz測試頁面 # [root@k8s-master ~]# kubectl get pods NAME READY STATUS RESTARTS AGE liveness-http 1/1 Running 1 10m [root@k8s-master ~]# kubectl describe pods/liveness-http ...... Containers: liveness-http-demo: ...... Port: 80/TCP Host Port: 0/TCP State: Running Started: Mon, 09 Sep 2019 15:53:04 +0800 Last State: Terminated Reason: Completed Exit Code: 0 Started: Mon, 09 Sep 2019 15:43:29 +0800 Finished: Mon, 09 Sep 2019 15:53:03 +0800 Ready: True Restart Count: 1 ......
host <string>:請求鏈接的目標IP地址,默認爲Pod IP port <string>:請求鏈接的目標端口,必選字段
[root@k8s-master ~]# vim manfests/liveness-tcp.yaml apiVersion: v1 kind: Pod metadata: name: liveness-tcp-pod namespace: default labels: test: liveness-tcp spec: containers: - name: liveness-tcp-demo image: nginx:1.12 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 livenessProbe: tcpSocket: port: http
[root@k8s-master ~]# kubectl explain pods.spec.containers.livenessProbe KIND: Pod VERSION: v1 RESOURCE: livenessProbe <Object> exec command 的方式探測,例如 ps 一個進程是否存在 failureThreshold 探測幾回失敗 纔算失敗, 默認是連續三次 initialDelaySeconds 初始化延遲探測,即容器啓動多久以後再開始探測,默認爲0秒 periodSeconds 每隔多久探測一次,默認是10秒 successThreshold 處於失敗狀態時,探測操做至少連續多少次的成功纔算經過檢測,默認爲1秒 timeoutSeconds 存活性探測的超時時長,默認爲1秒 httpGet http請求探測 tcpSocket 端口探測
與存活性探測機制相似,就緒性探測是用來判斷容器就緒與否的週期性(默認週期爲10秒鐘)操做,它用於探測容器是否已經初始化完成並可服務於客戶端請求,探測操做返回
」success「
狀態時,即爲傳遞容器已經」就緒「的信號。就緒性探測也支持
Exec
、HTTPGet
和TCPSocket
三種探測方式,且各自的定義機制也都相同。但與存活性探測觸發的操做不一樣的是,探測失敗時,就緒探測不會殺死或重啓容器以保證其健康性,而是通知其還沒有就緒,並觸發依賴於其就緒狀態的操做(例如,從Service
對象中移除此Pod
對象)以確保不會有客戶端請求接入此Pod
對象。
設置HTTP探針示例
#終端1: [root@k8s-master ~]# vim manfests/readiness-httpget.yaml #編輯readiness-httpget測試pod的yaml文件 apiVersion: v1 kind: Pod metadata: name: readiness-http namespace: default labels: test: readiness-http spec: containers: - name: readiness-http-demo image: nginx:1.12 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 readinessProbe: httpGet: path: /index.html port: http scheme: HTTP [root@k8s-master ~]# kubectl create -f manfests/readiness-httpget.yaml #建立pod pod/readiness-http created [root@k8s-master ~]# kubectl get pods 查看pod狀態 NAME READY STATUS RESTARTS AGE liveness-tcp-pod 1/1 Running 1 7d18h readiness-http 1/1 Running 0 7s #新打開一個終端2進入到容器裏面 [root@k8s-master ~]# kubectl exec pods/readiness-http -it -- /bin/sh #進入上面建立的pod # rm -f /usr/share/nginx/html/index.html #刪除nginx的主頁面文件 # ls /usr/share/nginx/html 50x.html # #回到終端1上面查看pod狀態 [root@k8s-master ~]# kubectl get pods #查看pod狀態 NAME READY STATUS RESTARTS AGE liveness-tcp-pod 1/1 Running 1 7d18h readiness-http 0/1 Running 0 2m44s