Kubernetes in Action 笔记 —— 管理 Pod 的生命周期

理解 Pod 的状态

Pod phase

在 Pod 完整的生命周期中,存在着 5 种不同的阶段:


Pod’s phases
  • Pending:创建 Pod 对象后的初始化阶段。会一直持续到 Pod 被分配给某个工作节点,镜像被拉取到本地并启动
  • Running:Pod 中至少一个容器处于运行状态
  • Succeeded:对于不打算无限期运行的 Pod,其容器部署完成后的状态
  • Failed:对于不打算无限期运行的 Pod,其容器中至少有一个由于错误终止
  • Unknown:由于 Kubelet 与 API Server 的通信中断,Pod 的状态未知。可能是工作节点挂掉或断网

kubia.yml 清单文件创建一个 Pod。

apiVersion: v1
kind: Pod
metadata:
  name: kubia
spec:
  containers:
  - name: kubia
    image: luksa/kubia:1.0
    ports:
    - containerPort: 8080

$ kubectl apply -f kubia.yml

查看 Pod 的 Phase

$ kubectl get po kubia -o yaml | grep phase
  phase: Running

或者借助 jq 工具从 JSON 格式的输出中检索 phase 字段:

$ kubectl get po kubia -o json | jq .status.phase
"Running"

也可以使用 kubectl describe 命令:

$ kubectl describe po kubia | grep Status:
Status:       Running
Pod conditions

Pod 的 conditions 用来表示某个 Pod 是否达到了特定的状态以及达到或未达到的原因。
与 phase 相反,一个 Pod 可以同时有几个 conditions。

  • PodScheduled:表明 Pod 是否已经被安排给了某个工作节点
  • Initialized:Pod 的初始化容器已经部署完成
  • ContainersReady:Pod 中的所有容器都已经准备完毕
  • Ready:Pod 自身已经准备好对其客户端提供服务

查看 Pod 的 conditions

$ kubectl describe po kubia | grep Conditions: -A5
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

kubectl describe 命令只会显示每个 condition 是 true 还是 false,不会显示更详细的信息。
为了显示某个 condition 为 false 的具体原因,需要检索 Pod 的清单文件:

$ kubectl get po kubia -o json | jq .status.conditions
[
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2021-12-30T03:02:45Z",
    "status": "True",
    "type": "Initialized"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2021-12-30T03:02:46Z",
    "status": "True",
    "type": "Ready"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2021-12-30T03:02:46Z",
    "status": "True",
    "type": "ContainersReady"
  },
  {
    "lastProbeTime": null,
    "lastTransitionTime": "2021-12-30T03:02:45Z",
    "status": "True",
    "type": "PodScheduled"
  }
]

当 condition 为 false 时,上述输出中会包含 reasonmessage 字段来显示失败的具体原因和详细信息。

容器的 status

容器的 status 包含多个字段。其中 state 字段表示该容器当前的状态,restartCount 表示容器重启的频率,此外还有 containerIDimageimageID 等。

Container status

容器的 status 包含以下几种:

  • Waiting:容器等待启动。reasonmessage 字段会记录容器处于此状态的原因
  • Running:容器已经创建,进程正在运行
  • Terminated:容器中运行的进程已经终止。exitCode 字段会记录进程的退出码
  • Unknown:容器的状态无法确定

比如修改 kubia.yml 清单文件中的 image 字段,故意改成 uksa/kubia:1.0 这样无效的地址,运行 kubectl apply -f kubia.yml 命令重新应用清单文件。
等待几分钟直到新的配置生效,查看容器的状态。

可以使用 kubectl describe 命令查看容器的状态:

$ kubectl describe po kubia | grep Containers: -A15
Containers:
  kubia:
    Container ID:   docker://62fa208957d396c38f65305fd073d6b334dd8da22ab5beab196ca9bcf2f9ff91
    Image:          uksa/kubia:1.0
    Image ID:       docker-pullable://luksa/kubia@sha256:a961dc8f377916936fa963508726d77cf77dcead5c97de7e5361f0875ba3bef7
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Waiting
      Reason:       ImagePullBackOff
    Last State:     Terminated
      Reason:       Error
      Exit Code:    137
      Started:      Fri, 31 Dec 2021 14:50:39 +0800
      Finished:     Fri, 31 Dec 2021 14:51:36 +0800
    Ready:          False
    Restart Count:  0

或者使用 kubectl get po kubia -o json 命令:

$ kubectl get po kubia -o json | jq .status.containerStatuses
[
  {
    "containerID": "docker://62fa208957d396c38f65305fd073d6b334dd8da22ab5beab196ca9bcf2f9ff91",
    "image": "luksa/kubia:1.0",
    "imageID": "docker-pullable://luksa/kubia@sha256:a961dc8f377916936fa963508726d77cf77dcead5c97de7e5361f0875ba3bef7",
    "lastState": {
      "terminated": {
        "containerID": "docker://62fa208957d396c38f65305fd073d6b334dd8da22ab5beab196ca9bcf2f9ff91",
        "exitCode": 137,
        "finishedAt": "2021-12-31T06:51:36Z",
        "reason": "Error",
        "startedAt": "2021-12-31T06:50:39Z"
      }
    },
    "name": "kubia",
    "ready": false,
    "restartCount": 0,
    "started": false,
    "state": {
      "waiting": {
        "message": "Back-off pulling image \"uksa/kubia:1.0\"",
        "reason": "ImagePullBackOff"
      }
    }
  }
]

上面输出中的 state 字段都表明了容器当前的状态是 waiting,还有 reasonmessage 字段表明处于此状态的原因:镜像拉取失败。

确保容器的健康状态

理解容器的自动重启机制

当一个 Pod 被分配给了某个工作节点,该工作节点上的 Kubelet 就会负责启动容器并保证该容器一直处于运行状态,只要该 Pod 对象一直存在没被移除。
如果容器中的主进程由于某些原因终止运行,Kubernetes 就会自动重启该容器。

创建如下内容的清单文件 kubia-ssl.yml

apiVersion: v1
kind: Pod
metadata:
  name: kubia-ssl
spec:
  containers:
  - name: kubia
    image: luksa/kubia:1.0
    ports:
    - name: http
      containerPort: 8080
  - name: envoy
    image: luksa/kubia-ssl-proxy:1.0
    ports:
    - name: https
      containerPort: 8443
    - name: admin
      containerPort: 9901

运行如下命令应用上述清单文件,并启用端口转发:

$ kubectl apply -f kubia-ssl.yml
pod/kubia-ssl created
$ kubectl port-forward kubia-ssl 8080 8443 9901
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Forwarding from 127.0.0.1:8443 -> 8443
Forwarding from [::1]:8443 -> 8443
Forwarding from 127.0.0.1:9901 -> 9901
Forwarding from [::1]:9901 -> 9901

待容器启动成功后,访问 localhost 的 8080、8443、9901 端口就等同于访问容器中 8080、8443、9901 端口上运行的服务。

打开一个新的命令行窗口运行 kubectl get pods -w 命令,实时监控容器的运行状态。
打开一个新的命令行窗口运行 kubectl get events -w 命令,实时监控触发的事件。

打开一个新的命令行窗口,尝试终止 Envoy 容器中运行的主进程。Envoy 容器 9901 端口上运行的服务刚好提供了一个管理接口,能够接收 HTTP POST 请求来终止进程:

$ curl -X POST http://localhost:9901/quitquitquit
OK

此时查看前两个窗口中的输出,负责监控容器状态的窗口输出如下:

$ kubectl get pods -w
NAME        READY   STATUS    RESTARTS   AGE
kubia-ssl   2/2     Running   0          11m
kubia-ssl   1/2     NotReady   0          12m
kubia-ssl   2/2     Running    1 (2s ago)   12m

最新的输出表明,在杀掉 Envoy 容器中的主进程后,Pod 的状态是先变成 NotReady,之后就立即重启该容器,Pod 的状态稍后恢复成 Running

负责监控最新事件的窗口输出如下:

$ kubectl get events -w
LAST SEEN   TYPE     REASON      OBJECT          MESSAGE
11m         Normal   Scheduled   pod/kubia-ssl   Successfully assigned default/kubia-ssl to minikube
11m         Normal   Pulled      pod/kubia-ssl   Container image "luksa/kubia:1.0" already present on machine
11m         Normal   Created     pod/kubia-ssl   Created container kubia
11m         Normal   Started     pod/kubia-ssl   Started container kubia
11m         Normal   Pulled      pod/kubia-ssl   Container image "luksa/kubia-ssl-proxy:1.0" already present on machine
11m         Normal   Created     pod/kubia-ssl   Created container envoy
11m         Normal   Started     pod/kubia-ssl   Started container envoy
0s          Normal   Pulled      pod/kubia-ssl   Container image "luksa/kubia-ssl-proxy:1.0" already present on machine
0s          Normal   Created     pod/kubia-ssl   Created container envoy
0s          Normal   Started     pod/kubia-ssl   Started container envoy

最新的事件信息中包含了新的 envoy 容器启动的过程。其中有一个很重要的细节:Kubernetes 从来不会重启容器,而是直接丢弃停止的容器并创建一个新的。一般在 Kubernetes 中提及“重启”容器,实质上都指的是“重建”。
任何写入到容器文件系统中的数据,在容器重新创建后都会丢失。为了持久化这些数据,需要向 Pod 添加 Volume

配置容器的重启策略
Kubernetes 支持 3 种容器重启策略:

  • Always:默认配置。不管容器中主进程的退出码是多少,容器都会自动重启
  • OnFailure:容器只会在退出码非 0 时重启
  • Never:容器永不重启
Restart policy

容器重启时的延迟时间
第一次容器终止时,重启会立即触发。但容器第二次重启时会先等待 10s,这个等待时间会随着重启次数依次增加到 20、40、80、160s。再之后则一直保持在 5 分钟。
等待过程中容器会处于 Waiting 状态,reason 字段显示 CrashLoopBackOffmessage 字段显示需要等待的时间。

liveness probes

Kubernetes 会在容器的进程终止时重启容器,以保证应用的健康。但应用实际上有可能在进程不终止的情况下无响应,比如一个 Java 应用报出 OutOfMemoryError 错误,而 JVM 进程仍在运行中。
理想情况下,Kubernetes 需要能够检测到此类错误并重启容器。

当然,应用自身也可以捕获这类错误并令进程立即终止。但假如应用因为进入无限循环或死锁导致无响应,又或者应用本身无法检测到错误存在呢?
为了确保容器能够在这些复杂情况下重启,应该提供一种从外部检查应用状态的机制。

liveness probe 介绍
Kubernetes 可以通过配置 liveness probe 来检查某个应用是否能够正常响应,Pod 中的每个容器都可以分别配置 liveness probe。一旦应用无响应或有错误发生,容器就会被认为是不健康的并被终止掉。之后容器被 Kubernetes 重新启动。

Kubernetes 支持以下三种 probe 机制:

  • HTTP GET probe:会发送 GET 请求到容器的 IP 地址、端口号和 URL 路径。如果 probe 收到正常的响应(2xx 或 3xx),该 probe 就被认定是成功的。如果服务返回了一个错误的响应码,或者没有在规定的时间内响应,则该 probe 被认定是失败的。
  • TCP Socket probe:会尝试打开一个 TCP 连接到容器的特定端口。若连接成功,probe 就被认定是成功的;否则失败。
  • Exec probe:会在容器内部执行一个命令并检查该命令的退出码。若退出码为 0,则 probe 被认定是成功的;否则失败。

HTTP GET liveness probe
创建如下内容的 kubia-liveness.yml 清单文件:

apiVersion: v1
kind: Pod
metadata:
  name: kubia-liveness
spec:
  containers:
  - name: kubia
    image: luksa/kubia:1.0
    ports:
    - name: http
      containerPort: 8080
    livenessProbe:
      httpGet:
        path: /
        port: 8080
  - name: envoy
    image: luksa/kubia-ssl-proxy:1.0
    ports:
    - name: https
      containerPort: 8443
    - name: admin
      containerPort: 9901
    livenessProbe:
      httpGet:
        path: /ready
        port: admin
      initialDelaySeconds: 10
      periodSeconds: 5
      timeoutSeconds: 2
      failureThreshold: 3

