kubernetes之pod生命周期

参考:https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/

Pod phase

系统中表示pod的条目包含一个表示pod状态的字段,称为“status”。“status”字段本身是一个“PodStatus”类型的对象,其中包含一个“phase”字段,用来表示pod当前所处的生命周期状态。以下是“phase”可能的取值:

Value Description
Pending 系统已经接受pod实例的创建,但其中所包含容器的一个或者多个image还没有创建成功。Pending包含调度计算与通过网络创建image,所以此phase的时间可能会有点长。
Running Pod已经被调度到某个node上,pod包含的所有容器已经创建完成,至少有一个容器正常运行或者处于启动与重启动过程。
Succeeded Pod中的所有容器正常终止,并且不会再次启动。
Failed Pod中所有容器已终止运行,至少有一个容器非正常结束,比如退出码非零,被系统强制杀死等。
Unknow 无法取得pod状态,一般是网络问题引起。

由以上可知,phase表示的pod状态非常粗略与宽泛。

Pod conditions

PodStatus还包含PodConditions字段,此字段表示pod更详细的状态信息,PodConditions是一个数组,数据中的每个成员包含如下六个字段:

  • lastProbeTime:表示PodConditions最后一次被探测的时间戳。
  • latTransitionTime:表示PodConditions​​​​​​​中“status”字段最后一次发生变更的时间戳。
  • message:人可读的最后一次“status”变更的原因
  • reason:表示最后一次“status”变更原因的标识,不可读。
  • status:表示pod状态,可能的值“True”、“False”、“Unknow”。

最后一个字段“type”,有如下五种可能取值:

  • PodScheduled:Pod已经被高度到某个node。
  • Ready:Pod已经可以接受请求对外提供服务,此时pod可以被加入到相应service的endpoint中。
  • Initialized:所有初始化容器已经成功启动。
  • Unschedulable:Pod无法被调度。
  • ContainersReady:Pod中所有容器的状态处于“ready”状态。

Container probes 

“探针”是指由kubelet周期性调用的处理程序,实现对容器状态的诊断,探针处理程序的实现有以下三种方式:

  • ExecAction:在容器内执行的特殊命令,如果退出码为0,则表示容器健康。
  • TCPSocketAction:检测容器某个端口,如果端口打开则认为正常。
  • HTTPGetAction:向容器的某个路径发起HTTP GET请求,如果返回应答状态码大于等于200小于400则认为正常。

探针的返回结果有以下三种:

  • Succees:表示容器通过诊断。
  • Failed:表示容器没有通过诊断。
  • Unknown:诊断本身失败,所以对容器的诊断结果未知。

以上是探针处理程序的三种实现方式,从kubernetes对探针结果的操作与反应看,探针分成两类:

  • livenessProbe:表示容器是否正在运行。如果这种类型的探针诊断失败,则 kubelet杀死容器,然后根据restart policy决定后续处理。如果没有提供此种类型的探针则默认诊断成功。
  • readinessProbe:指示容器是否能处理请求。如果失败,则将此容器的endpoint从所有包含此endpoint的service中删除。当容器处于启动时的初始化阶段时,此探针的诊断结果为Succees,如果没有提供此类探针,默认诊断结果为Success。

由以上可知,探针由kubelet执行,其结果影响kubelet对容器执行何种操作。

When should you use liveness or readiness probes?

如果容器中运行的程序能够健康自检,当发生问题时程序主动退出、销毁,这种情况无需使用livenessProbe,kubelet能根据restart policy正确处理。如果程序不具备自检功能,那么可以通过livenessProbe检测程序状态,当失败时kubelet杀死容器。同样kubelet根据restart policy决定后续处理。比如restart policy设置成"Always"或者"OnFailure",则重新启动容器。只是重启,并没有试图去修复问题。

如果打算在某项条件具备之前,不允许pod处理请求,则可以使用readinessProbe。readinessProbe失败并不会像livenessProbe一样删除容器,只是阻止容器处理外部发过来的请求。当readinessProbe成功后,容器就可以正常对外提供服务了。

