Pod狀態和生命週期管理
Pod狀態和生命週期管理
Pod概覽
理解Pod
Pod是Kubernetes中可以建立和部署的最小單位。Pod代表著叢集中執行的程序。
Pod中封裝著應用的容器,儲存、獨立的網路IP,管理容器如何執行的策略選項。Pod代表著部署的一個單位:Kubernetes中應用的一個例項,可能由一個或多個容器組合在一起共享資源。
在Kubernetes叢集中Pod有如下兩種使用方式:
- 一個Pod中執行一個容器:這種模式是最常見的用法,在這種使用方式中,可將Pod想象成單個容器的封裝,Kubernetes管理的是Pod而不是直接管理容器。
- 在一個Pod中同時執行多個容器:一個Pod中也可以同時封裝幾個需要緊密耦合、互相協作的容器,它們之間共享資源。這些在同一個Pod中的容器可以互相協作成為一個service單位——一個容器共享檔案,另一個來更新這些檔案。Pod將這些容器的儲存資源作為一個實體來管理。
Pod中如何管理多個容器
Pod中可以同時執行多個程序(作為容器執行)協同工作。同一個Pod中的容器會自動的分配到同一個node上。同一個Pod中的容器共享資源、網路環境和依賴,它們總是被同時排程。
注意:在一個Pod中同時執行多個容器時一種比較高階的用法。只有當你的容器需要緊密配合協作的時候才考慮這種模式。
Pod中可以共享兩種資源:網路和儲存
網路
每個Pod都會被分配一個唯一的IP地址。Pod中的所有容器共享網路空間,包括IP地址和埠。Pod內部的容器可以使用localhost互相通訊。Pod中的容器與外界通訊時,必須分配共享網路資源(例如使用宿主機的埠對映)
儲存
可以為一個Pod指定多個共享的Volume。Pod中的所有容器都可以訪問共享的volume。Volume也可以用來持久化Pod中的儲存資源,以防容器重啟後文件丟失。
使用Pod
當Pod被建立後,都會被Kubernetes排程到叢集的Node上。直到Pod的程序終止、被刪掉、因為缺少資源而被驅逐、或Node故障之前,這個Pod都會一直保持在那個Node上。
注意:重啟Pod這種的容器和重啟Pod是兩碼事。Pod只提供容器的執行環境並保持容器的執行狀態,重啟容器不會造成Pod重啟。
Pod不會自愈。如果Pod執行的Node故障,或者是排程器本身故障,這個Pod就會被刪除。同樣的,如果Pod所在Node缺少資源或Pod處於維護狀態,Pod也會被驅逐。Kubernetes使用更高階的Controller來管理Pod例項。雖然可以直接使用Pod(自主式),但是在Kubernetes中通常是使用Controller來管理Pod的。
自主式Pod
自主式pod,即pod自己管理自己。
測試:
apiVersion: v1
kind: Pod
metadata:
name: tomcat-pod
namespace: default
labels:
tomcat: tomcat-pod
spec:
containers:
- name: tomcat-pod-java
ports:
- containersPort: 8080
image: tomcat:latest
imagePullPolicy: IfNotPresent
#建立pod
[root@k8s-master pod]# kubectl apply -f pod.yaml
pod/tomcat-pod created
#檢視pod
[root@k8s-master pod]# kubectl get pods | grep tomcat
tomcat-pod 1/1 Running 0 2m24s
#效果驗證
[root@k8s-master pod]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
my-nginx-5b56ccd65f-dqpcn 1/1 Running 0 44m 10.244.169.133 k8s-node2 <none> <none>
my-nginx-5b56ccd65f-kzc5x 1/1 Running 0 48m 10.244.169.132 k8s-node2 <none> <none>
tomcat-pod 1/1 Running 0 54s 10.244.36.73 k8s-node1 <none> <none>
[root@k8s-master pod]# curl 10.244.36.73:8080
<!doctype html><html lang="en"><head><title>HTTP Status 404 – Not Found</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 404 – Not Found</h1><hr class="line" /><p><b>Type</b> Status Report</p><p><b>Description</b> The origin server did not find a current representation for the target resource or is not willing to disclose that one exists.</p><hr class="line" /><h3>Apache Tomcat/10.0.14</h3></body></html>
#刪除pod,看看效果
[root@k8s-master pod]# kubectl delete pods tomcat-pod
pod "tomcat-pod" deleted
[root@k8s-master pod]# kubectl get pods
NAME READY STATUS RESTARTS AGE
my-nginx-5b56ccd65f-dqpcn 1/1 Running 0 53m
my-nginx-5b56ccd65f-kzc5x 1/1 Running 0 57m
可以看到,當刪除pod之後,pod不會再建立一個新的pod,而是徹底從機器上刪除了,這種自主式pod適合測試環境或者非核心業務場景。
問題:tomcat為何報404?
tomcat官方映象是精簡的映象,需要將映象中webapps.dist目錄下的ROOT目錄複製到webapps目錄下
Pod解析
Pod是Kubernetes中可以建立的最小部署單元,也是Kubernetes REST API中的頂級資源型別。
什麼是Pod
Pod就像豌豆莢一樣,它由一個或多個容器組成,它們共享容器儲存、網路和容器執行配置項。Pod中的容器總是被同時排程,有共同的執行環境。可以將單個Pod想象成執行獨立應用的“邏輯主機”——其中執行著一個或多個緊密耦合的應用容器(在有容器之前,這些應用都是執行在幾個相同的物理機或虛擬機器上。)
Pod中的容器共享IP地址和埠號,它們之間可以通過localhost互相發現。它們之間可以通過程序間通訊,如SystemV訊號或者POSIX共享記憶體。不同Pod之間的容器具有不同的IP地址,不能直接通過IPC通訊。
Pod中的容器也有訪問共享volume的許可權,這些volume會被定義成pod的一部分並掛載到應用容器的檔案系統中。
Volume和Pod有相同的生命週期(當其UID存在的時候)。當Pod因為某種原因被刪除或者被新建立的相同的Pod取代,它相關的東西(如Volume)也會被銷燬和再建立一個新的volume。
Pod的動機
管理
Pod是一個服務的多個程序的聚合單位,pod提供這些模型能夠簡化應用部署管理,通過提供一個更高級別的抽象的方式。Pod作為一個獨立的部署單位,支援橫向擴充套件和複製。共生(協同排程)、命運共同體、協同複製、資源共享、依賴管理,Pod都會自動的為容器處理這些問題。
資源共享和通訊
Pod中的應用可以共享網路空間,因此可以通過localhost互相發現。pod中的應用必須協調端口占用,每個pod都有一個唯一的IP地址,和物理機、其他pod都處於一個扁平的網路空間中,它們之間可以直接連通。
Pod的使用
Pod也可以用於垂直應用棧(如LAMP),這樣使用的主要動機是為了支援共同排程和協調管理應用程式,例如:
- 內容管理系統、檔案和資料載入器、本地換群管理器等
- 日誌和檢查點備份、壓縮、旋轉、快照等
- 資料變更觀察者、日誌和監控介面卡、活動釋出者等
- 控制器、管理器、配置器、更新器等
通常單個pod中不會同時執行一個應用的多個例項。
為何不直接在一個容器中執行多個應用程式?
- 透明。讓Pod中的容器對基礎設施可見,以便基礎設施能夠為這些容器提供服務,例如程序管理和資源監控
- 解耦軟體依賴。每個容器都可以進行版本管理,獨立的編譯和釋出。
- 使用方便。使用者不必執行自己的程序管理器,還要擔心錯誤訊號傳播等
- 效率。因為由基礎架構提供更多的職責,所以容器可以變得更加輕量級。
為何不支援容器的親和性的協同排程?
此方法可以提供容器的協同定位,能夠根據容器的親和性進行排程,但是無法使用pod帶來的大部分好處,例如資源共享、IPC、保持狀態一致性和簡化管理等。
Pod的終止
因為Pod作為在叢集的節點上執行的程序,所以不再需要的時候能夠優雅地終止掉是十分必要的。使用者需要能夠發起一個刪除Pod的請求,並且知道它們何時會被終止,是否被正確的刪除。使用者想終止程式時傳送刪除pod的請求,在pod可以被強制刪除前會有一個寬限期,會發送一個TERM請求到每個容器的主程序。一旦超時,將向主程序傳送KILL訊號並從API server中刪除。如果kubelet或者container manager在等待程序終止的過程中重啟,在重啟後仍然會重試完整的寬限期。流程如下:
- 使用者傳送刪除pod的命令,預設寬限期是30秒
- 在Pod超過該寬限期後API server就會更新Pod的狀態為“dead”
- 在客戶端命令上顯示的Pod狀態為:terminating
- 和第三步同時進行,當kubelet發現pod被標記為“terminating”狀態時,開始停止pod程序:
- 如果在pod中定義了preStop hook,在停止pod前會被呼叫。如果在寬限期過後,preStop hook依然在執行,第二步會再增加2秒的寬限期;
- 向Pod中的程序傳送TERM資訊
- 和第三步同時進行,該Pod將從該service的端點列表中刪除,不再是replication controller的一部分。關閉得慢的pod將繼續處理load balancer轉發的流量
- 過了寬限期後,將向Pod中依然執行的程序傳送SIGKILL訊號而殺掉程序。
- Kubelet會在API server中完成Pod的刪除,通過將優雅週期設定為0(立馬刪除)。Pod在API中消失,並且在客戶端也不可見。
刪除寬限期預設是30秒。kubelet delete命令支援--grace-period=
可在yaml檔案中通過{{ .spec.spec.terminationGracePeriodSeconds }}來修改此值。
Init容器
這是一種專用的容器,在應用程式容器啟動之前執行,用來包含一些應用映象中不存在的實用工具或安裝指令碼
Init容器與普通容器的區別
Init容器支援應用容器的全部欄位和特性,包括資源限制、資料卷和安全設定。而Init不支援Readliness Probe,因為它們必須在Pod就緒之前執行完成。
如果為一個Pod指定了多個Init容器,那些容器會按順序一次執行一個。只有當前面的Init容器必須執行成功後,才可以執行下一個Init容器。當所有的Init容器執行完成後,Kubernetes才初始化Pod和執行應用容器。
如果Pod的Init容器失敗,Kubernetes會不斷地重啟該Pod,直到Init容器成功為止。當然,如果Pod對應的重啟策略(restartPolicy)為Never,它不會重啟。
Init容器能做什麼?
因為Init容器具有與應用容器分離的單獨映象,所以它們的啟動相關程式碼具有如下優勢:
- 它們可以包含應用程式映象中不存在的實用程式或自定義設定程式碼
- 應用程式映象構建者和部署者角色可以獨立工作,無需共同構建
- 它們使用Linux Namespace,所以對應用容器具有不同的檔案系統檢視。因此,它們可以具有訪問Serect的許可權,而應用程式不能夠訪問
- 它們在應用容器啟動之前執行完成,而應用程式容器是並行執行的,所以Init容器能夠提供一種簡單的阻塞或延遲應用容器的啟動分方法,直到滿足了一組先決條件。