前面我们已经了解了 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. Github关于PAT(Personal Access Token)

    Github关于PAT(Personal Access Token) 创建个人访问令牌 您应该通过命令行或 API 创建个人访问令牌来代替密码. 注意: 如果您在命令行上使用 GitHub CLI 向 ...

  2. windows下mysql服务局域网访问配置

    在局域网中访问本机(Windows)的MySQL服务器,需要确保MySQL服务器配置为允许远程访问,并且防火墙设置允许外部连接.以下是详细的步骤: 1. 修改MySQL配置文件允许远程访问 找到并编辑 ...

  3. 解决IE11兼容问题的一些心得

    IE11中,都不支持es6新特性. vue想要兼容IE11不要写箭头函数, UI框架不要写有箭头的回调函数(编译成es5的时候,会通不过), 使用label将es6编译成es5. 使用typescri ...

  4. 如何用 WinDbg 调试Linux上的 .NET程序

    一:背景 1. 讲故事 最新版本 1.2402.24001.0 的WinDbg真的让人很兴奋,可以将自己伪装成 GDB 来和远程的 GDBServer 打通来实现对 Linux 上 .NET程序进行调 ...

  5. ABC352

    A link \(x\)停不到,\(y\)能停到. 要先判断是从前往后还是从后往前. 点击查看代码 #include<bits/stdc++.h> using namespace std; ...

  6. vue使用Echarts常见警告处理方法

    [警告一][ECharts] DEPRECATED: textStyle hierarchy in label has been removed since 4.0. All textStyle pr ...

  7. 【C】Re09 结构体

    一.结构体 Struct 创建和基本使用 #include <stdio.h> #include <stdlib.h> #include <string.h> // ...

  8. 【Layui】01 快速入门

    [原生JavaScript 与 JQuery] <!DOCTYPE html> <html lang="en"> <head> <meta ...

  9. 《最新出炉》系列小成篇-Python+Playwright自动化测试-67 - 模拟手机浏览器兼容性测试

    1.简介 在日常工作中,我们会遇到需要使用不同的硬件设备测试兼容性的问题,尤其是现在手机型号基本上是每个厂家每年发布一款新机型,而且手机的屏幕大小分辨率五花八门的,我们基本不可能全部机型都用真机测试一 ...

  10. 火山引擎ByteHouse助力车企实现高性能数据分析

    更多技术交流.求职机会,欢迎关注字节跳动数据平台微信公众号,回复[1]进入官方交流群.   新能源汽车市场正在迎来飞速发展时期.根据 IDC 预测,中国乘用车市场中,新能源车市场规模将在2028年超过 ...