当删除pod时,无需通过readinessProbe实现drain操作。当删除pod时,pod会进入"unready"状态,不管有没有readinessProbe,这种状态会一直操持到pod被stop。

有关探针的详细使用方法: Configure Liveness and Readiness Probes

Pod and Container status

Pod状态详细参考:PodStatus​​​​​​​

Container状态详细参考:ContainerState

注意pod状态对container的状态有依赖。

Restart policy

有三种重启策略: Always、OnFailure、Never。Always表示容器无论是正常还是异常退出都重启。Onfailure表示只有在容器异常退出时才重启。Never表示无论容器是正常还是异常退出都不重启。Kubernetes根据算法将重启的时间间隔逐渐拉大,重启成功后重置。单纯从重启策略上看的话,重启策略不关系异常退出原因,也没有也异常修复过程集成,好像没有什么鸟毛的用处。如果容器因为自身原因,比如配置问题启动失败而异常退出,那么重启多少次结果都一样。

Pod lifetime

除非被用户或者某个控制器明确删除,否则pod会一直存在。这条规则的例外情况是处于"Succeeded"或者"Failed"的pod,如果处于此种状态超过一定的时限,比如terminated-pod-gc-threshold的设定值,则会被垃圾回收机制清除。

pod控制器与restart policy的适配:

  • JOB:适用于一次性任务如批量计算,任务结束后pod会被此类控制器清除。JOB的重启策略只能是"OnFailure"或者"Never"。
  • ReplicationController, ReplicaSet, or Deployment,此类控制器希望pod一直运行下去,它们的restart policy只能是"always"。
  • DaemonSet:每个node一个pod,很明显此类控制器的restart policy应该是"always"。

Examples

Advanced liveness probe example

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

探针由kubelet执行,那么执行探针时使用的网络与kubelet占用的网络一样,而容器的属于pod网络,要保证网络的连通性。

Example states

  • Pod包含一个容器,容器正常退出.

    • 日志正常完成事件
    • 如果重启策略是:
      • Always: 重启容器; Pod的phase保持在Running.
      • OnFailure: Pod的phase变成Succeeded.
      • Never: Pod的phase变成Succeeded.
  • 容器异常退出

    • 日志失败事件。
    • 如果restart policy是:
      • Always: 重启容器; Pod的phase保持在Running.
      • OnFailure: 重启容器;Pod的phase保持在Running.
      • Never: 不重启容器,Pod的phase变成Failed.
  • Pod有两个容器,其中一个异常退出:

    • 日志失败事件
    • 如果restart policy是:
      • Always: 重启异常退出容器,pod的phase是Running.
      • OnFailure:重启异常退出容器,pod的phase是Running .
      • Never: 不重启容器,但pod的phase依然是Running.
    • 如果容器1没有运行,容器2异常退出:
      • 日志失败事件
      • 如果restart policy是:
        • Always: 重启异常退出容器,pod的phase是Running.
        • OnFailure: 重启异常退出容器,pod的phase是Running.
        • Never: 不重启容器,但pod的phase变成failed.
  • pod只有一个容器,容器运行时内存溢出:

    • 容器异常退出
    • 日志OOM事件
    • 如果restart policy是:
      • Always: 重启异常退出容器,pod的phase是Running(不修复问题,重启有什么用?).
      • OnFailure: 重启异常退出容器,pod的phase是Running(不修复问题,重启有什么用?).
      • Never: pod的phase变成Failed.
  • pod在运行时磁盘出问题(由谁发现磁盘出问题?):

    • 杀死所有容器
    • 日志相应事件
    • pod的phase变成Failed
    • 如果有相关控制器,则控制器在其它地方创建新实例。
  • pod运行时node离开集群

    • Node controller 联系不上node,node的状态变成unknown。
    • Node controller 将pod的状态设置成Failed。
    • 控制器在其它地方设置副本。

猜你喜欢

转载自blog.csdn.net/dkfajsldfsdfsd/article/details/81075825