目錄
引言
一、Pod基礎概念
(一)Pod簡介
(二)Pod的分類
1.自主式Pod
2.控制器管理的Pod
(三)Pod使用方式
1.單容器pod
2.多容器Pod
3. 注意事項
二、Pod容器的分類
(一)基礎容器
1.Pause容器的主要作用
2.基礎容器的創建
3. pod中容器通信
(二)初始化容器
1.主要特點
2.用途
3.官網示例
3.1 編寫yaml文件
3.2 創建service
4.具體行為
(三)應用容器
三、鏡像拉取策略
(一)Always
1.基本含義
2.示例
2.1 編寫文件
2.2 查看策略結果
(二)IfNotPresent
1.基本含義
2.示例
(三)Never
1.基本含義
2.示例
四、容器重啟策略
(一)Always
1.編寫文件
2.查看結果
(二)OnFailure
1.編寫文件
2.查看結果
(三)Never
1.編寫文件
2.查看結果
引言
在Kubernetes(簡稱K8s)這一強大的容器編排系統中,Pod是最基本的部署單元。Pod封裝了一個或多個容器,共享存儲、網絡和進程空間,允許它們協同工作以完成特定任務。本文將深入探討Pod的概念、特性以及如何在K8s中對其進行管理
一、Pod基礎概念
(一)Pod簡介
Pod是Kubernetes中的最小部署單元,它是一組(一個或多個)緊密關聯的容器集合,它們共享存儲、網絡、以及對于如何運行容器的聲明(比如啟動命令、環境變量等)。Pod中的容器共享一個IP地址和端口空間,它們可以直接通過localhost互相通信。
Pod是Kubernetes進行管理的最小單位,而不是僅僅運行的單個容器。Pod的設計初衷是支持多個容器在一個Pod中協同工作,完成一個復雜的任務。這些容器共享Pod級別的存儲卷、網絡和生命周期。Pod中可能包含一個或多個緊密相關的應用容器,這些容器可以共享數據卷、網絡棧和生命周期管理
(二)Pod的分類
1.自主式Pod
自主式Pod(Ad-Hoc Pod或Non-Controller Managed Pod)是指那些由用戶直接創建但不受任何控制器管理的Pod。它們通常通過kubectl run命令或直接向API Server提交YAML/JSON配置文件的方式來創建。自主式Pod一旦創建,除非手動刪除,否則不會自動消失或者被重建。這類Pod沒有與之關聯的控制器,所以如果Pod出現故障,不會像受控制器管理的Pod那樣自動恢復到期望狀態
2.控制器管理的Pod
Kubernetes使用更高級的稱為Controller的抽象層,來管理Pod實例。Controller可以創建和管理多個Pod,提供副本管理、滾動升級和集群級別的自愈能力。例如,如果一個Node故障,Controller就能自動將該節點上的Pod調度到其他健康的Node上。雖然可以直接使用Pod,但是在Kubernetes中通常是使用Controller來管理Pod的。
(三)Pod使用方式
在Kubernetes中,Pod可以包含一個或多個容器,這些容器共享相同的網絡命名空間、存儲卷和生命周期。根據Pod中容器數量的不同,可以將Pod分為單容器Pod和多容器Pod。
1.單容器pod
單容器Pod是最簡單和最常見的Pod類型,它只包含一個容器。在這種情況下,Pod的整個生命周期和容器的生命周期是一致的。當容器啟動時,Pod開始運行;當容器停止時,Pod也會終止。單容器Pod通常用于運行單個應用或服務,該應用或服務在單個容器中就能完成所有功能。
2.多容器Pod
多容器Pod則包含兩個或更多容器,這些容器共享相同的網絡和存儲資源,并且可以相互通信。多容器Pod通常用于以下場景
2.1 邊車(Sidecar)模式
邊車模式是一種常用的多容器Pod設計模式。在這種模式下,一個主容器負責處理主要的業務邏輯,而一個或多個邊車容器則提供輔助功能,如日志收集、監控、配置管理等。邊車容器與主容器共享相同的網絡和存儲資源,因此可以輕松地訪問主容器的日志、配置文件等。
2.2 容器間通信
多容器Pod允許容器之間通過localhost進行通信,這使得容器間協作變得更加容易。例如,一個Web應用可能需要一個數據庫容器來存儲數據,這兩個容器可以部署在同一個Pod中,并通過localhost進行通信。
2.3 資源共享
多容器Pod中的所有容器共享相同的網絡和存儲資源,這可以簡化資源的配置和管理。例如,多個容器可以共享同一個存儲卷,以便在容器之間共享數據
3. 注意事項
- 雖然多容器Pod在某些場景下很有用,但過度使用多容器Pod也可能導致一些問題。例如,如果Pod中的容器過多,可能會導致資源競爭和管理復雜性增加。
- 在設計多容器Pod時,需要仔細考慮容器之間的依賴關系和通信方式,以確保Pod的穩定性和可維護性。
- 通常情況下,建議將獨立的服務或組件部署在單獨的Pod中,以便更好地進行資源隔離和擴展。只有在確實需要容器間緊密協作或共享資源的情況下,才考慮使用多容器Pod。
二、Pod容器的分類
Pod容器在Kubernetes中可以根據其功能和使用場景進行分類。常見的Pod容器分類包括
(一)基礎容器
基礎容器,又叫Pause容器(全稱Infrastructure Container或Infra容器)是Kubernetes中的一個特殊容器,主要用于支持Pod級別的網絡命名空間和共享存儲卷。它是由Kubernetes自動生成并注入到每個Pod中的,不是用戶定義的容器。
1.Pause容器的主要作用
創建共享網絡命名空間:Pause容器首先啟動,并創建一個網絡命名空間,所有該Pod內的其他業務容器都加入到這個共享的網絡命名空間中,并分配不同的IP地址。這意味著這些容器可以相互通信就如同它們在同一臺主機上的進程一樣,共享相同的網絡棧和IP地址。
PID命名空間共享:Pod中的不同容器通過共享Pause容器的PID命名空間,使得容器間能夠看到彼此的進程ID。
IPC命名空間共享:在同一Pod內的容器也可以通過Pause容器共享IPC命名空間,從而允許它們使用SystemV IPC或POSIX消息隊列進行跨容器通信。
資源隔離與管理:雖然Pause容器本身通常是一個非常小且不執行任何實際業務邏輯的鏡像(僅包含一個無限循環或暫停進程),但它作為Pod內所有容器的父進程,有助于系統管理和跟蹤容器生命周期。同時,Pause容器的存在簡化了對Pod整體行為的管理和控制
存儲:Pod可以指定多個共享的Volume。Pod中的所有容器都可以訪問共享的Volume。Volume也可以用來持久化Pod中的存儲資源,以防容器重啟后文件丟失。
2.基礎容器的創建
在創建一個pod時,節點服務器上會事先創建一個pause容器做為基礎,而后去生成應用容器,pause容器負責管理此應用容器
創建一個自主式pod,而后在對應的node節點上進行查看
[root@master01 ~]#kubectl run nginx --image=nginx:1.18.0
pod/nginx created
[root@master01 ~]#kubectl get pod nginx -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 8s 10.244.1.101 node01 <none> <none>
[root@master01 ~]#
在node01節點上查看
[root@node01 ~]#docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9a7620aa067b c2c45d506085 "/docker-entrypoint.…" 2 minutes ago Up 2 minutes k8s_nginx_nginx_default_82cb8607-3afd-4f8b-a021-fd7bc26320a0_0
3faadfeb233f k8s.gcr.io/pause:3.2 "/pause" 2 minutes ago Up 2 minutes k8s_POD_nginx_default_82cb8607-3afd-4f8b-a021-fd7bc26320a0_0
#在開啟pod之前,會建立k8s.gcr.io/pause:3.2基礎容器,而后管理pod
3. pod中容器通信
在同一個pod中的多個容器之間,需要通過pause創建的共享網絡空間進行通信
當Kubernetes創建一個Pod時,會首先啟動一個Pause容器。這個Pause容器會創建一個新的網絡命名空間,并且初始化該命名空間的網絡接口。隨后,當Pod中的其他容器啟動時,它們會被加入到這個已經由Pause容器創建的網絡命名空間中。
由于所有容器都共享同一個網絡命名空間,它們可以直接通過localhost或者Pod的IP地址進行通信,無需經過Pause容器。
同樣的,如果需要進行數據共享,pause容器同樣會創建一個共享存儲空間進行數據之間的共享
(二)初始化容器
初始化容器在主應用程序容器啟動之前運行,用于執行一些初始化任務,如設置配置文件、初始化數據庫或等待外部服務準備就緒等。
在Kubernetes中,初始化容器(Init Containers)是一種特殊類型的容器,它們在應用程序容器啟動之前運行。
1.主要特點
初始化順序:初始化容器總是在Pod的主容器(即應用容器)啟動之前運行。如果有多個初始化容器,它們會按照在Pod定義中的順序一個接一個地運行。只有當所有的初始化容器都成功執行完畢后,主容器才會啟動。
獨立性和隔離性:每個初始化容器都獨立運行并單獨完成其任務。初始化容器之間以及初始化容器和主容器之間都是隔離的。
運行時長:初始化容器必須運行成功到完成(即退出碼為0),如果初始化容器運行失敗(即退出碼非0),Kubernetes會不斷重啟Pod,直到初始化容器成功為止(除非Pod的重啟策略設置為Never)。
資源限制:初始化容器可以使用與主容器相同的資源限制和配額。
2.用途
資源準備:某些應用程序可能需要一些額外的資源或文件,例如配置文件、SSL證書、密鑰等。初始化容器可以負責從配置存儲或其他位置獲取這些資源,并將它們復制到應用容器可以訪問的位置。
同步/等待:有時,應用程序可能需要等待其他外部依賴項就緒,例如數據庫服務或消息隊列。初始化容器可以負責檢查這些依賴項的可用性,并在其就緒后再啟動應用容器。
數據預處理:某些應用程序可能需要在啟動之前對數據進行預處理,例如解壓縮文件、驗證數據完整性等。初始化容器可以在應用容器之前執行這些任務,確保應用容器運行時所需的數據已準備就緒。
提供工具程序或自定義代碼:初始化容器還可以提供主容器鏡像中不具備的工具程序或自定義代碼,以滿足特定的初始化需求。
修改目錄權限:初始化容器還可以用于修改應用容器所需的目錄權限,確保應用容器能夠正常訪問和寫入所需的文件或目錄。
3.官網示例
在官網網站中有如何使用init容器的示例文件
官方網站:Init 容器 _ Kubernetes(K8S)中文文檔_Kubernetes中文社區
3.1 編寫yaml文件
[root@master01 data]#vim init.yaml
[root@master01 data]#cat init.yaml
apiVersion: v1 #指定了 Kubernetes API 的版本
kind: Pod #指定創建資源的類型為pod
metadata: #開始定義Pod的元數據name: myapp-pod #Pod 的名稱labels: #定義標簽名稱app: myapp
spec: #定義Pod的期望狀態的所有信息containers: #定義Pod中要運行的容器- name: myapp-container #容器的名稱image: busybox #容器要使用的鏡像command: ['sh', '-c', 'echo The app is running! && sleep 3600']
#command指令,表示在容器中運行的命令及其參數。
#[...]:表示運行一個 shell 命令,該命令輸出一條消息并休眠3600秒(1 小時)。initContainers: #開始定義初始化容器- name: init-myserviceimage: busyboxcommand: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']- name: init-mydbimage: busyboxcommand: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
#初始化容器要運行的命令及其參數。
#在這個例子中,兩個初始化容器都運行了一個shell命令,until表示死循環。
#與while的區別在于,while條件判斷為真時,則會進行循環,而until表示條件為假時,進行死循環
#該命令使用 nslookup 來檢查 myservice 和 mydb 是否可解析。
#如果它們不可解析,則命令會輸出一條消息并休眠 2 秒,然后再次嘗試#initContainers是一個特殊的容器列表,它們在Pod的主容器啟動之前運行。
#這些容器可以包含用于設置 Pod 運行環境的初始化任務,如等待其他服務變得可用
此時還需要創建兩個用于解析的service,(myservice、mydb)
如果不創建service資源,當使用nslookup進行解析時,因為沒有myservice與mydb這個域名,導致nslookup解析失敗,until判斷條件為假,則會陷入循環
不創建service時,執行該文件,STATUS會一直處于Init:0/2的狀態
[root@master01 data]#kubectl apply -f init.yaml
pod/myapp-pod created
[root@master01 data]#kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod/myapp-pod 0/1 Init:0/2 0 19s 10.244.1.116 node01 <none> <none>
可以通過kubectl get events指令通過查看事件信息,查看調度信息與創建情況
[root@master01 data]#kubectl get events
LAST SEEN TYPE REASON OBJECT MESSAGE
2m43s Normal Pulling pod/myapp-pod Pulling image "busybox"
2m42s Normal Scheduled pod/myapp-pod Successfully assigned default/myapp-pod to node01
2m27s Normal Pulled pod/myapp-pod Successfully pulled image "busybox" in 15.925716511s
2m27s Normal Created pod/myapp-pod Created container init-myservice
2m26s Normal Started pod/myapp-pod Started container init-myservice
當狀態一直處于Init:0/2時,可以通過日志查看pod中init容器的啟動失敗的原因
按照定義init容器的順序進行查看,首先查看init-myservice初始化容器
[root@master01 data]#kubectl logs myapp-pod -c init-myservice
Server: 10.96.0.10
Address: 10.96.0.10:53** server can't find myservice.default.svc.cluster.local: NXDOMAIN*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.default.svc.cluster.local: No answer
*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answerwaiting for myservice #進入死循環時echo輸出的信息
Server: 10.96.0.10
Address: 10.96.0.10:53** server can't find myservice.default.svc.cluster.local: NXDOMAIN*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.default.svc.cluster.local: No answer
*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
......#錯誤信息表示在解析myservice并沒有找到這個名稱,并且返回了NXDOMAIN(非存在域)錯誤。導致一直處在死循環當中
由于init-myservice初始化容器并沒有成功運行,pod會不斷重啟這個容器,導致init-mydb無法運行,同樣的也不會運行myapp-pod這個pod實例
相似的,init-mydb的初始化容器,同樣如此,所以需要創建這兩個service,是nslookup能夠正常解析
3.2 創建service
使用yaml文件,同時創建兩個service
[root@master01 data]#vim svc.yaml
[root@master01 data]#cat svc.yaml
apiVersion: v1
kind: Service
metadata:name: myservice
spec:ports:- protocol: TCPport: 80targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:name: mydb
spec:ports:- protocol: TCPport: 80targetPort: 9377
創建service
[root@master01 data]#kubectl apply -f svc.yaml
service/myservice created
service/mydb created
[root@master01 data]#kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-pod 0/1 Init:1/2 0 22m #先啟動定義的第一個初始化容器NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
service/mydb ClusterIP 10.96.50.193 <none> 80/TCP 86s
service/myservice ClusterIP 10.96.33.11 <none> 80/TCP 86s
[root@master01 data]#kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/myapp-pod 1/1 Running 0 23m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
service/mydb ClusterIP 10.96.50.193 <none> 80/TCP 2m10s
service/myservice ClusterIP 10.96.33.11 <none> 80/TCP 2m10s#當兩個初始化容器都啟動成功后,則會正常啟動應用容器,即myapp-pod
4.具體行為
在 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 容器可能會被重啟、重試或者重新執行,所以 Init 容器的代碼應該是冪等的。 特別地,被寫到?EmptyDirs?中文件的代碼,應該對輸出文件可能已經存在做好準備。
Init 容器具有應用容器的所有字段。 除了?readinessProbe,因為 Init 容器無法定義不同于完成(completion)的就緒(readiness)的之外的其他狀態。 這會在驗證過程中強制執行。
在 Pod 上使用?activeDeadlineSeconds,在容器上使用?livenessProbe,這樣能夠避免 Init 容器一直失敗。 這就為 Init 容器活躍設置了一個期限。
在 Pod 中的每個 app 和 Init 容器的名稱必須唯一;與任何其它容器共享同一個名稱,會在驗證時拋出錯誤。
(三)應用容器
Pod是Kubernetes中用于運行和管理應用程序的基本單元,而Pod中的應用容器則是實際運行應用程序的組件。通過合理地定義和管理Pod和其中的容器,可以構建出高可用、可擴展和易于管理的分布式應用程序
三、鏡像拉取策略
Pod 的核心是運行容器,必須指定容器引擎,比如 Docker,啟動容器時,需要拉取鏡像,k8s 的鏡像拉取策略可以由用戶指定:
(一)Always
1.基本含義
當設置為Always時,kubelet在每次創建Pod或者重啟容器時,無論本地節點上是否已存在該鏡像,都會嘗試從鏡像倉庫中拉取的鏡像。這確保了你總是使用倉庫中最新的鏡像版本,但可能會導致不必要的網絡流量和拉取時間,尤其是在頻繁重啟容器的場景下。此策略是默認的鏡像拉取策略
2.示例
2.1 編寫文件
[root@master01 data]#vim always.yaml
[root@master01 data]#cat always.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx01
spec:containers:- name: nginx01image: nginx #使用nginx官方鏡像,不指定版本默認使用最新版本imagePullPolicy: Always #定義鏡像拉取策略為Alwayscommand: [ "echo", "imagepullpolicy is always" ]
#這指定了容器啟動時要運行的命令。
#此例中,容器不會運行nginx服務器,而是會執行echo "imagepullpolicy is always"命令,
#并打印出"imagepullpolicy is always"字符串#注意:由于command字段覆蓋了容器的默認命令(在這種情況下是啟動nginx服務器的命令),
#因此即使指定了nginx鏡像,容器也不會運行nginx服務器
2.2 查看策略結果
使用yaml文件創建pod后,可以查看event事件,并過濾出nginx01的信息,來查看有關事件,或者使用describe查看詳細信息
[root@master01 data]#kubectl apply -f always.yaml
[root@master01 data]#kubectl get pod nginx01
NAME READY STATUS RESTARTS AGE
nginx01 0/1 CrashLoopBackOff 2 83s
#Pod的狀態為CrashLoopBackOff時,這通常意味著容器在啟動后立即崩潰
[root@master01 data]#kubectl get events|grep "pod/nginx01"
56m Normal Killing pod/nginx01 Stopping container nginx01
3m51s Normal Scheduled pod/nginx01 Successfully assigned default/nginx01 to node02
2m18s Normal Pulling pod/nginx01 Pulling image "nginx"
3m35s Normal Pulled pod/nginx01 Successfully pulled image "nginx" in 15.726844912s
2m2s Normal Created pod/nginx01 Created container nginx01
2m2s Normal Started pod/nginx01 Started container nginx01
3m17s Normal Pulled pod/nginx01 Successfully pulled image "nginx" in 15.72008403s
98s Warning BackOff pod/nginx01 Back-off restarting failed container
2m45s Normal Pulled pod/nginx01 Successfully pulled image "nginx" in 15.97180592s
2m2s Normal Pulled pod/nginx01 Successfully pulled image "nginx" in 15.664176207s
#可以發現Pod中的容器在生命周期結束后,由于鏡像拉取策略為Always,會重新拉取鏡像,而后重啟容器
(二)IfNotPresent
1.基本含義
當設置為IfNotPresent時,kubelet首先會檢查本地節點上是否已存在指定的鏡像。如果存在,就直接使用本地鏡像;如果不存在,則會從鏡像倉庫中拉取。這種方式可以減少不必要的鏡像拉取操作,加快啟動速度,同時節省網絡帶寬。它能夠利用緩存提高效率,同時保持一定的靈活性
在node節點上查看存在的nginx鏡像版本
#node01節點
[root@node01 ~]#docker images |grep nginx
nginx 1.18.0 c2c45d506085 3 years ago 133MB#node02節點
[root@node02 ~]#docker images|grep nginx
nginx 1.18.0 c2c45d506085 3 years ago 133MB
2.示例
通過創建nginx:1.18.0版本的pod實例與創建nginx:1.20.2版本的pod實例,再查看event事件,來鑒別IfNotPresent策略的作用
編寫創建nginx:1.18.0版本與nginx:1.20.2版本的pod實例的yaml文件
[root@master01 data]#cat ifnotpresent.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx02
spec:containers:- name: nginx02image: nginximagePullPolicy: IfNotPresent #指定鏡像拉取策略為IfNotPresent
---
apiVersion: v1
kind: Pod
metadata:name: nginx03
spec:containers:- name: nginx03image: nginx:1.20.2imagePullPolicy: IfNotPresent #指定鏡像拉取策略為IfNotPresent
當創建成功時,查看event事件
[root@master01 data]#kubectl describe pod nginx02 |sed -n "/Events/,/$$/p"
#使用describe查看pod的詳細信息,并使用sed過濾出Events行到最后一行
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled 4m5s default-scheduler Successfully assigned default/nginx02 to node02Normal Pulled 4m4s kubelet Container image "nginx:1.18.0" already present on machine
#此信息表示容器鏡像nginx:1.18.0已經在目標節點node02上存在,所以沒有重新拉取鏡像,直接使用了現有的鏡像。Normal Created 4m4s kubelet Created container nginx02Normal Started 4m3s kubelet Started container nginx02
[root@master01 data]#kubectl describe pod nginx03 |sed -n "/Events/,/$$/p"
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Pulling 4m10s kubelet Pulling image "nginx:1.20.2"Normal Scheduled 4m9s default-scheduler Successfully assigned default/nginx03 to node01Normal Pulled 3m39s kubelet Successfully pulled image "nginx:1.20.2" in 30.148587341s
#在node01上拉取鏡像,拉取鏡像時長為30.148587341sNormal Created 3m39s kubelet Created container nginx03Normal Started 3m39s kubelet Started container nginx03
(三)Never
1.基本含義
當設置為Never時,kubelet不會試圖從鏡像倉庫拉取鏡像,僅使用節點上已有的鏡像。如果本地節點缺少請求的鏡像,Pod將無法啟動,并報告錯誤。
2.示例
編寫yaml文件,設置拉取策略為Never
[root@master01 data]#vim never.yaml
[root@master01 data]#cat never.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx04
spec:containers:- name: nginx04image: nginx:1.14imagePullPolicy: Never
查看事件信息
[root@master01 data]#kubectl apply -f never.yaml
pod/nginx04 created
[root@master01 data]#kubectl get pod nginx04
NAME READY STATUS RESTARTS AGE
nginx04 0/1 ErrImageNeverPull 0 28s
[root@master01 data]#kubectl get events |grep "pod/nginx04"
51s Normal Scheduled pod/nginx04 Successfully assigned default/nginx04 to node02
9s Warning ErrImageNeverPull pod/nginx04 Container image "nginx:1.14" is not present with pull policy of Never
9s Warning Failed pod/nginx04 Error: ErrImageNeverPull
#創建失敗,因為本地沒有nginx:1.14版本的鏡像文件
注意:對于標簽為“:latest”的鏡像文件,其默認的鏡像獲取策略即為“Always”;而對于其他標簽的鏡像,其默認策略則為“IfNotPresent”
四、容器重啟策略
在Kubernetes(K8s)中,重啟策略(restartPolicy)定義了Pod中的容器在退出時應如何被重啟。Pod的spec字段中包含一個restartPolicy字段,該字段決定了容器在遇到故障或退出時應如何響應。
Kubernetes支持以下三種重啟策略
(一)Always
總是重啟。這是默認值。當容器終止退出后,總是重啟容器。無論容器的退出狀態碼是什么,它都會被重啟
1.編寫文件
編寫yaml文件,設置重啟策略為Always
[root@master01 data]#vim restart-always.yaml
[root@master01 data]#cat restart-always.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx05
spec:containers:- name: nginx05image: nginx:1.18.0args:- /bin/sh- -c- sleep 10; exit 3 #休眠10秒。10秒鐘后,退出,并返回狀態碼為3restartPolicy: Always #設置重啟策略為Always
2.查看結果
使用yaml文件創建后,在打開新的終端,進行追蹤
[root@master01 data]#kubectl apply -f restart-always.yaml
pod/nginx05 created
[root@master01 data]#kubectl get pod nginx05 -w
NAME READY STATUS RESTARTS AGE
nginx05 0/1 ContainerCreating 0 2s
nginx05 1/1 Running 0 2s
nginx05 0/1 Error 0 12s #休眠十秒后退出
nginx05 1/1 Running 1 13s #重啟啟動
nginx05 0/1 Error 1 23s #休眠十秒后退出
nginx05 0/1 CrashLoopBackOff 1 35s
nginx05 1/1 Running 2 36s
nginx05 0/1 Error 2 46s #休眠十秒后退出
nginx05 0/1 CrashLoopBackOff 2 61s
nginx05 1/1 Running 3 77s
nginx05 0/1 Error 3 87s
.......#其結果就是該容器退出后不停的進行重啟
注釋:,Pod的restartPolicy被設置為Always,這意味著當容器退出時(無論退出狀態碼是什么),它都將被重啟。容器啟動后,會運行/bin/sh -c "sleep 10; exit 3"命令,該命令會使容器休眠10秒然后以狀態碼3退出。由于重啟策略是Always,所以容器退出后會立即被重啟
(二)OnFailure
僅當容器異常退出(退出狀態碼非0)時,才重啟容器。
1.編寫文件
同樣的,將重啟策略修改為onfailure,當狀態碼為非0是會重啟,而當狀態碼為0時,則不會重啟
[root@master01 data]#vim restart-onfailure.yaml
[root@master01 data]#cat restart-onfailure.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx06
spec:containers:- name: nginx06image: nginx:1.18.0args:- /bin/sh- -c- sleep 10; exit 3 #休眠十秒后退出,并指定狀態碼為3restartPolicy: OnFailure
---
apiVersion: v1
kind: Pod
metadata:name: nginx07
spec:containers:- name: nginx07image: nginx:1.18.0args:- /bin/sh- -c- sleep 10; exit #休眠十秒后退出,默認狀態碼為0restartPolicy: OnFailure
2.查看結果
[root@master01 data]#kubectl apply -f restart-onfailure.yaml
pod/nginx06 created
pod/nginx07 created
[root@master01 data]#kubectl get pod nginx06
NAME READY STATUS RESTARTS AGE
nginx06 1/1 Running 0 3s
[root@master01 data]#kubectl get pod nginx07
NAME READY STATUS RESTARTS AGE
nginx07 1/1 Running 0 5s
[root@master01 ~]#kubectl get pod nginx06
NAME READY STATUS RESTARTS AGE
nginx06 0/1 CrashLoopBackOff 1 36s
[root@master01 data]#kubectl get pod nginx07
NAME READY STATUS RESTARTS AGE
nginx07 0/1 Completed 0 37s
查看狀態碼為非0的pod實例
[root@master01 data]#kubectl get pod nginx06 -w
NAME READY STATUS RESTARTS AGE
nginx06 1/1 Running 0 11s
nginx06 0/1 Error 0 12s
nginx06 1/1 Running 1 13s
nginx06 0/1 Error 1 23s
nginx06 0/1 CrashLoopBackOff 1 36s
nginx06 1/1 Running 2 37s
nginx06 0/1 Error 2 47s
nginx06 0/1 CrashLoopBackOff 2 61s
nginx06 1/1 Running 3 73s
......
#當狀態碼為非0時,與always相同,它會不停的重啟
查看狀態碼為0的pod實例
[root@master01 ~]#kubectl get pod nginx07 -w
NAME READY STATUS RESTARTS AGE
nginx07 0/1 Completed 0 39s
#可以看到,休眠退出之后,因為是正常退出,狀態碼為0.所以不會重啟
(三)Never
不論狀態如何,當容器終止退出時,從不重啟容器
1.編寫文件
設置重啟策略為Never
[root@master01 data]#vim restart-never.yaml
[root@master01 data]#cat restart-never.yaml
apiVersion: v1
kind: Pod
metadata:name: nginx08
spec:containers:- name: nginx08image: nginx:1.18.0args:- /bin/sh- -c- sleep 10; exitrestartPolicy: Never #重啟策略為Never
2.查看結果
[root@master01 data]#kubectl apply -f restart-never.yaml
pod/nginx08 created
[root@master01 data]#kubectl get pod nginx08
NAME READY STATUS RESTARTS AGE
nginx08 1/1 Running 0 7s
[root@master01 data]#kubectl get pod nginx08
NAME READY STATUS RESTARTS AGE
nginx08 0/1 Completed 0 16s
[root@master01 data]#kubectl get pod nginx08
NAME READY STATUS RESTARTS AGE
nginx08 0/1 Completed 0 32s
#Completed正常退出容器,在Never策略下不會重啟
注釋:Kubernetes不支持直接重啟Pod資源,因為Pod是Kubernetes集群中的最小部署單元。如果你需要更改Pod的配置或重啟Pod中的容器,通常的做法是刪除并重新創建Pod。但是,通過設置合適的重啟策略,你可以確保在容器退出時自動重啟容器,而無需手動干預。