该篇文章已经被专栏《从零开始学k8s》收录
上一篇文章:k8s污点、容忍度和pod状态 点击跳转

pod生命周期

  • Init 容器
  • 主容器
    • 容器钩子
    • 创建 pod 需要经过哪些阶段?
  • Pod 容器探测和钩子
    • 容器钩子:postStart 和 preStop
  • 写在最后

Init 容器

Pod 里面可以有一个或者多个容器,部署应用的容器可以称为主容器,在创建 Pod 时候,Pod 中 可以有一个或多个先于主容器启动的Init 容器,这个 init 容器就可以成为初始化容器,初始化容器一旦执行完,它从启动开始到初始化代码执行完就退出了,它不会一直存在,所以在主容器启动之前执行初始化,初始化容器可以有多个,多个初始化容器是要串行执行的,先执行初始化容器 1,在执行初始化容器 2等,等初始化容器执行完初始化就退出了,然后再执行主容器,主容器一退出,pod 就结束了,主容器退出的时间点就是 pod 的结束点,它俩时间轴是一致的;

Init 容器就是做初始化工作的容器。可以有一个或多个,如果多个按照定义的顺序依次执行,只有所有的初始化容器执行完后,主容器才启动。由于一个 Pod 里的存储卷是共享的,所以 Init Container 里产生的数据可以被主容器使用到,Init Container 可以在多种 K8S 资源里被使用到,如 Deployment、DaemonSet, StatefulSet、Job 等,但都是在 Pod 启动时,在主容器启动前执行,做初始化工作。

Init 容器与普通的容器区别是:

1、Init 容器不支持 Readiness,因为它们必须在 Pod 就绪之前运行完成

2、每个 Init 容器必须运行成功,下一个才能够运行

3、如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止,如果 Pod 对应的 restartPolicy 值为 Never,它不会重新启动。

[root@k8smaster node]# vim init.yaml
apiVersion: v1
kind: Pod
metadata:name: myapp-podlabels:app: myapp
spec:containers:- name: myapp-containerimage: busybox:1.28command: ['sh', '-c', 'echo The app is running! && sleep 3600']initContainers:- name: init-myserviceimage: busybox:1.28command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]- name: init-mydbimage: busybox:1.28command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]#上面两段长的是myservice的svc和mydb的svc
[root@k8smaster node]# kubectl apply -f init.yaml
pod/myapp-pod created
[root@k8smaster node]# kubectl get pods
NAME                    READY   STATUS     RESTARTS   AGE
myapp-pod               0/1     Init:0/2   0          7s
#发现一直在初始化,查看一下日志
[root@k8smaster node]# kubectl logs myapp-pod
Error from server (BadRequest): container "myapp-container" in pod "myapp-pod" is waiting to start: PodInitializing
#有个container是waiting状态,去yaml看看
until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local;
#这是在解析myservice的svc,解析到才成功,不然就会一直循环,我们没有创建,所以一直卡在这里![root@k8smaster node]# vim service.yaml
---
apiVersion: v1
kind: Service
metadata:name: myservice
spec:ports:- protocol: TCPport: 80targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:name: mydb
spec:ports:- protocol: TCPport: 80targetPort: 9377[root@k8smaster node]# kubectl apply -f service.yaml
service/myservice created
service/mydb created[root@k8smaster node]# kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
myapp-pod               1/1     Running   0          4m46s
#成功启动[root@k8smaster node]# kubectl logs myapp-pod
The app is running!
[root@k8smaster node]# kubectl describe pods myapp-pod
#也可以看启动了哪些容器 在下面

主容器

容器钩子

初始化容器启动之后,开始启动主容器,在主容器启动之前有一个 post start hook(容器启动后钩子)和 pre stop hook(容器结束前钩子),无论启动后还是结束前所做的事我们可以给它放两个钩子,这个钩子就表示用户可以用它来钩住一些命令,来执行它,做开场前的预设,结束前的清理,如 awk 有 begin,end,和这个效果类似。

postStart: 该钩子在容器被创建后立刻触发,通知容器它已经被创建。如果该钩子对应的 hook handler 执行失败,则该容器会被杀死,并根据该容器的重启策略决定是否要重启该容器,这个钩子不需要传递任何参数。

preStop: 该钩子在容器被删除前触发,其所对应的 hook handler 必须在删除该容器的请求发送 给 Docker daemon 之前完成。在该钩子对应的 hook handler 完成后不论执行的结果如何,Docker daemon 会发送一个 SGTERN 信号量给 Docker daemon 来删除该容器,这个钩子不需要传递任何参数。

在 k8s 中支持两类对 pod 的检测