其中 kubia 容器的 liveness probe 是最简单版本的 HTTP 应用的 probe。该 probe 只是向 8080 端口的 / 路径发送 HTTP GET,看容器是否仍然能够处理请求。当应用的响应码介于 200 到 399 之间时,该应用就被认为是健康的。
由于该 probe 没有配置其他选项,默认配置生效。第一次检查请求会在容器启动 10s 后发起,之后每隔 10s 发起新的请求。若应用没有在 1s 之内响应,则该次 probe 请求被认定是失败的。连续 3 次请求失败以后,容器就被认为是不健康的并被终止掉。

Envoy 容器的管理员接口提供了一个 /ready 入口,可以返回其健康状态,因此 envoy 容器的 liveness probe 的目标可以是容器的 admin 端口即 9901。
参数 initialDelaySeconds 表示容器启动后到发起第一个检测请求之间的等待时间,periodSeconds 表示两次连续的检测请求之间的时间间隔,timeoutSeconds 表示多长时间以后没有响应则认定此次检测失败,failureThreshold 则表示连续多少次检测失败以后才认定容器失效并重启。

liveness probe

观察 liveness probe 的效果
运行 kubectl apply 命令应用上述清单文件并通过 kubectl port-forward 命令启用端口转发,启动该 Pod 并令其能够被访问:

$ kubectl apply -f kubia-liveness.yml
pod/kubia-liveness created
$ kubectl port-forward kubia-liveness 8080 8443 9901
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Forwarding from 127.0.0.1:8443 -> 8443
Forwarding from [::1]:8443 -> 8443
Forwarding from 127.0.0.1:9901 -> 9901
Forwarding from [::1]:9901 -> 9901

Pod 启动成功以后,liveness probe 会在初始等待时间过后持续向 Pod 中的容器发起检测请求,其检测结果只会在容器的 log 中看到。
kubia 容器中的 Node.js 应用会在每次处理 HTTP 请求时向标准输出打印记录,这些请求也包括 liveness probe 的检测请求。因此可以打开一个新的命令行窗口,使用如下命令查看请求记录:

$ kubectl logs kubia-liveness -c kubia -f
Kubia server starting...
Local hostname is kubia-liveness
Listening on port 8080
Received request for / from ::ffff:172.17.0.1
Received request for / from ::ffff:172.17.0.1
Received request for / from ::ffff:172.17.0.1
Received request for / from ::ffff:172.17.0.1
Received request for / from ::ffff:172.17.0.1
...

envoy 容器的 liveness probe 被配置成向其管理员接口发送 HTTP 请求,这些请求被记录在 /var/log/envoy.admin.log 文件中。可以使用如下命令查看:

$ kubectl exec kubia-liveness -c envoy -- tail -f /var/log/envoy.admin.log
[2022-01-02T18:34:59.818Z] "GET /ready HTTP/1.1" 200 - 0 5 0 - "172.17.0.1" "kube-probe/1.22" "-" "172.17.0.3:9901" "-"
[2022-01-02T18:35:04.818Z] "GET /ready HTTP/1.1" 200 - 0 5 0 - "172.17.0.1" "kube-probe/1.22" "-" "172.17.0.3:9901" "-"
[2022-01-02T18:35:09.818Z] "GET /ready HTTP/1.1" 200 - 0 5 0 - "172.17.0.1" "kube-probe/1.22" "-" "172.17.0.3:9901" "-"
[2022-01-02T18:35:14.818Z] "GET /ready HTTP/1.1" 200 - 0 5 0 - "172.17.0.1" "kube-probe/1.22" "-" "172.17.0.3:9901" "-"

观察失败的 liveness probe
可以尝试手动令 liveness probe 的检测请求失败。先在一个新的窗口中运行 kubectl get events -w 命令,方便后续观察检测失败时输出的事件信息。
访问 Envoy 容器的管理员接口,手动配置其健康状态为 fail

$ curl -X POST localhost:9901/healthcheck/fail
OK

此时转到观察事件信息的命令行窗口,发现连续输出了 3 次 probe failed 503 错误,之后 envoy 容器开始重启:

kubectl get events -w
LAST SEEN   TYPE      REASON          OBJECT               MESSAGE
...
0s          Warning   Unhealthy       pod/kubia-liveness   Liveness probe failed: HTTP probe failed with statuscode: 503
0s          Warning   Unhealthy       pod/kubia-liveness   Liveness probe failed: HTTP probe failed with statuscode: 503
0s          Warning   Unhealthy       pod/kubia-liveness   Liveness probe failed: HTTP probe failed with statuscode: 503
0s          Normal    Killing         pod/kubia-liveness   Container envoy failed liveness probe, will be restarted
0s          Normal    Pulled          pod/kubia-liveness   Container image "luksa/kubia-ssl-proxy:1.0" already present on machine
0s          Normal    Created         pod/kubia-liveness   Created container envoy
0s          Normal    Started         pod/kubia-liveness   Started container envoy
exec & tcpSocket liveness probe

添加 tcpSocket liveness probe
对于接收非 HTTP 请求的应用,可以配置 tcpSocket liveness probe。
一个 tcpSocket liveness probe 的示例配置如下:

livenessProbe:
  tcpSocket:
    port: 1234
    periodSeconds: 2
    failureThreshold: 1

该 probe 会检查容器的 1234 端口是否打开,每隔 2s 检查一次,一次检查失败则认定该容器是不健康的并重启它。

exec liveness probe
不接受 TCP 连接的应用可以配置一条命令去检测其状态。
下面的示例配置会每隔 2s 运行 /usr/bin/healthcheck 命令,检测容器中的应用是否仍在运行:

livenessProbe:
  exec:
    command:
    - /usr/bin/healthcheck
  periodSeconds: 2
  timeoutSeconds: 1
  failureThreshold: 1
startup probe

默认的 liveness probe 配置会给应用 20 到 30s 的时间启动,如果应用需要更长的时间才能启动完成,容器会永远达不到 liveness probe 检测成功的状态,从而进入了无限重启的循环。
为了防止上述情况发生,可以增大 initialDelaySecondsperiodSecondsfailureThreshold 的值,但也会有一定的副作用。periodSeconds * failureThreshold 的值越大,当应用不健康时重启的时间就越长。

Kubernetes 还提供了一种 startup probe。当容器配置了 startup probe 时,容器启动时只有 startup probe 会执行。startup probe 可以按照应用的启动时间配置,检测成功之后 Kubernetes 会切换到使用 liveness probe 检测。
比如 Node.js 应用需要 1 分钟以上的时间启动,当启动成功以后若应用状态不正常,则在 10s 以内重启。可以这样配置:

containers:
- name: kubia
  image: luksa/kubia:1.0
  ports:
  - name: http
    containerPort: 8080
  startupProbe:
    httpGet:
      path: /
      port: http
    periodSeconds: 10
    failureThreshold: 12
  livenessProbe:
    httpGet:
      path: /
      port: http
    periodSeconds: 5
    failureThreshold: 2

上面配置的效果如下图:


startup probe & liveness probe

应用有 120s 的时间启动。Kubernetes 一开始每隔 10s 发起 startup probe 请求,最多尝试 12 次。
不同于 liveness probe,startup probe 失败是很正常的,只是说明应用还未成功启动。一旦某次 startup probe 检测返回成功状态,Kubernetes 就会立即切换到 liveness probe 模式,通常拥有更短的检测间隔,能够对未响应应用做出更快速的反应。

在容器启动或关闭时触发动作

可以向容器中添加 lifecycle hooks。Kubernetes 目前支持两种类型的钩子:

  • Post-start hooks:在容器启动后执行
  • Pre-stop hooks:在容器停止前执行
Lifecycle hooks
post-start hooks

post-start lifecycle hook 会在容器创建完成之后立即触发。可以使用 exec 类型的钩子在主进程启动的同时执行一个额外的程序,或者 httpGet 类型的钩子向容器中运行的应用发送 HTTP 请求,以完成初始化或预热操作。
假如你是应用的作者,类似的操作当然可以加入到应用本身的代码中。但对于一个已经存在的并非自己创建的应用,就有可能无法做到。post-start hook 提供了一种不需要修改应用或容器镜像的替代方案。

post-start hook 在容器中执行命令

apiVersion: v1
kind: Pod
metadata:
  name: fortune-poststart
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    lifecycle:
      postStart:
        exec:
          command:
          - sh
          - -c
          - "apk add fortune && fortune > /usr/share/nginx/html/quote"
    ports:
    - name: http
      containerPort: 80

