一、Pod基礎概念
? 1.1 Pod定義
? Pod是kubernetes中最小的資源管理組件,Pod也是最小化運行容器化應用的資源對象。一個Pod代表著集群中運行的一個進程。kubernetes中其他大多數組件都是圍繞著Pod來進行支撐和擴展Pod功能的,例如,用于管理Pod運行的StatefulSet和Deployment等控制器對象,用于暴露Pod應用的Service和Ingress對象,為Pod提供存儲的PersistentVolume存儲資源對象等。
? 一個Pod下的容器必須運行于同一節點上。現代容器技術建議一個容器只運行一個進程,該進程在容器中PID命令空間中的進程號為1,可直接接收并處理信號,進程終止時容器生命周期也就結束了。若想在容器內運行多個進程,需要有一個類似Linux操作系統init進程的管控類進程,以樹狀結構完成多進程的生命周期管理。運行于各自容器內的進程無法直接完成網絡通信,這是由于容器間的隔離機制導致,Pod對象是一組容器的集合,這些容器共享Network、UTS及IPC命令空間,因此具有相同的域名、主機名和網絡接口,并可通過IPC直接通信。
Pod資源中針對各容器提供網絡命令空間等共享機制的是底層基礎容器,又叫pause基礎容器(也可稱為父容器),pause就是為了管理Pod容器間的共享操作,這個父容器需要能夠準確地知道如何去創建共享運行環境的容器,還能管理這些容器的生命周期。為了實現這個父容器的構想,kubernetes中,用pause容器來作為一個Pod中所有容器的父容器。這個pause容器有兩個核心的功能,一是它提供整個Pod的Linux命名空間的基礎。二來啟用PID命名空間,它在每個Pod中都作為PID為1進程(init進程),并回收僵尸進程。
? 1.2 Pod管理方式
在Kubrenetes集群中Pod有如下兩種使用方式
- 一個Pod中運行一個容器。“每個Pod中一個容器”的模式是最常見的用法;在這種使用方式中,你可以把Pod想象成是單個容器的封裝,kuberentes管理的是Pod而不是直接管理容器。
- 在一個Pod中同時運行多個容器。一個Pod中也可以同時封裝幾個需要緊密耦合互相協作的容器,它們之間共享資源。這些在同一個Pod中的容器可以互相協作成為一個service單位。比如一個容器共享文件,另一個“sidecar”容器來更新這些文件。Pod將這些容器的存儲資源作為一個實體來管理。
??
? 1.3?pod共享資源
? ? pause容器使得Pod中的所有容器可以共享兩種資源:網絡和存儲。
- 網絡:每個Pod都會被分配一個唯一的IP地址。Pod中的所有容器共享網絡空間,包括IP地址和端口。Pod內部的容器可以使用localhost互相通信。Pod中的容器與外界通信時,必須分配共享網絡資源(例如使用宿主機的端口映射)。
- 存儲:Pod可以指定多個共享的Volume。Pod中的所有容器都可以訪問共享的Volume。Volume也可以用來持久化Pod中的存儲資源,以防容器重啟后文件丟失。
? ? 總結:pause管理網絡命名空間、共享存儲、負載調用、健康檢查、生存探針和協調生命周期,目的是讓port之間能夠相互共享存儲、共享網絡
? 1.4?設計pod的用意
- 在一組容器作為一個單元的情況下,難以對整體的容器簡單地進行判斷及有效地進行行動。比如,一個容器死亡了 那么引入與業務無關的Pause容器作為Pod的基礎容器,以它的狀態代表著整個容器組的狀態,這樣就可以解決該問題。
- Pod里的多個應用容器共享Pause容器的IP,共享Pause容器掛載的Volume。這樣解決了應用容器之間的通信問題以及文件共享問題
? 1.5?pod分類
- 自主式/靜態pod:不被控制器管理的pod,沒有自愈能力,一旦掛掉不會被重新拉起,而且副本數量不會因為達不到期望值而創建新的pod,即數據保存在節點上,一旦掛掉直接結束
- 控制器管理的pod:被控制器管理的pod有自愈能力,一旦pod掛掉會被重新拉起,而且副本數量會因為達不到期望值而創建新的pod。簡而言之,pod出現問題(生命周期刪除、故障等)會自動重新拉起新的pod
? 1.6?pod容器分類
- 基礎容器(infrastructure container)
??每次創建Pod時候就會創建,運行的每一個Pod都有一個pause-amd64的基礎容器自動會運行,對于用戶是透明的。
docker ps -a——進行docker容器的查看
- 初始化容器(initcontainers)
? 阻塞或者延遲應用容器的啟動,可以為應用容器事先提供好運行環境和工具。多個init容器時是串行啟動,每個init容器都必須在下一個init容器啟動前完成啟動和退出
- 應用容器(Maincontainer)
? 在所有init容器啟動和退出后應用容器才會啟動而且是并行啟動的應用,提供業務的程序業務
? 1.7?示例——啟動兩個init容器
? 1.7.1?在opt下創建demo文件夾
? 1.7.2?編輯demo1
官網示例:https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/
?1.7.3?啟動服務并查看pod
? 查看pod后發現init為0/2
? 1.7.4?解決問題
? 1.7.4.1?過濾出myapp
? 1.7.4.2?查看pod詳細信息
kubectl describe pod myapp-pod
? 1.7.4.3?查看日志信息
? 1.7.4.4?查看系統信息和服務
? ? 發現服務下沒有,需要創建一個server
? 1.7.4.5?編輯svc-demo1文件
? 1.7.4.6?啟動文件
? ? 啟動文件后,再次查看pod有相應服務?
? 1.7.4.7?查看pod詳細信息
? ? 發現init-mydb如上方的操作方式一致
kubectl describe pod myapp-pod
? 1.7.4.8 查看日志信息
kubectl logs myapp-pod -c init-myservice
? 1.7.4.9?編輯svc-demo1文件
? 1.7.4.10?執行文件
? ? 執行文件后,需要等pod創建完
特別說明:
- 在Pod啟動過程中,Init容器會按順序在網絡和數據卷初始化之后啟動。每個容器必須在下一個容器啟動之前成功退出。
- 如果由于運行時或失敗退出,將導致容器啟動失敗,它會根據Pod的restartPolicy指定的策略進行重試。然而,如果Pod的restartPolicy設置為Always,Init容器失敗時會使用RestartPolicy策略。
- 在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態。Init容器的端口將不會在Service中進行聚集。正在初始化中的Pod處于Pending狀態,但應該會將Initializing狀態設置為true。
- 如果Pod重啟,所有Init容器必須重新執行。
- 對Init容器spec的修改被限制在容器image字段,修改其他字段都不會生效。更改Init容器的image字段,等價于重啟該Pod。
- Init容器具有應用容器的所有字段。除了readinessProbe,因為Init容器無法定義不同于完成(completion)的就緒(readiness)之外的其他狀態。這會在驗證過程中強制執行。
- 在Pod中的每個app和Init容器的名稱必須唯一;與任何其它容器共享同一個名稱,會在驗證時拋出錯誤。?
? 1.8?鏡像拉取策略
? ? Pod的核心是運行容器,必須指定容器引擎,比如Docker,啟動容器時,需要拉取鏡像,k8s的鏡像拉取策略可以由用戶指定,通常分為三類:
- IfNotPresent:優先使用本地已存在的鏡像,如本地沒有則從倉庫去拉取鏡像
- Always:總是從倉庫拉取鏡像,無論本地是否已存在鏡像
- Never:總是不從倉庫拉取鏡像,僅使用本地鏡像
注意:
image nginx:latest或nginx 鏡像的標簽為latest或者無標簽時,默認拉取鏡像策略為always
nginx:1.14 鏡像的標簽為非latest時,默認的鏡像為獲取策略為IfNotPresent
? 1.8.1?實例一
官方示例:https://kubernetes.io/docs/concepts/containers/images?
? 1.8.1.1?編輯demo2?
? 1.8.1.2 執行demo2并查看pod
? 1.8.1.3?查看pod詳細信息
?kubectl describe pod myapp-pod
? 1.8.1.4?再次查看pod
? 1.8.1.5?過濾出restart
? 1.8.2?示例二
? 1.8.2.1?編輯demo2并執行,同時查看pod
? 1.8.2.2?查看pod詳細信息
kubectl describe pod myapp-pod
? 1.8.3?示例三?
? 1.8.3.1?編輯demo2并執行
? 1.8.3.2?查看日志信息
查看pod詳細信息?
? 1.8.3.3?查看pod
? 1.8.4?示例四
? ? 編輯demo2并執行,同時查看過濾出鏡像的pod
? 1.9?重啟策略(restartPolicy)
? ??pod容器重啟策略(restartPolicy)三種和container在同一層綁定。同時重啟策略也分為三種:
- Always:容器退出時總是重啟容器,不管返回狀態碼如何,默認的Port重啟策略
- OnFailure:僅在容器異常退出時(返回狀態碼非0時)會重啟策略
- Never:容器退出時從不重啟容器,不管返回狀態如何