# Pod 的生命周期
## Pod phase
Pod 的 `status` 字段是一個 PodStatus 對象,PodStatus中有一個 `phase` 字段。
Pod 的相位(phase)是 Pod 在其生命周期中的簡單宏觀概述。該階段并不是對容器或 Pod 的綜合匯總,也不是為了做為綜合狀態機。
Pod 相位的數量和含義是嚴格指定的。除了本文檔中列舉的狀態外,不應該再假定 Pod 有其他的 `phase` 值。
下面是 `phase` 可能的值:
- 掛起(Pending):Pod 已被 Kubernetes 系統接受,但有一個或者多個容器鏡像尚未創建。等待時間包括調度 Pod 的時間和通過網絡下載鏡像的時間,這可能需要花點時間。
- 運行中(Running):該 Pod 已經綁定到了一個節點上,Pod 中所有的容器都已被創建。至少有一個容器正在運行,或者正處于啟動或重啟狀態。
- 成功(Succeeded):Pod 中的所有容器都被成功終止,并且不會再重啟。
- 失敗(Failed):Pod 中的所有容器都已終止了,并且至少有一個容器是因為失敗終止。也就是說,容器以非0狀態退出或者被系統終止。
- 未知(Unknown):因為某些原因無法取得 Pod 的狀態,通常是因為與 Pod 所在主機通信失敗。
下圖是Pod的生命周期示意圖,從圖中可以看到Pod狀態的變化。