第一类叫做 livenessprobe(pod 存活性探测): 存活探针主要作用是,用指定的方式检测 pod 中的容器应用是否正常运行,如果检测失败,则认为容器不健康,那么 Kubelet 将根据 Pod 中设置的 restartPolicy 来判断 Pod 是否要进行重启操作,如果容器配置中没有配置 livenessProbe,Kubelet 将认为存活探针探测一直为成功状态。 get pods里的status就是存活探测

第二类是状态检 readinessprobe(pod 就绪性探测):用于判断容器中应用是否启动完成,当探测成功后才使 Pod 对外提供网络访问,设置容器 Ready 状态为 true,如果探测失败,则设置容器的 Ready 状态为 false。

创建 pod 需要经过哪些阶段?

当用户创建 pod 时,这个请求给 apiserver,apiserver 把创建请求的状态保存在 etcd 中;接下来 apiserver 会请求 scheduler 来完成调度,如果调度成功,会把调度的结果(如调度到哪个节点上了,运行在哪个节点上了,把它更新到 etcd 的 pod 资源状态中)保存在 etcd 中,一旦存到 etcd 中并且完成更新以后,如调度到 k8snode1 上,那么 node1 节点上的 kubelet 通过 apiserver 当中的状态变化知道有一些任务被执行了,所以此时此 kubelet 会拿到用户创建时所提交的清单,这个清单会在当前节点上运行或者启动这个 pod,如果创建成功或者失败会有一个当前状态,当前这个状态会发给 apiserver,apiserver 在存到 etcd 中;在这个过程 中,etcd 和 apiserver 一直在打交道,不停的交互,scheduler 也参与其中,负责调度 pod 到合适的 node 节点上,这个就是 pod 的创建过程.

pod 在整个生命周期中有非常多的用户行为:

1、初始化容器完成初始化

2、主容器启动后可以做启动后钩子

3、主容器结束前可以做结束前钩子

4、在主容器运行中可以做一些健康检测,如 liveness probe,readness probe

Pod 容器探测和钩子

容器钩子:postStart 和 preStop

postStart:容器创建成功后,运行前的任务,用于资源部署、环境准备等。

preStop:在容器被终止前的任务,用于优雅关闭应用程序、通知其他系统等。

......
containers:
- image: samplename: war lifecycle: postStart:   #钩子exec: command:   #命令- “cp” - “/sample.war” - “/app”prestop:      #钩子httpGet:         #httpget的探针host: monitor.com    path: /waring port: 8080 scheme: HTTP
...... 以上示例中,定义了一个 Pod,包含一个 JAVA 的 web 应用容器,其中设置了 PostStart
和PreStop 回调函数。即在容器创建成功后,复制/sample.war 到/app 文件夹中。而在容器
终止之前,发送 HTTP 请求到 http://monitor.com:8080/waring,即向监控系统发送警告。 #可以看帮助文档
[root@k8smaster node]# kubectl explain pods.spec.containers.lifecycle

优雅的删除资源对象

当用户请求删除含有 pod 的资源对象时(如 RC、deployment 等),K8S 为了让应用程序优雅关闭(即让应用程序完成正在处理的请求后,再关闭软件),K8S 提供两种信息通知:

默认:K8S 通知 node 执行 docker stop 命令,docker 会先向容器中 PID 为 1 的进程发送系统信号 SIGTERM,然后等待容器中的应用程序终止执行,如果等待时间达到设定的超时时间,或者默认超时时间(30s),会继续发送 SIGKILL 的系统信号强行 kill 掉进程。

使用 pod 生命周期(利用 PreStop 回调函数),它执行在发送终止信号之前。
默认情况下,所有的删除操作的优雅退出时间都在 30 秒以内。kubectl delete 命令支持–grace-period=的选项,以运行用户来修改默认值。0 表示删除立即执行,并且立即从 API 中删除 pod。在节点上,被设置了立即结束的的 pod,仍然会给一个很短的优雅退出时间段,才会开始被强制杀死。如下:

spec: containers: - name: nginx-demo image: centos:nginx lifecycle: preStop: #钩子exec: command: ["/usr/local/nginx/sbin/nginx","-s","quit"]  #删除之前会先停掉nginx再删除容器ports: - name: http containerPort: 80

写在最后

创作不易,如果觉得内容对你有帮助,麻烦给个三连关注支持一下我!如果有错误,请在评论区指出,我会及时更改!
目前正在更新的系列:从零开始学k8s
感谢各位的观看,文章掺杂个人理解,如有错误请联系我指出~

