前面我们已经了解了 Pod 的设计原理,接下来我们来了解下 Pod 的生命周期。下图展示了一个 Pod 的完整生命周期过程,其中包含 Init Container、Pod Hook、健康检查 三个主要部分,接下来我们就来分别介绍影响 Pod 生命周期的部分:

首先在介绍 Pod 的生命周期之前,我们先了解下 Pod 的状态,因为 Pod 状态可以反应出当前我们的 Pod 的具体状态信息,也是我们分析排错的一个必备的方式。

一、Pod 状态

首先先了解下 Pod 的状态值,我们可以通过 kubectl explain pod.status 命令来了解关于 Pod 状态的一些信息,Pod 的状态定义在 PodStatus 对象中,其中有一个 phase 字段,下面是 phase 的可能取值:

  • 挂起(Pending):Pod 信息已经提交给了集群,但是还没有被调度器调度到合适的节点或者 Pod 里的镜像正在下载
  • 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态
  • 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启
  • 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止
  • 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败导致的

除此之外,PodStatus 对象中还包含一个 PodCondition 的数组,里面包含的属性有:

  • lastProbeTime:最后一次探测 Pod Condition 的时间戳。
  • lastTransitionTime:上次 Condition 从一种状态转换到另一种状态的时间。
  • message:上次 Condition 状态转换的详细描述。
  • reason:Condition 最后一次转换的原因。
  • status:Condition 状态类型,可以为 “True”, “False”, and “Unknown”.
  • type:Condition 类型,包括以下方面:
  • PodScheduled(Pod 已经被调度到其他 node 里)
  • Ready(Pod 能够提供服务请求,可以被添加到所有可匹配服务的负载平衡池中)
  • Initialized(所有的init containers已经启动成功)
  • Unschedulable(调度程序现在无法调度 Pod,例如由于缺乏资源或其他限制)
  • ContainersReady(Pod 里的所有容器都是 ready 状态)

二、重启策略

我们可以通过配置restartPolicy字段来设置 Pod 中所有容器的重启策略,其可能值为Always,OnFailure 和 Never,默认值为 Always。restartPolicy 仅指通过 kubelet 在同一节点上重新启动容器。通过 kubelet 重新启动的退出容器将以指数增加延迟(10s,20s,40s…)重新启动,上限为 5 分钟,并在成功执行 10 分钟后重置。不同类型的的控制器可以控制 Pod 的重启策略:

  • Job:适用于一次性任务如批量计算,任务结束后 Pod 会被此类控制器清除。Job 的重启策略只能是"OnFailure"或者"Never"。
  • Replication Controller, ReplicaSet, or Deployment,此类控制器希望 Pod 一直运行下去,它们的重启策略只能是"Always"。
  • DaemonSet:每个节点上启动一个 Pod,很明显此类控制器的重启策略也应该是"Always"。

三、初始化容器