上述清单文件定义的 Pod 名为 fortune-poststart,包含一个基于 nginx:alpine 镜像的容器,同时定义了一个 postStart 钩子。该钩子会在 Nginx 服务启动时执行以下命令:
sh -c "apk add fortune && fortune > /usr/share/nginx/html/quote"

postStart 这个名称其实有些误导作用,它并不是在主进程完全启动后才开始执行,而是在容器创建后,几乎和主进程同时执行。

$ kubectl apply -f fortune-poststart.yml
pod/fortune-poststart unchanged
$ kubectl port-forward fortune-poststart 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

打开一个新的命令行窗口使用 curl 命令测试效果:

$ curl localhost:8080/quote
The Official MBA Handbook on business cards:
        Avoid overly pretentious job titles such as "Lord of the Realm,
        Defender of the Faith, Emperor of India" or "Director of Corporate
        Planning."

post-startup hook 对容器的影响
虽然 post-start hook 相对于容器的主进程以异步的方式执行,它还是会对容器产生两个方面的影响。
首先,在 post-start hook 的执行过程中容器会一直处于 Waiting 状态,原因显示为 ContainerCreating,直到 hook 执行完毕。
其次,若 hook 绑定的命令无法执行或返回了一个非零的状态值,则整个容器会被重启。

在容器终止前执行命令

前面 fortune Pod 中的 Nginx 服务在收到 TERM 信号后会立即关闭所有打开的连接并终止进程,这并不是理想的操作,不会等待正在处理的客户端请求彻底完成。
可以使用 pre-stop hook 执行 nginx -s quit 命令舒缓地关闭 Nginx 服务。示例配置如下:

lifecycle:
  preStop:
    exec:
      command:
      - nginx
      - -s
      - quit

假如某个 pre-stop hook 执行失败,只会在 Pod 的 events 消息中显示一条 FailedPreStopHook 警告信息,并不影响容器继续被终止。

理解容器的生命周期

一个 Pod 的生命周期可以被分成如下三个阶段:


Pod 生命周期的三个阶段
  • 初始化阶段:Pod 的 init 容器从开始运行到启动完成
  • 运行阶段:Pod 的普通容器从开始运行到启动完成
  • 终止阶段:Pod 的所有容器被终止运行
初始化阶段

Pod 中的初始化容器会最先运行,按照 specinitContainers 字段中定义的顺序。
第一个初始化容器的镜像被下载到工作节点并启动,完成后继续拉取第二个初始化容器的镜像,直到所有的初始化容器都成功运行。
若某个初始化容器因为某些错误启动失败,且其重启策略设置为 AlwaysOnFailure,则该失败的容器自动重启。若其重启策略设置为 Never,则 Pod 的状态显示为 Init:Error,必须删除并重新创建 Pod 对象。

All init containers must run to completion before the regular containers can start

运行阶段

当所有的初始化容器成功运行后,Pod 的普通容器开始以并行的方式创建(需要注意的是,容器的 post-start hook 会阻塞下一个容器的创建)。

termination grace period
容器中的应用都有一个固定的关闭时间做缓冲用,定义在 spec 下的 terminationGracePeriodSeconds 字段中,默认是 30s。
该时间从 pre-stop hook 触发或收到 TERM 信号时开始计算,若时间过了进程仍在运行,应用会收到 KILL 信号被强制关闭。

container’s termination sequence

终止阶段

Pod 的容器以并行的方式终止。对每个容器来说,pre-stop hook 触发,然后主进程接收 TERM 信号,如果应用关闭的时间超过了 terminationGracePeriodSeconds,就发送 KILL 信号给容器的主进程。
在所有的容器都被终止以后,Pod 对象被删除。

termination sequence inside a pod

可以在删除一个 Pod 时手动指定一个新的时间覆盖 terminationGracePeriodSeconds 的值,如:
kubectl delete po kubia-ssl --grace-period 10

Pod 完整生命周期图示
初始化阶段
运行阶段和终止阶段

参考资料

Kubernetes in Action, Second Edition

你可能感兴趣的:(Kubernetes in Action 笔记 —— 管理 Pod 的生命周期)