【云原生 | 从零开始学Kubernetes】十二、k8spod的生命周期与容器钩子相关推荐

  1. 【云原生 | 从零开始学Kubernetes】二十三、Kubernetes控制器Statefulset

    该篇文章已经被专栏<从零开始学k8s>收录 上一篇文章:kubernetes持久化存储下 点击跳转 Statefulset Statefulset 控制器:概念.原理解读 有状态服务? 无 ...

  2. 【云原生 | 从零开始学Kubernetes】二十七、配置管理中心Secret和rbac授权

    该篇文章已经被专栏<从零开始学k8s>收录 上一篇文章:kubectl深入理解 点击跳转 配置管理与rbac 配置管理中心 Secret Secret 是什么? 使用 Secret k8s ...

  3. 【云原生 | 从零开始学Kubernetes】二、使用kubeadm搭建K8S集群

    这里写目录标题 安装要求 准备环境 初始化 安装Docker/kubeadm/kubelet 添加kubernetes软件源 三台机子 安装kubeadm,kubelet和kubectl 部署Kube ...

  4. 【云原生 | 从零开始学Kubernetes】十、k8sPod节点亲和性和反亲和性

    该篇文章已经被专栏<从零开始学k8s>收录 Pod节点亲和性和常见的状态 Pod 节点亲和性 pod 节点反亲和性 写在最后 Pod 节点亲和性 pod 自身的亲和性调度有两种表示形式 p ...

  5. 【云原生 | 从零开始学Docker】二、Docker的常用指令学习以及使用

    该篇文章已经被专栏<从零开始学docker>收录 Docker常用命令使用 一.如何去学习命令 二.镜像常用命令 2.1查看本地所有镜像 2.2 搜索镜像 2.3下载镜像 2.4 删除镜像 ...

  6. 【云原生 | 从零开始学istio】二、Istio核心特性与架构

    istio核心特性 Istio 核心特性 断路器 超时 重试 多路由规则 Istio 架构 写在最后 Istio 核心特性 1.流控(traffic management) 断路器(circuit b ...

  7. 【云原生 | 从零开始学Docker】一、Docker的安装,启动以及工作原理

    [从零开始学Docker]安装篇 一丶Docker浅谈 1.1Docker为什么出现 1.2Docker能干吗 二.Docker的安装 2.1 Docker的组成 2.2 安装前提 2.3 安装步骤 ...

  8. 【云原生 | 从零开始学Docker】七丶实战提交自己的镜像以及docker网络

    该篇文章已经被专栏<从零开始学docker>收录 实战以及网络 实战测试 制作自己的tomcat 1.准备镜像文件(tomcat的压缩包,jdk的压缩包) 2.编写dockerfile文件 ...

  9. 【云原生 | 从零开始学Docker】六、如何写出自己的镜像——Docker file

    该篇文章已经被专栏<从零开始学docker>收录 Docker file 数据卷容器 mysql数据共享 结论 Docker File Docker File的介绍 构建步骤 Docker ...

最新文章

  1. 五分钟看完 RocketMQ应用
  2. Webservice soap wsdl区别之个人见解
  3. python基础之if、while、for语句
  4. ces测试数据测试ces测试数据测试ces测试数据测试ces测试数据测试ces测试数据测试ces测试数据测试ces测试数据测试再次测试
  5. Java命令行界面(第15部分):Jargo
  6. mysql 分析服务_MySQL分析服务器状态_MySQL
  7. 神奇的go语言(基本语法)
  8. vue 给标签添加data属性_在Vue中获取自定义属性方法:data-id的实例
  9. 【大数据部落】R语言犯罪率回归模型报告Regression model on crimerate report
  10. AT89C51的矩阵键盘、跑马灯和呼吸灯设计
  11. jquery进度条_jQuery进度栏
  12. 40个PPT下载 | 分享珍藏很久的大数据PPT合集(附链接)
  13. 5.3 - 抽屉新热榜
  14. CVPR 2021 | 自监督学习新思路!S2-BNN:基于蒸馏的自监督学习算法
  15. 移动云API开放平台助力开发者驰骋云端
  16. 免费阅读里的“B站”,后浪已乘“疯”
  17. @keyup.enter.native不生效问题解决
  18. SPSS——方差分析(Analysis of Variance, ANOVA)——单因素方差分析
  19. 虚拟机集群启动,Hadoop常用命令
  20. 2021年R2移动式压力容器充装考试内容及R2移动式压力容器充装模拟考试

热门文章

  1. 关于glRotatef(GLfloat angle,GLfloat x,GLfloat y,GLfloat z)的参数的一些理解
  2. 所有城市及经纬度数据(2021-8-28)
  3. 单元测试和E2E测试
  4. C语言写的一个简单的计算器
  5. 2020年开春最新面试!今日头条 Android 面试题及答案 (已拿到 offer)
  6. 【LiteApp系列】爱奇艺小程序架构浅析
  7. jackson 入门
  8. 文件服务器迁移方法,文件服务器迁移工具
  9. MySQL的触发器原理应用,after和before的区别
  10. 2021赤峰市地区高考成绩排名查询,2021年赤峰高考状元是谁分数多少分,历年赤峰高考状元名单...