2.3 Pod
Pod是Kubernetes中創建應用的最小、最簡單的基本執行單元。Pod封裝了應用程序的容器(一個或多個)、存儲資源、網絡以及其他相關選項。這表明:
● Kubernetes直接管理Pod,而不是容器。
● Pod可以封裝多個協作的容器,類似于Docker Stack。
● 每個Pod僅運行某個應用程序的單個實例,如果要水平擴展,不建議使用Pod部署。
2.3.1 創建Pod
盡管在Kubernetes中可以通過命令來創建對象,但是如果創建對象的參數比較多,本書建議通過聲明文件來創建。下面的聲明文件用來創建一個鏡像為busybox的Pod。

2.3.2 Pod內部多個容器
Pod支持多個協作容器組成一個有凝聚力的服務單元。Pod中的容器自動放置在同一個節點上,共同調度,共享資源和依賴關系,彼此通信,并協調何時可以終止,以及如何終止。Pod具有這種能力,不代表我們可以隨意使用這種模式,畢竟在云原生應用中,需要盡量確保每個部件可以自動擴展,并減少彼此的依賴性。而聚合多個容器的Pod則增加了依賴性,所以只能在特定的場景下使用該模式。例如伴生模式下的容器,后文會提到兩個容器共享同一個存儲卷,從而形成內容管理和內容發布兩個容器聚合在同一個Pod中對外透明服務。
圖2-2演示了一個Pod內有兩個容器,分別是Drupal站點和Drupal后端數據庫。但在這種模式下無法橫向擴展,只有Drupal站點系統和MySQL數據庫分離后在不同的Pod中才能進行擴展。

圖2-2 一個Pod多個容器
2.3.3 初始化容器
Pod能夠聚合多個容器,應用在容器里面運行,但是它也可能有一個或多個先于應用容器啟動的初始化容器(Init container)。
初始化容器與普通容器非常像,除了如下兩點:
● 它們總是運行到完成。
● 每個都必須在下一個啟動之前成功完成。
如果Pod的初始化容器失敗,Kubernetes會不斷地重啟該Pod,直至初始化容器成功。當然,如果Pod對應的restartPolicy值為Never,則不會重新啟動。
在本書所提及的Elasticsearch部署案例中,使用了三個初始化容器,按照以下順序執行:
● 修正存儲卷的權限。
● 修改系統參數vm.max_map_count。
● 修改系統參數ulimit的值。
描述初始化容器:

修正存儲卷的權限:

增加系統參數vm.max_map_count到262144:

增加ulimit值:

2.3.4 狀態探針
在Kubernetes中,通過kubelet對容器進行持續探測來判斷容器是否可用,一旦容器不可用,kubelet將重啟該容器。為了更精確地判斷容器狀態,Kubernetes中提供了就緒探針(Readiness Probe)和存活探針(Liveness Probe)。
存活探針用于判斷容器啟動就緒后是否還在持續正常服務。業務有可能會因為某種錯誤而導致系統不可用,或者普通的探測方法不足以判斷業務是否正常工作,此時可以通過設置自定義的存活探針來檢測。
就緒探針用于判斷容器是否可以接受流量,是針對有前端服務的容器來講的。有些容器可能已經啟動完畢,但是業務系統還不能正常處理請求。例如Tomcat啟動需要1min,此時要進行存活狀態檢測將返回不可用,前端服務就不會將請求轉給容器。
存活探針的事例代碼如下,在該代碼中,使用了httpGet方法去探測,訪問的path是/healthz,并且在容器啟動3s后進行判斷,之后每隔3s進行一次探測。

就緒探針和存活探針非常類似,只是將liveness Probe換成readiness Probe。其中幾個關鍵參數說明如下:
● initialDelaySeconds:容器啟動后第一次執行探測需要等待多少秒。
● periodSeconds:執行探測的頻率。默認間隔是10s,最小1s。
● timeoutSeconds:探測超時時間。默認1s,最小1s。
● successThreshold:探測失敗后,最少連續探測成功多少次才被認定為成功。默認是1。對于liveness必須是1。最小值是1。
● failureThreshold:探測成功后,最少連續探測失敗多少次才被認定為失敗。默認是3。最小值是1。
2.3.5 測試工具
Kubernetes中容器所在的網絡與客戶端所在的網絡是不能直接通信的,這就導致部署一個Pod后,如果需要測試其功能將非常麻煩。為此,Google推出了一個busybox鏡像,該鏡像含有基本的網絡工具,用于在容器網絡中測試。
例如,可以通過命令來ping一個名稱為test的Pod:

也可以訪問容器內的某個網站:
