目錄
pod概念
Kubernetes設計Pod概念和特殊組成結構的用意
Pod內部結構:
網絡共享:
存儲共享:
pause容器主要功能
pod創建方式
pod使用方式
pod分類
pod的容器分類
基礎容器(infrastructure container):
查看pause容器的基礎鏡像
配置kubelet使用阿里云的鏡像
初始化容器(init containers):
Init 容器和普通容器的區別
應用容器(業務容器 main container):
官方示例
完整執行示例
注意
pod 鏡像拉取策略(image PullPolicy)
鏡像拉取的三種策略
官方示例
測試示例
pod 容器重啟策略
重啟策略的三種格式
示例
pod狀態
Container生命周期
pod概念
Pod是Kubernetes中最小的部署單位,它可以包含一個或多個容器,并共享相同的網絡命名空間、IP地址和存儲卷。Pod通常用于運行一個單一應用程序實例或者一組相互關聯的應用程序實例。其他Kubernetes組件,如Deployment、StatefulSet、Service等,都是圍繞Pod來管理和擴展應用的功能。Deployment和StatefulSet用于管理Pod的生命周期,Service用于暴露Pod內部的應用程序服務,而PersistentVolume用于提供Pod的持久化存儲。
Kubernetes設計Pod概念和特殊組成結構的用意
-
解決容器組狀態管理問題:
-
引入Pause容器作為Pod的基礎容器,使得整個Pod的生命周期可以由Pause容器的狀態來代表。這種設計可以簡化對容器組狀態的判斷和管理,當一個容器死亡時,Pause容器的狀態可以反映整個Pod的狀態,從而觸發相應的處理措施,例如重啟Pod或者執行其他故障恢復操作。
-
簡化容器間通信和資源共享:
-
Pod中的多個應用容器共享Pause容器的IP地址和掛載的Volume,這樣可以簡化應用容器之間的通信問題,使它們能夠通過localhost直接通信。同時,共享Volume也解決了容器之間的文件共享問題,使得容器能夠共享數據和狀態,從而更輕松地進行協作和共享資源。
綜合而言,Pod的設計使得容器化應用程序在Kubernetes中能夠更加方便地進行管理和部署,同時提供了更高的靈活性和可靠性,使得容器組能夠更加高效地運行和協作。
Pod內部結構:
-
每個Pod都包含一個特殊的被稱為“基礎容器”的Pause容器,該容器負責管理Pod內部容器的共享操作。
-
除了Pause容器外,Pod還包含一個或多個緊密相關的用戶應用容器。
網絡共享:
-
Pod中的所有容器共享同一個網絡命名空間,擁有相同的IP地址和端口空間。
-
容器之間可以通過localhost進行通信,而與外部通信時,需要分配共享網絡資源,例如使用宿主機的端口映射。
存儲共享:
-
Pod可以指定多個共享的Volume,所有容器都可以訪問這些共享的Volume。
-
Volume也可以用于持久化Pod中的存儲資源,以防止容器重啟導致文件丟失。
這種設計使得Pod成為了Kubernetes中的最小調度單位,為容器化應用程序提供了便捷的管理和共享資源的機制。
pause容器主要功能
-
提供Linux命名空間共享的基礎:
-
Pause容器負責管理Pod中的網絡命名空間等共享資源,確保所有容器在Pod內部共享相同的網絡環境,從而實現容器間的通信和協作。
-
啟用PID命名空間,充當init進程:
-
Pause容器在Pod中作為PID命名空間的第一個進程(PID 1),類似于Linux系統中的init進程。它負責監控和管理其他容器的生命周期,例如處理僵尸進程等。
-
協調其他容器的生命周期:
-
Pause容器負責協調Pod中其他容器的生命周期,確保它們能夠按照預期啟動、停止和重啟,從而實現整個Pod的穩定運行。
-
提供健康檢查和生存探針:
-
Pause容器通常也會提供健康檢查和生存探針服務,以確保Pod中的其他容器處于健康狀態,并在必要時進行故障恢復或重啟操作。
pod創建方式
- 通過命令行工具kubectl創建Pod:您可以使用kubectl命令行工具創建Pod,并指定Pod的配置文件或直接提供Pod的定義。
kubectl create -f <pod-definition.yaml>
- 通過Deployment或StatefulSet創建Pod:Deployment和StatefulSet是Kubernetes中的控制器對象,它們管理Pod的生命周期,可以自動創建、擴展、更新和刪除Pod。
kubectl create deployment <deployment-name> --image=<image-name>
kubectl create statefulset <statefulset-name> --image=<image-name>
- 通過Pod模板創建Pod:您可以定義一個Pod模板,然后使用該模板創建多個Pod實例。
apiVersion: v1
kind: Pod
metadata:name: mypod
spec:containers:- name: mycontainerimage: nginx
- 通過命令行工具kubectl管理Pod:使用kubectl命令行工具,您可以管理Pod的各種操作,如獲取Pod信息、刪除Pod、調試Pod等。
kubectl get pods
kubectl describe pod <pod-name>
kubectl delete pod <pod-name>
- 通過調度器將Pod調度到集群節點:Kubernetes調度器負責將Pod調度到集群中的節點上,并確保Pod的資源需求得到滿足。
pod使用方式
-
在Kubernetes集群中,Pod有兩種主要的使用方式:
-
一個Pod中運行一個容器: 這是最常見的用法,每個Pod中只包含一個容器。在這種模式下,Pod可以被視為是封裝了單個容器的最小部署單元。Kubernetes管理的是Pod,而不是直接管理容器。這種方式適用于運行獨立的應用程序或服務,例如一個Web服務器或一個數據庫。
-
在一個Pod中同時運行多個容器: 一個Pod中也可以同時封裝多個需要緊密耦合互相協作的容器。這些容器共享相同的網絡命名空間、IP地址和存儲卷,它們可以協同工作成為一個服務單元。例如,一個容器可以負責運行主要的應用程序,而另一個"sidecar"容器可以處理日志收集、監控或其他輔助任務。Pod將這些容器作為一個實體來管理,它們共享Pod的資源,可以方便地相互通信和共享數據。
pod分類
-
自主式Pod:
-
這種類型的Pod本身不具備自我修復的能力。一旦創建后,Pod會被調度到集群的Node上,并保持在該節點上,直到滿足終止條件,如進程終止、被手動刪除、因缺少資源而被驅逐或節點故障等。Pod不會自動遷移或恢復。
-
如果Pod所在的Node發生故障,或者調度器出現故障,Pod將被刪除。同樣地,如果Pod所在Node缺少資源或處于維護狀態,Pod也會被驅逐。
-
控制器管理的Pod:
-
Kubernetes引入了更高級的抽象層稱為Controller來管理Pod實例。Controller可以管理多個Pod,并提供副本管理、滾動升級和集群級別的自愈能力。
-
通過使用Controller,可以實現對Pod的自動化管理,例如在節點故障時自動遷移Pod到其他健康的節點上。通常情況下,Kubernetes推薦使用Controller來管理Pod,而不是直接操作Pod。
pod的容器分類
基礎容器(infrastructure container):
-
基礎容器負責維護整個Pod的網絡和存儲空間,是Pod中的一個特殊容器。
-
每當創建一個Pod時,Kubernetes會自動啟動一個基礎容器,通常使用Pause容器作為基礎容器。
查看pause容器的基礎鏡像
docker images #node01節點上
配置kubelet使用阿里云的鏡像
cat /etc/sysconfig/kubelet #node01節點上查看pause配置鏡像文件
空值即為默認官方鏡像,修改為阿里pause鏡像源
cat > /etc/sysconfig/kubelet << EOFKUBELET_EXTRA_ARGS=--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF
初始化容器(init containers):
-
初始化容器是在應用容器啟動之前運行的容器,用于執行初始化任務或滿足先決條件。
-
初始化容器總是運行到成功完成為止,并且每個初始化容器必須在下一個初始化容器啟動之前成功完成啟動和退出。
-
初始化容器可以包含安裝、配置或準備數據等任務,使得應用容器能夠以正確的環境啟動運行。
-
如果 Pod 的 Init 容器失敗,k8s 會不斷地重啟該 Pod,直到 Init 容器成功為止。然而,如果 Pod 對應的重啟策略(restartPolicy)為 Never,它不會重新啟動。
Init 容器和普通容器的區別
-
包含實用工具或個性化代碼:
-
初始化容器可以包含一些在應用容器中不存在的實用工具或個性化代碼,例如sed、awk、python或dig等工具。這樣就無需為了使用這些工具而構建新的應用鏡像,可以在初始化容器中單獨使用它們。
-
安全運行工具:
-
由于初始化容器和應用容器分離,并且初始化容器的作用是在啟動前完成特定任務,因此可以安全地運行這些工具,而不會影響應用鏡像的安全性。
-
獨立工作:
-
創建者和部署者可以獨立地為初始化容器和應用容器工作,無需聯合構建單個應用鏡像。這樣可以提高靈活性和獨立性。
-
具有訪問權限:
-
初始化容器可以以不同于應用容器的文件系統視圖運行,因此可以具有訪問一些敏感信息如Secrets的權限。這樣可以確保敏感信息在初始化過程中被安全地使用。
-
阻塞或延遲應用容器啟動:
-
初始化容器必須在應用容器啟動之前成功運行完成。因此,可以利用初始化容器來阻塞或延遲應用容器的啟動,直到滿足一組先決條件。一旦這些條件滿足,Pod中的所有應用容器會并行啟動。
總的來說,初始化容器為Pod提供了一種在啟動前執行特定任務的機制,可以增加靈活性、安全性,并允許更細粒度地控制應用程序的啟動過程。
應用容器(業務容器 main container):
-
應用容器是Pod中實際運行業務邏輯的容器,它們通常并行啟動。
- 應用容器并行啟動是指在 Kubernetes Pod 中,所有的應用容器同時啟動并運行。這意味著當 Pod 中有多個應用容器時,它們可以在相同的時間段內開始執行,而不必等待其他容器啟動完成。這種并行啟動可以提高應用程序的啟動速度和整體性能,因為不同的容器可以在同一時間內獨立地執行其任務,而不會相互阻塞或等待其他容器的完成。這種方式可以加速應用程序的啟動過程,并提高整個集群的資源利用率。
-
應用容器執行實際的應用程序代碼,并處理業務邏輯。
官方示例
官網示例: https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/init-containers/
apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app: myapp
spec:containers:- name: myapp-containerimage: busybox:1.28command: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busybox:1.28command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']- name: init-mydbimage: busybox:1.28command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
這是一個官方示例,展示了一個Pod定義,其中包含一個應用容器(myapp-container
)和兩個初始化容器(init-myservice
和init-mydb
)。以下是對該示例的解釋:
-
Pod名稱和標簽:
-
Pod的名稱為
myapp-pod
,并設置了一個標簽app: myapp
。 -
應用容器:
-
應用容器的名稱為
myapp-container
,使用了busybox:1.28
鏡像。 -
容器中的命令是
['sh', '-c', 'echo The app is running! && sleep 3600']
,即在啟動后輸出一條消息并休眠3600秒。 -
初始化容器:
-
第一個初始化容器的名稱是
init-myservice
,使用了busybox:1.28
鏡像。 -
容器中的命令是
['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
,即等待名為myservice
的服務啟動完成。 -
第二個初始化容器的名稱是
init-mydb
,同樣使用了busybox:1.28
鏡像。 -
容器中的命令是
['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
,即等待名為mydb
的服務啟動完成。
這個示例的目的是展示如何使用初始化容器等待特定服務(myservice
和mydb
)啟動后,再啟動主應用容器。這種方式可以確保應用容器在滿足一組先決條件后才開始運行。此外,所有初始化容器和應用容器都可以并行啟動,提高了啟動效率。
-
示例Pod的定義展示了一個包含初始化容器和應用容器的Pod,初始化容器等待特定服務啟動后才啟動應用容器。這種設計使得Pod能夠按照需要完成初始化任務,并在滿足條件后才啟動應用程序,確保應用程序的可靠啟動和運行。
-
通過使用基礎容器、初始化容器和應用容器,Kubernetes提供了靈活而強大的容器編排能力,使得容器化應用程序的部署和管理更加簡單和可靠。
完整執行示例
kubectl describe pod myapp-podkubectl logs myapp-pod -c init-myservicevim myservice.yaml
apiVersion: v1
kind: Service
metadata:name: myservice
spec:ports:- protocol: TCPport: 80targetPort: 9376kubectl create -f myservice.yamlkubectl get svckubectl get pods -n kube-systemkubectl get podsvim mydb.yaml
apiVersion: v1
kind: Service
metadata:name: mydb
spec:ports:- protocol: TCPport: 80targetPort: 9377kubectl create -f mydb.yamlkubectl get pods
這個命令序列描述了一系列 Kubernetes 命令的執行過程,用于創建和管理 Pod 中的服務以及查看相關資源狀態。下面對每個命令進行解析:
-
kubectl describe pod myapp-pod
:描述了名為myapp-pod
的 Pod 的詳細信息,包括其狀態、容器信息、事件等。 -
kubectl logs myapp-pod -c init-myservice
:檢索名為myapp-pod
的 Pod 中init-myservice
容器的日志,用于查看初始化容器的執行情況。 -
vim myservice.yaml
:編輯一個名為myservice.yaml
的 YAML 文件,其中定義了一個名為myservice
的 Service,該 Service 暴露了端口 80,目標端口為 9376。 -
kubectl create -f myservice.yaml
:通過 YAML 文件創建名為myservice
的 Service。 -
kubectl get svc
:獲取所有服務的列表,包括剛創建的myservice
服務。 -
kubectl get pods -n kube-system
:獲取位于kube-system
命名空間中的所有 Pod 的列表。 -
kubectl get pods
:獲取所有 Pod 的列表,包括主命名空間中的 Pod。 -
vim mydb.yaml
:編輯一個名為mydb.yaml
的 YAML 文件,其中定義了一個名為mydb
的 Service,該 Service 暴露了端口 80,目標端口為 9377。 -
kubectl create -f mydb.yaml
:通過 YAML 文件創建名為mydb
的 Service。 -
kubectl get pods
:獲取所有 Pod 的列表,包括更新后的狀態,其中可能包括對myservice
和mydb
服務的影響。
這些命令用于創建、描述和管理 Kubernetes 中的各種資源,如 Pod 和 Service。通過這些命令,您可以查看集群中各種資源的狀態,以及執行與其相關的操作。
注意
-
Init容器啟動順序和退出條件:
-
在Pod啟動過程中,Init容器會按順序在網絡和數據卷初始化之后啟動,并且每個容器必須在下一個容器啟動之前成功退出。
-
Init容器的失敗和重試策略:
-
如果Init容器由于運行時錯誤或失敗退出,將導致容器啟動失敗。根據Pod的restartPolicy指定的策略進行重試。如果restartPolicy設置為Always,Init容器失敗時會使用RestartPolicy策略。
-
Pod狀態和Init容器就緒狀態:
-
在所有的Init容器沒有成功之前,Pod將不會變成Ready狀態。Init容器的端口將不會在Service中進行聚集。正在初始化中的Pod處于Pending狀態,但應該會將Initializing狀態設置為true。
-
Pod重啟和Init容器:
-
如果Pod重啟,所有Init容器必須重新執行。
-
修改Init容器的限制:
-
對Init容器spec的修改被限制在容器image字段,修改其他字段都不會生效。更改Init容器的image字段,等價于重啟該Pod。
-
Init容器的字段:
-
Init容器具有應用容器的所有字段,除了readinessProbe。因為Init容器無法定義不同于完成(completion)的就緒(readiness)之外的其他狀態,這會在驗證過程中強制執行。
-
容器名稱的唯一性:
-
在Pod中的每個應用和Init容器的名稱必須唯一;與任何其他容器共享相同名稱會在驗證時拋出錯誤。
這些規則和限制有助于確保Pod和Init容器的穩健性和可靠性,并提供了對容器啟動和狀態的嚴格管理和控制。
pod 鏡像拉取策略(image PullPolicy)
鏡像拉取策略(image PullPolicy)對于 Kubernetes Pod 中的容器部分非常重要,它決定了在容器啟動時如何獲取鏡像。
Pod 的核心是運行容器,必須指定容器引擎,比如 Docker,啟動容器時,需要拉取鏡像,k8s 的鏡像拉取策略可以由用戶指定
鏡像拉取的三種策略
-
IfNotPresent:如果鏡像已經存在于節點上(本地),則不會從鏡像倉庫中拉取鏡像。只有在本地缺少該鏡像時,才會從鏡像倉庫中拉取。這是默認的鏡像拉取策略。
-
Always:每次創建 Pod 時,都會強制從鏡像倉庫中拉取鏡像,即使本地已經存在該鏡像的版本。
-
Never:Pod 不會主動從鏡像倉庫拉取鏡像,它假定本地已經存在所需鏡像。如果本地不存在該鏡像,則會導致容器啟動失敗。
-
對于鏡像標簽為“:latest”的鏡像文件,其默認的拉取策略為“Always”,這意味著每次創建 Pod 時都會重新拉取最新版本的鏡像。而對于其他標簽的鏡像,默認的拉取策略為“IfNotPresent”,只有當本地缺少該鏡像時才會拉取。
在生產環境中,避免使用:latest
標簽是一個良好的實踐。使用:latest
標簽可能導致以下問題:
-
版本追蹤困難:由于
:latest
一直指向最新的鏡像版本,因此在運行時很難確定正在使用的確切版本。這使得故障排除、審計和版本追蹤變得更加困難。 -
難以正確回滾:如果使用
:latest
標簽,并且在應用升級后出現問題,回滾到先前的版本可能會變得復雜,因為:latest
一直指向新的版本。使用特定版本的標簽可以更容易地進行回滾操作。
為了提高生產環境中的可維護性和可追溯性,推薦以下做法:
-
使用明確的鏡像版本標簽,例如
nginx:1.2
,而不是nginx:latest
。 -
定期更新使用的鏡像版本,并確保及時進行測試和部署。
-
在部署時明確指定所使用的鏡像版本,以確保重現性和可控性。
總的來說,鏡像拉取策略允許 Kubernetes 用戶控制容器啟動時鏡像的獲取行為,以確保應用程序始終使用正確的鏡像版本。
官方示例
官方示例: https://kubernetes.io/docs/concepts/containers/images
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:name: private-image-test-1
spec:containers:- name: uses-private-imageimage: $PRIVATE_IMAGE_NAMEimagePullPolicy: Alwayscommand: [ "echo", "SUCCESS" ]
EOF
這段命令使用了 Kubernetes 的 kubectl apply
命令,并通過標準輸入(stdin)傳遞了一個 Pod 的 YAML 配置文件。以下是對該配置文件的解析:
-
apiVersion: v1
:指定 Kubernetes API 的版本,這里使用的是 v1 版本。 -
kind: Pod
:定義了要創建的 Kubernetes 資源類型,這里是一個 Pod 對象。 -
metadata
:指定 Pod 的元數據,包括名稱等信息。 -
name: private-image-test-1
:指定 Pod 的名稱為private-image-test-1
。 -
spec
:定義了 Pod 的規格,包括容器的配置信息。 -
containers
:指定了 Pod 中包含的容器列表。-
name: uses-private-image
:定義了一個名為uses-private-image
的容器。 -
image: $PRIVATE_IMAGE_NAME
:指定了容器所使用的鏡像。這里使用了一個變量$PRIVATE_IMAGE_NAME
,該變量的值可能是一個私有鏡像的名稱。 -
imagePullPolicy: Always
:指定了容器的鏡像拉取策略為Always
,即每次創建 Pod 時都會重新拉取鏡像。 -
command: [ "echo", "SUCCESS" ]
:定義了容器啟動時要執行的命令,這里是輸出SUCCESS
消息。
-
該配置文件描述了一個 Pod,其中包含一個使用私有鏡像的容器。通過 imagePullPolicy: Always
指定了每次創建 Pod 都會重新拉取鏡像,以確保使用的是最新的鏡像版本。
master01 上操作
kubectl edit deployment/nginx-deployment
......template:metadata:creationTimestamp: nulllabels:app: nginxspec:containers:- image: nginx:1.15.4imagePullPolicy: IfNotPresent #鏡像拉取策略為 IfNotPresentname: nginxports:- containerPort: 80protocol: TCPresources: {}terminationMessagePath: /dev/termination-logterminationMessagePolicy: FilednsPolicy: ClusterFirstrestartPolicy: Always #Pod的重啟策略為 Always,默認值schedulerName: default-schedulersecurityContext: {}terminationGracePeriodSeconds: 30
......
這是一個對 nginx-deployment
的 Kubernetes 部署進行編輯的命令。以下是編輯部署時對部分配置的更改和一些注釋:
-
kubectl edit deployment/nginx-deployment
:通過編輯器編輯名為nginx-deployment
的 Kubernetes 部署。 -
template
:指定了部署中的 Pod 模板,即在每次創建 Pod 時使用的模板。 -
metadata
:包含了 Pod 模板的元數據。-
creationTimestamp: null
:指示該 Pod 模板的創建時間戳為空,表示此時尚未創建。 -
labels
:定義了一些標簽,其中app: nginx
是一個標識該 Pod 所屬應用的標簽。
-
-
spec
:包含了 Pod 模板的規格。-
containers
:指定了 Pod 中包含的容器列表。 -
image: nginx:1.15.4
:將容器使用的 nginx 鏡像版本指定為1.15.4
。 -
imagePullPolicy: IfNotPresent
:設置容器的鏡像拉取策略為IfNotPresent
,即如果本地不存在該鏡像版本才會拉取。 -
name: nginx
:容器的名稱為nginx
。 -
ports
:定義了容器監聽的端口。-
containerPort: 80
:容器監聽的端口號為80
。 -
protocol: TCP
:端口協議為TCP
。
-
-
resources: {}
:未指定容器的資源限制。 -
terminationMessagePath
和terminationMessagePolicy
:配置了容器終止時的消息路徑和策略。 -
dnsPolicy: ClusterFirst
:指定了 Pod 的 DNS 策略為ClusterFirst
。 -
restartPolicy: Always
:設置 Pod 的重啟策略為Always
,即當 Pod 終止時,始終嘗試重啟。 -
schedulerName: default-scheduler
:使用默認的調度器。 -
securityContext: {}
:未指定安全上下文。 -
terminationGracePeriodSeconds: 30
:定義了 Pod 終止的寬限期為30
秒。
-
測試示例
//創建測試案例
mkdir /opt/demo
cd /opt/demovim pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-test1
spec:containers:- name: nginximage: nginximagePullPolicy: Alwayscommand: [ "echo", "SUCCESS" ]kubectl create -f pod1.yamlkubectl get pods -o wide
pod-test1 0/1 CrashLoopBackOff 4 3m33s
//此時 Pod 的狀態異常,原因是 echo 執行完進程終止,容器生命周期也就結束了kubectl describe pod pod-test1//可以發現 Pod 中的容器在生命周期結束后,由于 Pod 的重啟策略為 Always,容器再次重啟了,并且又重新開始拉取鏡像//修改 pod1.yaml 文件
cd /opt/demo
vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-test1
spec:containers:- name: nginximage: nginx:1.14 #修改 nginx 鏡像版本imagePullPolicy: Always#command: [ "echo", "SUCCESS" ] #刪除//刪除原有的資源
kubectl delete -f pod1.yaml //更新資源
kubectl apply -f pod1.yaml //查看 Pod 狀態
kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE
pod-test1 1/1 Running 0 33s 172.17.36.4 192.168.41.31 <none>//在任意 node 節點上使用 curl 查看頭部信息
curl -I http://172.17.36.4
HTTP/1.1 200 OK
Server: nginx/1.14.2
......
這個示例提供了針對一個Kubernetes Pod的測試案例的步驟和結果。首先,創建了一個Pod,其中包含一個NGINX容器,但是容器的命令會導致進程終止,從而進入CrashLoopBackOff狀態。然后,通過查看Pod的描述,可以觀察到容器在重啟,并且重新拉取鏡像。接下來,修改了Pod的配置文件,將NGINX鏡像版本更新為1.14,并刪除了原有的命令。隨后,刪除了原有的資源并應用了更新后的配置文件。最后,檢查了Pod的狀態,并通過在任意節點上使用curl驗證了NGINX服務器是否運行正常
pod 容器重啟策略
重啟策略是Kubernetes中用于定義Pod中容器的重新啟動行為的設置。
重啟策略的三種格式
-
Always(總是):當容器終止時,無論是正常還是異常退出,都會被重新啟動。
-
OnFailure(失敗時):只有當容器異常退出(退出狀態碼非0)時,才會觸發重新啟動;正常退出(退出狀態碼為0)時則不會重新啟動。
-
Never(從不):不會自動重新啟動容器,無論退出原因。
這策略可在Pod的配置中設置,如前述的 restartPolicy: Always
,以控制容器的生命周期行為。
kubectl edit deployment nginx-deployment
......restartPolicy: Always
這段命令是通過編輯名為 nginx-deployment 的部署(Deployment)來修改其重啟策略為 Always(總是重啟)。這意味著當該部署中的Pod中的容器終止時,無論是正常退出還是異常退出,Kubernetes都會自動重新啟動這些容器,以確保服務的可用性。
示例
vim pod2.yaml
apiVersion: v1
kind: Pod
metadata:name: foo
spec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 30; exit 3kubectl apply -f pod3.yaml//查看Pod狀態,等容器啟動后30秒后執行exit退出進程進入error狀態,就會重啟次數加1
kubectl get pods
NAME READY STATUS RESTARTS AGE
foo 1/1 Running 1 50skubectl delete -f pod3.yamlvim pod3.yaml
apiVersion: v1
kind: Pod
metadata:name: foo
spec:containers:- name: busyboximage: busyboxargs:- /bin/sh- -c- sleep 30; exit 3restartPolicy: Never
#注意:跟container同一個級別kubectl apply -f pod3.yaml//容器進入error狀態不會進行重啟
kubectl get pods -w
在這個示例中,首先創建了一個名為 foo 的Pod,其中包含一個busybox容器,其命令是睡眠30秒然后退出進程,導致容器進入錯誤狀態,觸發一次重啟。然后,刪除了原有的Pod并修改了Pod的配置文件,將重啟策略修改為Never(從不重啟)。接著,重新應用了更新后的Pod配置文件。在這種情況下,即使容器進入錯誤狀態,由于重啟策略已設置為Never,Kubernetes也不會自動重新啟動該容器。
pod狀態
-
Pending:Pod 已被系統接受,但容器尚未創建。這可能是因為調度到節點上的時間或下載鏡像的時間。持續一段時間。
-
Running:Pod 已與節點綁定,其中至少一個容器正在運行或啟動中。需要進一步檢查容器狀態,因為 Pod 雖然運行,但容器不一定完全可用。
-
Succeeded:很少見的狀態,表示 Pod 中的所有容器已成功終止,并且不會重新啟動。
-
Failed:所有容器都已非正常終止,至少一個容器返回了非零退出碼或被系統直接終止。
-
Unknown:由于通信問題等原因,無法獲取 Pod 的狀態。通常情況下,最常見的是前兩種狀態
Container生命周期
-
Waiting:在啟動和運行之間的等待狀態,可能有等待依賴或資源。
-
Running:容器正在運行狀態,正常運行中。
-
Terminated:容器已終止狀態。如果長時間處于等待狀態,會有一個
reason
字段指示其狀態和原因。若原因(如ContainerCannotRun)表明容器無法啟動,整個服務啟動會迅速返回。這是一種失敗狀態返回的特性。