pod生命周期

和一个个独立的应用容器一样,Pod 也被认为是相对临时性(而不是长期存在)的实体。 Pod 会被创建、赋予一个唯一的 ID(UID),并被调度到节点,并在终止(根据重启策略)或删除之前一直运行在该节点。

如果一个节点死掉了,调度到该节点 的 Pod 也被计划在给定超时期限结束后删除。

Pod 自身不具有自愈能力。如果 Pod 被调度到某节点 而该节点之后失效,或者调度操作本身失效,Pod 会被删除;与此类似,Pod 无法在节点资源 耗尽或者节点维护期间继续存活。Kubernetes 使用一种高级抽象,称作控制器,来管理这些相对而言可随时丢弃的 Pod 实例。

任何给定的 Pod (由 UID 定义)从不会被“重新调度(rescheduled)”到不同的节点; 相反,这一 Pod 可以被一个新的、几乎完全相同的 Pod 替换掉。 如果需要,新 Pod 的名字可以不变,但是其 UID 会不同。

如果某物声称其生命期与某 Pod 相同,例如存储卷, 这就意味着该对象在此 Pod (UID 亦相同)存在期间也一直存在。 如果 Pod 因为任何原因被删除,甚至某完全相同的替代 Pod 被创建时, 这个相关的对象(例如这里的卷)也会被删除并重建。

我们一般将Pod对象从创建到终止的这段时间范围称为Pod的生命周期,它主要包含下面的过程:

​ 1)Pod创建过程;

​ 2)运行初始化容器(init container)过程;

​ 3)运行主容器(main container):

​ ① 容器启动后钩子函数(post start)、容器终止前钩子函数(pre stop)

​ ②容器存活性探测(liveness probe)、就绪性探测(readiness probe)

​ 4) Pod终止过程。

pod在生命周期内的五种状态

取值 描述
Pending(挂起) Pod 已被 Kubernetes 系统接受,但有一个或者多个容器尚未创建亦未运行。此阶段包括等待 Pod 被调度的时间和通过网络下载镜像的时间。
Running(运行中) Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
Succeeded(成功) Pod 中的所有容器都已成功终止,并且不会再重启。
Failed(失败) Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
Unknown(未知)

因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。

 

如果某节点死掉或者与集群中其他节点失联,Kubernetes 会实施一种策略,将失去的节点上运行的所有 Pod 的取值设置为 Failed。

pod的创建过程

1、kubectl向apiserver发送一个创建pod的请求

2、apiserver收到请求后生成一个包含创建信息的yaml文件并写入etcd。

3、scheduler发现有新的pod要创建,经过计算再找出最适合创建的node进行创建。

4、node节点的kubelet接收到创建pod的信息后调用docker启动容器,然后将结果发送给apiserver

5、apiserver将接收到pod的信息存入etcd

Pod 状况查看

Pod 有一个 PodStatus 对象,其中包含一个 PodConditions 数组。Pod 可能通过也可能未通过其中的一些状况测试。

  • PodScheduled:Pod 已经被调度到某节点;
  • ContainersReady:Pod 中所有容器都已就绪;
  • Initialized:所有的 Init 容器 都已成功完成;
  • Ready:Pod 可以为请求提供服务,并且应该被添加到对应服务的负载均衡池中。
字段名称 描述
type Pod 状况的名称
status 表明该状况是否适用,可能的取值有 "True", "False" 或 "Unknown"
lastProbeTime 上次探测 Pod 状况时的时间戳
lastTransitionTime Pod 上次从一种状态转换到另一种状态时的时间戳
reason 机器可读的、驼峰编码(UpperCamelCase)的文字,表述上次状况变化的原因
message 人类可读的消息,给出上次状态转换的详细信息

初始化容器(init c)

初始化容器Init Container是在Pod的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,可以是一个 它具有两大特征:

初始化容器必须运行完成直至结束,如果某个初始化容器运行失败,那么Kubernetes需要重启它直至成功完成。

初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面一个才能运行。