## Pod 狀態
Pod 有一個 PodStatus 對象,其中包含一個 PodCondition 數組。 PodCondition 數組的每個元素都有一個 `type` 字段和一個 `status` 字段。`type` 字段是字符串,可能的值有 PodScheduled、Ready、Initialized、Unschedulable和ContainersReady。`status` 字段是一個字符串,可能的值有 True、False 和 Unknown。
## 容器探針
探針是由 [kubelet](https://kubernetes.io/docs/admin/kubelet/) 對容器執行的定期診斷。要執行診斷,kubelet 調用由容器實現的 [Handler](https://godoc.org/k8s.io/kubernetes/pkg/api/v1#Handler)。有三種類型的處理程序:
- ExecAction:在容器內執行指定命令。如果命令退出時返回碼為 0 則認為診斷成功。
- TCPSocketAction:對指定端口上的容器的 IP 地址進行 TCP 檢查。如果端口打開,則診斷被認為是成功的。
- HTTPGetAction:對指定的端口和路徑上的容器的 IP 地址執行 HTTP Get 請求。如果響應的狀態碼大于等于200 且小于 400,則診斷被認為是成功的。
每次探測都將獲得以下三種結果之一:
- 成功:容器通過了診斷。
- 失敗:容器未通過診斷。
- 未知:診斷失敗,因此不會采取任何行動。
Kubelet 可以選擇是否執行在容器上運行的兩種探針執行和做出反應:
- `livenessProbe`:指示容器是否正在運行。如果存活探測失敗,則 kubelet 會殺死容器,并且容器將受到其 [重啟策略](https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#restart-policy) 的影響。如果容器不提供存活探針,則默認狀態為 `Success`。
- `readinessProbe`:指示容器是否準備好服務請求。如果就緒探測失敗,端點控制器將從與 Pod 匹配的所有 Service 的端點中刪除該 Pod 的 IP 地址。初始延遲之前的就緒狀態默認為 `Failure`。如果容器不提供就緒探針,則默認狀態為 `Success`。
### 該什么時候使用存活(liveness)和就緒(readiness)探針?
如果容器中的進程能夠在遇到問題或不健康的情況下自行崩潰,則不一定需要存活探針; kubelet 將根據 Pod 的`restartPolicy` 自動執行正確的操作。
如果您希望容器在探測失敗時被殺死并重新啟動,那么請指定一個存活探針,并指定`restartPolicy` 為 Always 或 OnFailure。
如果要僅在探測成功時才開始向 Pod 發送流量,請指定就緒探針。在這種情況下,就緒探針可能與存活探針相同,但是 spec 中的就緒探針的存在意味著 Pod 將在沒有接收到任何流量的情況下啟動,并且只有在探針探測成功后才開始接收流量。
如果您希望容器能夠自行維護,您可以指定一個就緒探針,該探針檢查與存活探針不同的端點。
請注意,如果您只想在 Pod 被刪除時能夠排除請求,則不一定需要使用就緒探針;在刪除 Pod 時,Pod 會自動將自身置于未完成狀態,無論就緒探針是否存在。當等待 Pod 中的容器停止時,Pod 仍處于未完成狀態。
## Pod 和容器狀態
有關 Pod 容器狀態的詳細信息,請參閱 PodStatus 和 ContainerStatus。請注意,報告的 Pod 狀態信息取決于當前的 ContainerState。
## 重啟策略
PodSpec 中有一個 `restartPolicy` 字段,可能的值為 Always、OnFailure 和 Never。默認為 Always。 `restartPolicy` 適用于 Pod 中的所有容器。`restartPolicy` 僅指通過同一節點上的 kubelet 重新啟動容器。失敗的容器由 kubelet 以五分鐘為上限的指數退避延遲(10秒,20秒,40秒...)重新啟動,并在成功執行十分鐘后重置。如 [Pod 文檔](https://kubernetes.io/docs/user-guide/pods/#durability-of-pods-or-lack-thereof) 中所述,一旦綁定到一個節點,Pod 將永遠不會重新綁定到另一個節點。
## Pod 的生命
一般來說,Pod 不會消失,直到人為銷毀他們。這可能是一個人或控制器。這個規則的唯一例外是成功或失敗的 `phase` 超過一段時間(由 master 確定)的Pod將過期并被自動銷毀。
有三種可用的控制器:
- 使用 [Job](https://kubernetes.io/docs/concepts/jobs/run-to-completion-finite-workloads/) 運行預期會終止的 Pod,例如批量計算。Job 僅適用于重啟策略為 `OnFailure` 或 `Never` 的 Pod。
- 對預期不會終止的 Pod 使用 [ReplicationController](https://kubernetes.io/docs/concepts/workloads/controllers/replicationcontroller/)、[ReplicaSet](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/) 和 [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) ,例如 Web 服務器。 ReplicationController 僅適用于具有 `restartPolicy` 為 Always 的 Pod。
- 提供特定于機器的系統服務,使用 [DaemonSet](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/) 為每臺機器運行一個 Pod 。
所有這三種類型的控制器都包含一個 PodTemplate。建議創建適當的控制器,讓它們來創建 Pod,而不是直接自己創建 Pod。這是因為單獨的 Pod 在機器故障的情況下沒有辦法自動復原,而控制器卻可以。
如果節點死亡或與集群的其余部分斷開連接,則 Kubernetes 將應用一個策略將丟失節點上的所有 Pod 的 `phase` 設置為 Failed。
## 示例
### 高級 liveness 探針示例
存活探針由 kubelet 來執行,因此所有的請求都在 kubelet 的網絡命名空間中進行。
```yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-http
spec:
containers:
- args:
- /server
image: k8s.gcr.io/liveness
livenessProbe:
httpGet:
# when "host" is not defined, "PodIP" will be used
# host: my-host
# when "scheme" is not defined, "HTTP" scheme will be used. Only "HTTP" and "HTTPS" are allowed
# scheme: HTTPS
path: /healthz
port: 8080
httpHeaders:
- name: X-Custom-Header
value: Awesome
initialDelaySeconds: 15
timeoutSeconds: 1
name: liveness
```
### 狀態示例
- Pod 中只有一個容器并且正在運行。容器成功退出。
- 記錄完成事件。
- 如果 `restartPolicy` 為:
- Always:重啟容器;Pod `phase` 仍為 Running。
- OnFailure:Pod `phase` 變成 Succeeded。
- Never:Pod `phase` 變成 Succeeded。
- Pod 中只有一個容器并且正在運行。容器退出失敗。
- 記錄失敗事件。
- 如果 `restartPolicy` 為:
- Always:重啟容器;Pod `phase` 仍為 Running。
- OnFailure:重啟容器;Pod `phase` 仍為 Running。
- Never:Pod `phase` 變成 Failed。
- Pod 中有兩個容器并且正在運行。容器1退出失敗。
- 記錄失敗事件。
- 如果 restartPolicy 為:
- Always:重啟容器;Pod `phase` 仍為 Running。
- OnFailure:重啟容器;Pod `phase` 仍為 Running。
- Never:不重啟容器;Pod `phase` 仍為 Running。
- 如果有容器1沒有處于運行狀態,并且容器2退出:
- 記錄失敗事件。
- 如果 `restartPolicy` 為:
- Always:重啟容器;Pod `phase` 仍為 Running。
- OnFailure:重啟容器;Pod `phase` 仍為 Running。
- Never:Pod `phase` 變成 Failed。
- Pod 中只有一個容器并處于運行狀態。容器運行時內存超出限制:
- 容器以失敗狀態終止。
- 記錄 OOM 事件。
- 如果 `restartPolicy` 為:
- Always:重啟容器;Pod `phase` 仍為 Running。
- OnFailure:重啟容器;Pod `phase` 仍為 Running。
- Never: 記錄失敗事件;Pod `phase` 仍為 Failed。
- Pod 正在運行,磁盤故障:
- 殺掉所有容器。
- 記錄適當事件。
- Pod `phase` 變成 Failed。
- 如果使用控制器來運行,Pod 將在別處重建。
- Pod 正在運行,其節點被分段。
- 節點控制器等待直到超時。
- 節點控制器將 Pod `phase` 設置為 Failed。
- 如果是用控制器來運行,Pod 將在別處重建。
原文地址:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/
翻譯:[rootsongjc](https://github.com/rootsongjc)
- 序言
- 云原生
- 云原生(Cloud Native)的定義
- CNCF - 云原生計算基金會簡介
- CNCF章程
- 云原生的設計哲學
- Play with Kubernetes
- 快速部署一個云原生本地實驗環境
- Kubernetes與云原生應用概覽
- 云原生應用之路——從Kubernetes到Cloud Native
- 云原生編程語言
- 云原生編程語言Ballerina
- 云原生編程語言Pulumi
- 云原生的未來
- Kubernetes架構
- 設計理念
- Etcd解析
- 開放接口
- CRI - Container Runtime Interface(容器運行時接口)
- CNI - Container Network Interface(容器網絡接口)
- CSI - Container Storage Interface(容器存儲接口)
- Kubernetes中的網絡
- Kubernetes中的網絡解析——以flannel為例
- Kubernetes中的網絡解析——以calico為例
- 具備API感知的網絡和安全性管理開源軟件Cilium
- Cilium架構設計與概念解析
- 資源對象與基本概念解析
- Pod狀態與生命周期管理
- Pod概覽
- Pod解析
- Init容器
- Pause容器
- Pod安全策略
- Pod的生命周期
- Pod Hook
- Pod Preset
- Pod中斷與PDB(Pod中斷預算)
- 集群資源管理
- Node
- Namespace
- Label
- Annotation
- Taint和Toleration(污點和容忍)
- 垃圾收集
- 控制器
- Deployment
- StatefulSet
- DaemonSet
- ReplicationController和ReplicaSet
- Job
- CronJob
- Horizontal Pod Autoscaling
- 自定義指標HPA
- 準入控制器(Admission Controller)
- 服務發現
- Service
- Ingress
- Traefik Ingress Controller
- 身份與權限控制
- ServiceAccount
- RBAC——基于角色的訪問控制
- NetworkPolicy
- 存儲
- Secret
- ConfigMap
- ConfigMap的熱更新
- Volume
- Persistent Volume(持久化卷)
- Storage Class
- 本地持久化存儲
- 集群擴展
- 使用自定義資源擴展API
- 使用CRD擴展Kubernetes API
- Aggregated API Server
- APIService
- Service Catalog
- 資源調度
- QoS(服務質量等級)
- 用戶指南
- 資源對象配置
- 配置Pod的liveness和readiness探針
- 配置Pod的Service Account
- Secret配置
- 管理namespace中的資源配額
- 命令使用
- Docker用戶過度到kubectl命令行指南
- kubectl命令概覽
- kubectl命令技巧大全
- 使用etcdctl訪問kubernetes數據
- 集群安全性管理
- 管理集群中的TLS
- kubelet的認證授權
- TLS bootstrap
- 創建用戶認證授權的kubeconfig文件
- IP偽裝代理
- 使用kubeconfig或token進行用戶身份認證
- Kubernetes中的用戶與身份認證授權
- Kubernetes集群安全性配置最佳實踐
- 訪問Kubernetes集群
- 訪問集群
- 使用kubeconfig文件配置跨集群認證
- 通過端口轉發訪問集群中的應用程序
- 使用service訪問群集中的應用程序
- 從外部訪問Kubernetes中的Pod
- Cabin - Kubernetes手機客戶端
- Kubernetic - Kubernetes桌面客戶端
- Kubernator - 更底層的Kubernetes UI
- 在Kubernetes中開發部署應用
- 適用于kubernetes的應用開發部署流程
- 遷移傳統應用到Kubernetes中——以Hadoop YARN為例
- 最佳實踐概覽
- 在CentOS上部署Kubernetes集群
- 創建TLS證書和秘鑰
- 創建kubeconfig文件
- 創建高可用etcd集群
- 安裝kubectl命令行工具
- 部署master節點
- 安裝flannel網絡插件
- 部署node節點
- 安裝kubedns插件
- 安裝dashboard插件
- 安裝heapster插件
- 安裝EFK插件
- 生產級的Kubernetes簡化管理工具kubeadm
- 使用kubeadm在Ubuntu Server 16.04上快速構建測試集群
- 服務發現與負載均衡
- 安裝Traefik ingress
- 分布式負載測試
- 網絡和集群性能測試
- 邊緣節點配置
- 安裝Nginx ingress
- 安裝配置DNS
- 安裝配置Kube-dns
- 安裝配置CoreDNS
- 運維管理
- Master節點高可用
- 服務滾動升級
- 應用日志收集
- 配置最佳實踐
- 集群及應用監控
- 數據持久化問題
- 管理容器的計算資源
- 集群聯邦
- 存儲管理
- GlusterFS
- 使用GlusterFS做持久化存儲
- 使用Heketi作為Kubernetes的持久存儲GlusterFS的external provisioner
- 在OpenShift中使用GlusterFS做持久化存儲
- GlusterD-2.0
- Ceph
- 用Helm托管安裝Ceph集群并提供后端存儲
- 使用Ceph做持久化存儲
- 使用rbd-provisioner提供rbd持久化存儲
- OpenEBS
- 使用OpenEBS做持久化存儲
- Rook
- NFS
- 利用NFS動態提供Kubernetes后端存儲卷
- 集群與應用監控
- Heapster
- 使用Heapster獲取集群和對象的metric數據
- Prometheus
- 使用Prometheus監控kubernetes集群
- Prometheus查詢語言PromQL使用說明
- 使用Vistio監控Istio服務網格中的流量
- 分布式跟蹤
- OpenTracing
- 服務編排管理
- 使用Helm管理Kubernetes應用
- 構建私有Chart倉庫
- 持續集成與發布
- 使用Jenkins進行持續集成與發布
- 使用Drone進行持續集成與發布
- 更新與升級
- 手動升級Kubernetes集群
- 升級dashboard
- 領域應用概覽
- 微服務架構
- 微服務中的服務發現
- 使用Java構建微服務并發布到Kubernetes平臺
- Spring Boot快速開始指南
- Service Mesh 服務網格
- 企業級服務網格架構
- Service Mesh基礎
- Service Mesh技術對比
- 采納和演進
- 定制和集成
- 總結
- Istio
- 安裝并試用Istio service mesh
- 配置請求的路由規則
- 安裝和拓展Istio service mesh
- 集成虛擬機
- Istio中sidecar的注入規范及示例
- 如何參與Istio社區及注意事項
- Istio教程
- Istio免費學習資源匯總
- 深入理解Istio Service Mesh中的Envoy Sidecar注入與流量劫持
- 深入理解Istio Service Mesh中的Envoy Sidecar代理的路由轉發
- Linkerd
- Linkerd 使用指南
- Conduit
- Condiut概覽
- 安裝Conduit
- Envoy
- Envoy的架構與基本術語
- Envoy作為前端代理
- Envoy mesh教程
- SOFAMesh
- SOFAMesh中的Dubbo on x-protocol
- SOFAMosn
- 使用 SOFAMosn 構建 SOFAMesh
- 大數據
- Spark standalone on Kubernetes
- 運行支持Kubernetes原生調度的Spark程序
- Serverless架構
- 理解Serverless
- FaaS-函數即服務
- OpenFaaS快速入門指南
- 邊緣計算
- 人工智能