了解了 Pod 状态后,首先来了解下 Pod 中最新启动的 Init Container,也就是我们平时常说的初始化容器。Init Container就是用来做初始化工作的容器,可以是一个或者多个,如果有多个的话,这些容器会按定义的顺序依次执行。我们知道一个 Pod 里面的所有容器是共享数据卷和Network Namespace 的,所以Init Container里面产生的数据可以被主容器使用到。从上面的 Pod 生命周期的图中可以看出初始化容器是独立与主容器之外的,只有所有的`初始化容器执行完之后,主容器才会被启动。那么初始化容器有哪些应用场景呢:

  • 等待其他模块 Ready:这个可以用来解决服务之间的依赖问题,比如我们有一个 Web 服务,该服务又依赖于另外一个数据库服务,但是在我们启动这个 Web 服务的时候我们并不能保证依赖的这个数据库服务就已经启动起来了,所以可能会出现一段时间内 Web 服务连接数据库异常。要解决这个问题的话我们就可以在 Web 服务的 Pod 中使用一个 InitContainer,在这个初始化容器中去检查数据库是否已经准备好了,准备好了过后初始化容器就结束退出,然后我们主容器的 Web 服务才被启动起来,这个时候去连接数据库就不会有问题了。
  • 做初始化配置:比如集群里检测所有已经存在的成员节点,为主容器准备好集群的配置信息,这样主容器起来后就能用这个配置信息加入集群。
  • 其它场景:如将 Pod 注册到一个中央数据库、配置中心等。

    比如现在我们来实现一个功能,在 Nginx Pod 启动之前去重新初始化首页内容,如下所示的资源清单:(init-pod.yaml)
apiVersion: v1
kind: Pod
metadata:
name: init-demo
spec:
volumes:
- name: workdir
emptyDir: {}
initContainers:
- name: install
image: busybox
command:
- wget
- "-O"
- "/work-dir/index.html"
- http://www.baidu.com # https
volumeMounts:
- name: workdir
mountPath: "/work-dir"
containers:
- name: web
image: nginx
ports:
- containerPort: 80
volumeMounts:
- name: workdir
mountPath: /usr/share/nginx/html

面的资源清单中我们首先在 Pod 顶层声明了一个名为 workdir 的 Volume,前面我们用了 hostPath 的模式,这里我们使用的是 emptyDir{},这个是一个临时的目录,数据会保存在 kubelet 的工作目录下面,生命周期等同于 Pod 的生命周期。

然后我们定义了一个初始化容器,该容器会下载一个 html 文件到 /work-dir 目录下面,但是由于我们又将该目录声明挂载到了全局的 Volume,同样的主容器 nginx 也将目录 /usr/share/nginx/html 声明挂载到了全局的 Volume,所以在主容器的该目录下面会同步初始化容器中创建的 index.html 文件。

直接创建上面的 Pod:

$ kubectl apply -f init-pod.yaml

创建完成后可以查看该 Pod 的状态:

$ kubectl get pods
NAME READY STATUS RESTARTS AGE
init-demo 0/1 Init:0/1 0 4s

可以发现 Pod 现在的状态处于 Init:0/1 状态,意思就是现在第一个初始化容器还在执行过程中,此时我们可以查看 Pod 的详细信息:

$ kubectl describe pod init-demo
Name: init-demo
Namespace: default
Priority: 0
Node: node2/10.151.30.23
Start Time: Thu, 22 Oct 2020 21:17:32 +0800
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"v1","kind":"Pod","metadata":{"annotations":{},"name":"init-demo","namespace":"default"},"spec":{"containers":[{"image":"ngi...
Status: Running
IP: 10.244.2.9
IPs:
IP: 10.244.2.9
Init Containers:
install:
Container ID: docker://0d53780635c2cbf7865648dcb9a4c981e23c2ce95edcaa3f474029a9a1db972a
Image: busybox
Image ID: docker-pullable://busybox@sha256:a9286defaba7b3a519d585ba0e37d0b2cbee74ebfe590960b0b1d6a5e97d1e1d
Port: <none>
Host Port: <none>
Command:
wget
-O
/work-dir/index.html
http://www.baidu.com
State: Terminated
Reason: Completed
Exit Code: 0
Started: Thu, 22 Oct 2020 21:17:47 +0800
Finished: Thu, 22 Oct 2020 21:17:47 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-hpd7s (ro)
/work-dir from workdir (rw)
Containers:
web:
Container ID: docker://c31aed9916ed5277d0b9be96787d336186f8d312b20d59c1fcd59548f3942312
Image: nginx
Image ID: docker-pullable://nginx@sha256:ed7f815851b5299f616220a63edac69a4cc200e7f536a56e421988da82e44ed8
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Thu, 22 Oct 2020 21:18:02 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/usr/share/nginx/html from workdir (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-hpd7s (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
workdir:
Type: EmptyDir (a temporary directory that shares a pod's lifetime)
Medium:
SizeLimit: <unset>
default-token-hpd7s:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-hpd7s
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute for 300s
node.kubernetes.io/unreachable:NoExecute for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 27m default-scheduler Successfully assigned default/init-demo to node2
Normal Pulling 27m kubelet, node2 Pulling image "busybox"
Normal Pulled 27m kubelet, node2 Successfully pulled image "busybox" in 12.597844015s
Normal Created 27m kubelet, node2 Created container install
Normal Started 27m kubelet, node2 Started container install
Normal Pulling 27m kubelet, node2 Pulling image "nginx"
Normal Pulled 27m kubelet, node2 Successfully pulled image "nginx" in 13.743250204s
Normal Created 27m kubelet, node2 Created container web
Normal Started 27m kubelet, node2 Started container web

从上面的描述信息里面可以看到初始化容器已经启动了,现在处于 Running 状态,所以还需要稍等,到初始化容器执行完成后退出初始化容器会变成 Completed 状态,然后才会启动主容器。待到主容器也启动完成后,Pod 就会变成Running 状态,然后我们去访问下 Pod 主页,验证下是否有我们初始化容器中下载的页面信息:

$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
init-demo 1/1 Running 0 28m 10.244.2.9 node2 <none> <none>
$ curl 10.244.2.9
<!DOCTYPE html>
<!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=http://s1.bdstatic.com/r/www/cache/bdorz/baidu.min.css><title>百度一下,你就知道</title></head> <body link=#0000cc> <div id=wrapper> <div id=head> <div class=head_wrapper> <div class=s_form> <div class=s_form_wrapper> <div id=lg> <img hidefocus=true src=//www.baidu.com/img/bd_logo1.png width=270 height=129> </div> <form id=form name=f action=//www.baidu.com/s class=fm> <input type=hidden name=bdorz_come value=1> <input type=hidden name=ie value=utf-8> <input type=hidden name=f value=8> <input type=hidden name=rsv_bp value=1> <input type=hidden name=rsv_idx value=1> <input type=hidden name=tn value=baidu><span class="bg s_ipt_wr"><input id=kw name=wd class=s_ipt value maxlength=255 autocomplete=off autofocus></span><span class="bg s_btn_wr"><input type=submit id=su value=百度一下 class="bg s_btn"></span> </form> </div> </div> <div id=u1> <a href=http://news.baidu.com name=tj_trnews class=mnav>新闻</a> <a href=http://www.hao123.com name=tj_trhao123 class=mnav>hao123</a> <a href=http://map.baidu.com name=tj_trmap class=mnav>地图</a> <a href=http://v.baidu.com name=tj_trvideo class=mnav>视频</a> <a href=http://tieba.baidu.com name=tj_trtieba class=mnav>贴吧</a> <noscript> <a href=http://www.baidu.com/bdorz/login.gif?login&amp;tpl=mn&amp;u=http%3A%2F%2Fwww.baidu.com%2f%3fbdorz_come%3d1 name=tj_login class=lb>登录</a> </noscript> <script>document.write('<a href="http://www.baidu.com/bdorz/login.gif?login&tpl=mn&u='+ encodeURIComponent(window.location.href+ (window.location.search === "" ? "?" : "&")+ "bdorz_come=1")+ '" name="tj_login" class="lb">登录</a>');</script> <a href=//www.baidu.com/more/ name=tj_briicon class=bri style="display: block;">更多产品</a> </div> </div> </div> <div id=ftCon> <div id=ftConw> <p id=lh> <a href=http://home.baidu.com>关于百度</a> <a href=http://ir.baidu.com>About Baidu</a> </p> <p id=cp>&copy;2017&nbsp;Baidu&nbsp;<a href=http://www.baidu.com/duty/>使用百度前必读</a>&nbsp; <a href=http://jianyi.baidu.com/ class=cp-feedback>意见反馈</a>&nbsp;京ICP证030173号&nbsp; <img src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>

下一篇将介绍Kubernetes中Pod Hook、Pod 健康检查、Pod 资源配置

(转发请注明出处:http://www.cnblogs.com/zhangyongli2011/ 如发现有错,请留言,谢谢)

Kubernetes Pod生命周期(十七)的更多相关文章

  1. Kubernetes Pod 生命周期

    一. Pod Hook Kubernetes 为我们提供了生命周期钩子,就是我们所说的Pod Hook,Pod Hook是由kubelet发起的,当容器中的进程启动前或者容器中的进程终止之前运行.这是 ...

  2. 【三】Kubernetes学习笔记-Pod 生命周期与 Init C 介绍

    一.容器生命周期 Init C(初始化容器)只是用于 Pod 初始化的,不会一直随着 Pod 生命周期存在,Init C 在初始化完成之后就会死亡. 一个 Pod 可以有多个 Init C,也可以不需 ...

  3. Kubernetes1.3:POD生命周期管理

    转:http://blog.csdn.net/horsefoot/article/details/52324830 (一)  核心概念 Pod是kubernetes中的核心概念,kubernetes对 ...

  4. Pod生命周期和健康检查

    Pod生命周期和健康检查 Pod的生命周期涵盖了前面所说的PostStart 和 PreStop在内 Pod phase Pod的status定义在 PodStatus对象中,其中有一个phase字段 ...

  5. 2.k8s.Pod生命周期,健康检查

    #Pod生命周期,健康检查 pod创建过程 Init容器 就绪探测 存活探测 生命周期钩子 #Pod创建过程 master节点:kubectl -> kube-api -> kubenle ...

  6. k8s学习-pod生命周期

    4.2.pod生命周期 创建一个pod的时候过程如下: 1.容器环境初始化: 2.pause执行网络.容器卷等初始化工作: 3.所有的InitC按顺序执行,每个InitC执行完后才能执行下一个,且必须 ...

  7. pod生命周期

    Pod生命周期 我们一般将pod对象从创建至终这段时间范围成为pod的生命周期,它主要包含以下的过程: pod创建过程 运行初始化容器(init container)过程 运行主容器(main con ...

  8. 容器编排系统之Pod生命周期、健康/就绪状态探测以及资源限制

    前文我们了解了在k8s上的资源标签.标签选择器以及资源注解相关话题,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/14141080.html:今天我们来聊下k8 ...

  9. kubernetes之pod生命周期,pod重启策略, 镜像拉取策略

    pod声明周期(状态):pending , running, succeeded, failed, unknown 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多 ...

  10. k8s的pod生命周期

    pod的生命周期: 1.init container 2.main contianer (1) post start hook :容器启动后做什么操作(可以命令查看kubectl explain po ...

随机推荐

  1. JavaScript小技巧~this的保存

    在JavaScript中如果一个函数返回一个函数,此时this容易丢失,为了不使this丢失,需要在函数内部保存this. change() { let _this=this return funct ...

  2. JMeter 后置处理器之JSON提取器

    后置处理器之JSON提取器 By:授客 QQ:1033553122 测试环境 JMeter 5.4.1 插件介绍 JSON后置处理器(PostProcessor)允许使用 JSON Path 语法从J ...

  3. 开源照片管理神器 PhotoPrism 安装和使用教程

    如今我们每个人都积累了海量的照片和视频,做自媒体的 UP 主们积累的照片和视频数量可能更多.面对这么多的照片和视频,我们该如何管理呢? 之前我一直用谷歌相册,因为它有很多优势,比如无限空间,支持智能整 ...

  4. Microsoft Dynamics CRM 高级查找不能搜索实体的解决方案(浏览器插件)

    背景 我们搜索某个实体的记录的时候,一般会去对应的视图"可用的XXX",但是视图自带的条件过滤了一些数据,或者缺少了我们所需要的列,或者不能查询关联实体.这时候我们需要用到高级查找 ...

  5. ComfyUI插件:ComfyUI layer style 节点(一)

    前言: 学习ComfyUI是一场持久战,而ComfyUI layer style 是一组专为图片设计制作且集成了Photoshop功能的强大节点.该节点几乎将PhotoShop的全部功能迁移到Comf ...

  6. 关于在windows系统下使用Linux子系统

    今天意外刷到一个短视频,介绍了如何在windows下方便的使用系统自带的Linux子系统,本人抱着好奇的心理,也因为最近碰到了只使用windows操作系统解决不了的问题,还有想到以后测试项目大概率也要 ...

  7. 【vue3】详解单向数据流,大家千万不用为了某某而某某了。

    总览 Vue3 的单向数据流 尽信官网,不如那啥. vue的版本一直在不断更新,内部实现方式也是不断的优化,官网也在不断更新. 既然一切皆在不停地发展,那么我们呢?等着官网更新还是有自己的思考? 我觉 ...

  8. 【SpringMVC】 Controller接收深度复杂对象封装不到的问题

    首先来看数据结构的定义: 一个Form对象,然后里面有一个排版日期对象的List集合 排班集合的每个元素中又有一个String集合 在前端的Post请求中可以看到这个String集合是传递了的 但是D ...

  9. 【PowerDesigner】快速上手

    破解下载地址: https://www.onlinedown.net/soft/577763.htm 安装点试用,完成安装后把破解的dll库文件替换即可 学习参考自: https://www.bili ...

  10. Parallel and Sequential Data Structures and Algorithms

    并串行 从零开始考前突击并串行数据结构与算法 强烈建议和原教材参照着看 Introduction 本书的要点 定义问题 不同的算法解决 设计抽象数据类型和相应的数据结构实现 分析比较算法和数据类型的代 ...