初始化容器有很多应用场景,下面列出的是最常见的几种:

提供主容器镜像中不具备的工具程序或自定义代码。
初始化容器要先于应用容器串行启动并运行完成;因此可用于延后应用容器的启动直至其依赖的条件得到满足。

例:

我们先创建一个init-pod.yml 文件

apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-containers
image: busybox
command: ['sh' ,'-c','echo the app is running && sleep 600s']
initContainers:
- name: init-myservice
image: busybox
command: ['sh','-c', 'until nslookup myservice; do echo waiting from myservice; sleep 2s ;done ']
- name: mydb-containers
image: busybox
command: ['sh','-c','until nslookup mydb; do echo waiting from mydb; sleep 2s; done']

然后创建pod并查看: kubectl create -f init-pod.yml

[root@master ~]# kubectl create -f init-pod.yml
pod/myapp-pod created
[root@master ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:0/2 0 23s
nginx-6799fc88d8-648cn 1/1 Running 0 48d

此时myapp-pod显示正在init初始化,我们describe看一下这个pod状态

[root@master ~]# kubectl describe pods myapp-pod
Name: myapp-pod
Namespace: default
Priority: 0
Node: node1/192.168.248.128
Start Time: Mon, 27 Jun 2022 15:49:59 +0800
Labels: app=myapp
Annotations: cni.projectcalico.org/containerID: bdead7238a0b177ce59049c3d13a180dadd5c867ad6eb3f0aa06710585eac8c5
cni.projectcalico.org/podIP: 10.101.149.3/32
cni.projectcalico.org/podIPs: 10.101.149.3/32
Status: Pending
IP: 10.101.149.3
IPs:
IP: 10.101.149.3
Init Containers:
init-myservice:
Container ID: docker://b2bcc9e7e88702bdf2fbd53fdfc5e70063d5fc3419338770f14b8b48804e4800
Image: busybox
Image ID: docker-pullable://busybox@sha256:5acba83a746c7608ed544dc1533b87c737a0b0fb730301639a0179f9344b1678
Port: <none>
Host Port: <none>
Command:
sh
-c
until nslookup myservice; do echo waiting from myservice; sleep 2s ;done
State: Running
Started: Mon, 27 Jun 2022 15:50:25 +0800
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-trqgw (ro)
mydb-containers:
Container ID:
Image: busybox
Image ID:
Port: <none>
Host Port: <none>
Command:
sh
-c
until nslookup mydb; do echo waiting from mydb; sleep 2s; done
State: Waiting
Reason: PodInitializing
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-trqgw (ro)
Containers:
myapp-containers:
Container ID:
Image: busybox
Image ID:
Port: <none>
Host Port: <none>
Command:
sh
-c
echo the app is running && sleep 600s
State: Waiting
Reason: PodInitializing
Ready: False
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-trqgw (ro)
Conditions:
Type Status
Initialized False
Ready False
ContainersReady False
PodScheduled True
Volumes:
kube-api-access-trqgw:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 6m12s default-scheduler Successfully assigned default/myapp-pod to node1
Normal Pulling 6m11s kubelet Pulling image "busybox"
Normal Pulled 5m46s kubelet Successfully pulled image "busybox" in 24.671646739s
Normal Created 5m46s kubelet Created container init-myservice
Normal Started 5m46s kubelet Started container init-myservice

此时正在启动init-myservice,由于我们还没没有创建myservice,所以init容器就一直在重启,我们看一下日志

[root@master ~]# kubectl logs myapp-pod -c init-myservice
Server: 10.96.0.10
Address: 10.96.0.10:53 ** server can't find myservice.default.svc.cluster.local: NXDOMAIN *** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer
*** Can't find myservice.default.svc.cluster.local: No answer
*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer waiting from myservice
Server: 10.96.0.10
Address: 10.96.0.10:53 ** server can't find myservice.default.svc.cluster.local: NXDOMAIN *** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer
*** Can't find myservice.default.svc.cluster.local: No answer
*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer waiting from myservice
Server: 10.96.0.10
Address: 10.96.0.10:53 ** server can't find myservice.default.svc.cluster.local: NXDOMAIN *** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer
*** Can't find myservice.default.svc.cluster.local: No answer
*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer waiting from myservice
Server: 10.96.0.10
Address: 10.96.0.10:53 ** server can't find myservice.default.svc.cluster.local: NXDOMAIN *** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer
*** Can't find myservice.default.svc.cluster.local: No answer
*** Can't find myservice.svc.cluster.local: No answer
*** Can't find myservice.cluster.local: No answer
*** Can't find myservice.localdomain: No answer waiting from myservice

通过日志发现myservice没有启动,所以init-myservice一直在重启,我们再将myservice创建启动后再看

[root@master ~]# cat myservice.yml
kind: Service
apiVersion: v1
metadata:
name: myservice
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9376
[root@master ~]# kubectl create -f myservice.yml
service/myservice created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 Init:1/2 0 22m
nginx-6799fc88d8-648cn 1/1 Running 0 49d

此时发现STATUS变成了 Init:1/2 ,说明init-myservice初始化已经完成,我们再创建mydb启动看一下

[root@master ~]# cat mydb.yml
kind: Service
apiVersion: v1
metadata:
name: mydb
spec:
ports:
- protocol: TCP
port: 80
targetPort: 9377
[root@master ~]# kubectl create -f mydb.yml
service/mydb created
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 0/1 PodInitializing 0 29m
nginx-6799fc88d8-648cn 1/1 Running 0 49d

这次init容器都已经初始化完成并正在启动

[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-pod 1/1 Running 0 32m
nginx-6799fc88d8-648cn 1/1 Running 0 49d

init初始化完成并启动容器成功

init初始化特殊说明:

在pod的启动过程中,init容器会按顺序在网络和数据卷启动之后启动,每个容器启动必须在上个容器成功退出后执行。

如果pod重启,那init容器必须重新执行

对init容器的spec修改被限制在image字段,修改其他字段不会生效,更改init容器的image字段,等于重启该pod。

探针

为什么要有探针,因为探针可以探测pod当中的容器是否正常运行,我们知道容器启动,业务程序未必正常,因此,我们可以用livenessProbe探针来探测业务是否正常,而对于我们新建的pod如果不做就绪性探测,会被前端的service立刻关联,这样有可能导致部分客户端无法正常访问,所欲对于k8s探针主要分为两种:

  • 一种为存活性探测(livenessProbe)
  • 一种为就绪性探测(readinessProbe)
探针是由kubelet对容器执行的定期诊断,有三种类型的处理程序:

1、ExecAction:在容器内执行指定命令,如果命令退出时返回码为0则认为诊断成功。

2、TCPsocketAction:对执定端口上的容器的IP地址进行tcp检查,如果端口打开则认为是诊断成功的。

3、HTTPGetAction:对指定的端口和路径上的容器的IP地址执行HTTP get请求。如果响应的状态码大于200且小于400,则被诊断认为是成功的。

每次探测都将获得以下三种结果之一:

Success(成功): 容器通过了诊断。

Failuer(失败):  容器未通过诊断。

Unknown(未知):诊断失败,因此不会采取任何行动。

livenessProbe:指容器是否正在运行。如果存活探测失败,则kubelet会杀死容器,并且容器将受到其重启策略的影响。

例1:ExecAction

[root@master ~]# cat livenessprobe-exec.yaml
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-pod
namespace: default
labels:
app: liveness
spec:
containers:
- name: livenessprobe-container
image: busybox
imagePullPolicy: IfNotPresent
command: ["/bin/sh","-c","touch /tmp/test.txt;sleep 20; rm -rf /tmp/test.txt;sleep 3600"]
livenessProbe:
exec:
command: ["test","-e","/tmp/test.txt"]
initialDelaySeconds: 2
periodSeconds: 2
failureThreshold: 3 验证:可以看到由于文件被删除已经crash了,并且重启了6次
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
livenessprobe-pod 0/1 CrashLoopBackOff 6 10m

例2:HttpGetAction

[root@master ~]# cat livenessprobe-gethttp.yaml
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-gethttp-pod
namespace: default
labels:
app: liveness-gethttp
spec:
containers:
- name: livenessprobe-gethttp-container
image: nginx
imagePullPolicy: IfNotPresent
livenessProbe:
initialDelaySeconds: 2
periodSeconds: 2
failureThreshold: 3
httpGet:
port: 80
path: /index.html
容器跑起来之后删除/usr/share/nginx/html/index.html文件,然后稍等片刻


验证:可以看到容器被重启了一次然后就一直正常运行
[root@master ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
livenessprobe-gethttp-pod 1/1 Running 1 14m

readinessProbe:指示容器是否准备好请求服务,如果就绪探测失败,端点控制器将从pod匹配的所有service的端点中删除该pod的ip地址。

 
[root@master ~]# cat readinessprobe-gethttp.yaml
apiVersion: v1
kind: Pod
metadata:
name: livenessprobe-gethttp-pod
namespace: default
labels:
app: liveness-gethttp
spec:
containers:
- name: livenessprobe-gethttp-container
image: nginx
imagePullPolicy: IfNotPresent
readinessProbe:
initialDelaySeconds: 2
periodSeconds: 2
failureThreshold: 3
httpGet:
port: 80
path: /index.html 验证:
1.连入容器删除index.html文件
[root@master ~]# kubectl exec -it livenessprobe-gethttp-pod -- /bin/bash
root@livenessprobe-gethttp-pod:/# cd /usr/share/nginx/html/
root@livenessprobe-gethttp-pod:/usr/share/nginx/html# ls
50x.html index.html
root@livenessprobe-gethttp-pod:/usr/share/nginx/html# rm -rf index.html
root@livenessprobe-gethttp-pod:/usr/share/nginx/html# exit
2.查看pod状态
[root@master ~]# kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
livenessprobe-gethttp-pod 1/1 Running 0 6s 10.244.1.38 node1 <none> <none>
livenessprobe-gethttp-pod 0/1 Running 0 24s 10.244.1.38 node1 <none> <none>
3.随后我们在在容器里创建出index.html文件,然后在观察pod
[root@master ~]# kubectl get pods -o wide -w
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
livenessprobe-gethttp-pod 1/1 Running 0 6s 10.244.1.38 node1 <none> <none>
livenessprobe-gethttp-pod 0/1 Running 0 24s 10.244.1.38 node1 <none> <none>
livenessprobe-gethttp-pod 1/1 Running 0 2m48s 10.244.1.38 node1 <none> <none>

pod的终止过程

1. 用户向apiserver发送删除pod对象的命令

2. apiserver中的pod对象信息会随着时间的推移而更新,在宽限期内(默认是30s),pod被视为dead

3. 将pod标记为terminating(正在删除)状态

4. kubelet在监控到pod对象转为terminating状态的同时启动pod关闭过程

5. 端点控制器监控到pod对象的关闭行为时将其从所有匹配到此端点的service资源的端点列表中移除

6. 如果当前pod对象定义了 preStop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行

7. pod对象中的容器进程收到停止信号

8. 宽限期结束后,若pod中还存在仍在运行的进程,那么pod对象会收到立即终止的信号

9. kubelet请求apiserver将此pod资源的宽限期设置为0,从而完成删除操作,此时pod对于用户已不可见

k8s之pod的生命周期的更多相关文章

  1. Kubernetes中资源清单与Pod的生命周期(二)

    一.资源清单 1,定义: 在k8s中一般使用yaml格式的文件来创建符合我们预期的资源,这样的yaml被称为资源清单. 使用资源清单创建Pod: kubectl apply -f nginx.yaml ...

  2. Pod 的生命周期

    上图展示了一个 Pod 的完整生命周期过程,其中包含 Init Container.Pod Hook.健康检查 三个主要部分,接下来我们就来分别介绍影响 Pod 生命周期的部分: 首先在介绍 Pod ...

  3. k8s的Pod状态和生命周期管理

    Pod状态和生命周期管理   一.什么是Pod? 二.Pod中如何管理多个容器? 三.使用Pod 四.Pod的持久性和终止 五.Pause容器 六.init容器 七.Pod的生命周期 (1)Pod p ...

  4. k8s的pod生命周期

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

  5. Kubernetes学习之路(十一)之Pod状态和生命周期管理

    一.什么是Pod? Pod是kubernetes中你可以创建和部署的最小也是最简的单位.一个Pod代表着集群中运行的一个进程. Pod中封装着应用的容器(有的情况下是好几个容器),存储.独立的网络IP ...

  6. Pod——状态和生命周期管理及探针和资源限制

    一.什么是Podkubernetes中的一切都可以理解为是一种资源对象,pod,rc,service,都可以理解是 一种资源对象.pod的组成示意图如下,由一个叫”pause“的根容器,加上一个或多个 ...

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

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

  8. pod生命周期

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

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

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

  10. (五)Kubernetes Pod状态和生命周期管理

    什么是Pod Pod是kubernetes中你可以创建和部署的最小也是最简的单位.Pod代表着集群中运行的进程. Pod中封装着应用的容器(有的情况下是好几个容器),存储.独立的网络IP,管理容器如何 ...

随机推荐

  1. java后端整合极光消息推送

    目录 1.简介 2.极光Demo 2.1.进入极光官网--应用管理 2.2.快速集成一个Android/iOS的SDK​ 2.3.java服务端代码 3.参考资料 1.简介 简单来说,就是androi ...

  2. 一步步教你在Edge浏览器上安装网风笔记

    微软于2022年6月15日正式结束对浏览器"Internet Explorer (IE)"的支持,IE已正式退出历史舞台,取而代之的是目前风头正盛的被微软称为当今最好用的Edge浏 ...

  3. CentOS 7安装mysql5.7-单节点&主从

    一 下载 Mysql5.7下载地址:https://dev.mysql.com/downloads/mysql/5.7.html#downloads Mysql精细版本存档版本下载地址:https:/ ...

  4. 《深度探索C++对象模型》第六章 执行期语意学

    new运算符和delete运算符 运算符new看似是一个简单的运算,比如: int *pi=new int(5); 但是它实际由两个步骤完成: 1.通过适当的new运算符函数实体,配置所需的内存: / ...

  5. GIS数据下载合集:遥感、土壤、气象、行政区数据...

      本文介绍GIS领域相关的各类综合数据免费获取网站,包括遥感数据.气象数据.土地数据.土壤数据.农业数据.行政区数据.社会数据.经济数据等等.   数据较多,大家可以直接通过下方目录加以总览:点击数 ...

  6. pycharm下载 安装使用

    pycharm下载与使用 1.下载 ​ 该软件分免费版和收费版 ​ 免费版(community):功能少 ​ 收费版(professional):30天试用 ​ 我们尽量使用收费版本 ​ 官网地址:h ...

  7. 创建a标签使用get请求下载文件

    创建a标签使用get请求下载文件 let url = `${BaseUrl.path}/aa/bb/cc?no=${this.sqcode}&pae=${this.wlName}&as ...

  8. three.js一步一步来--如何画出一个逃跑的圆柱体

    代码如下 <template> <div style="width:1000px; height:800px"> <p>逃跑的圆柱体</p ...

  9. 五、pycharm的安装与基本使用

    目录 一.pycharm的安装 1.软件介绍 2.正版安装 1.下载软件 2.安装软件 3.其他方法安装(需要先下载相关资源) ①无限试用法 ②傻瓜式激活法 ③淘宝购买 二.pycharm软件的使用 ...

  10. Fiddler抓手机APP包

    *手机和电脑连接在同一wifi下 *fiddler设置 *启动Fiddler,打开菜单栏中的 Tools > Fiddler Options,打开"Fiddler Options&qu ...