前言

本篇是Kubernetes第五篇,大家一定要把环境搭建起来,看是解决不了问题的,必须实战。

Kubernetes系列文章:
  1. Kubernetes介绍
  2. Kubernetes环境搭建
  3. Kubernetes-kubectl介绍
  4. Kubernetes-Pod介绍(-)

Pod生命周期

Pod对象自从其创建开始至其终止退出的时间范围称为其生命周期。在这段时间中,Pod会处于多种不同的状态,并执行一些操作;其中,创建主容器(main container)为必需的操作,其他可选的操作还包括运行初始化容器(init container)、容器启动后钩子(post start hook)、容器的存活性探测(liveness probe)、就绪性探测(readiness probe)以及容器终止前钩子(pre stop hook)等,这些操作是否执行则取决于Pod的定义。如下图所示:


image.png
Pod phase

Pod phase代表其所处生命周期的阶段。Pod phase 并不是用来代表其容器的状态,也不是一个严格的状态机。定义在Pod的PodStatus对象的phase字段中,phase 的可能情况有:


image.png

image.png
Pod conditions

Pod有一个PodStatus对象,PodStatus包含一个 PodCondition 数组, 用来描述Pod是否达到某些指定的条件。 PodCondition包含以下字段:


image.png
Pod 生命周期中的重要行为

除了创建应用容器之外,用户还可以为 Pod 对象定义其生命周期中的多种行为,如初始化容器、存活性探测及就绪性探测等。

init container

初始化容器(init container)即应用程序的主容器启动之前要运行的容器,常用于为主容器执行一些预置操作,它们具有两种典型特征:

  1. 初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么 Kubernetes 需要重启它直到成功完成;
  2. 每个初始化容器都必须按定义的顺序串行运行;
初始化容器可以做什么

有不少场景都需要在应用容器启动之前进行初始化操作,例如,基于环境变量或配置模板为应用程序生成配置文件、从配置中心获取配置等。初始化容器的典型应用场景大概有以下几种:

  1. 用于运行特定的检测程序,出于安全等原因,这些程序不方便包含再主容器镜像中;
  2. 为容器镜像的构建和部署人员提供了分离、独立工作的途径,使得他们不必协同起来制作单个镜像文件;
  3. 初始化容器和主容器处于不同的文件系统视图中,因此可以分别安全地使用敏感数据,例如 Secrets 资源;
  4. 初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足;

注意点: 初始化容器不支持就绪型探测器(Readiness Probe),因为它们必须在 Pod 就绪之前运行完成,而就绪型探测器是在之后才开始的。

实战
  1. 删除Pod,这里先清理之前实现的Demo,这一步可忽略;
kubectl delete -f nginx-deployment.yaml
  1. 新建nginx-init-container.yaml文件,在启动Nginx之前,通过初始化容器busybox为Nginx创建一个index.html,init container与Nginx容器共享Volume,以保证Nginx访问的是init container设置的index.html页面;
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  #通过wget下载index.html
  initContainers:
    - name: install
      image: busybox
      command:
      - wget
      - "-O"
      - "/workdir/index.html"
      - http://www.baidu.com
      volumeMounts:
      - name: workdir
        mountPath: /workdir
  containers:
  - name: nginx
    image: nginx
    resources:
      limits:
        memory: "128Mi"
        cpu: "128m"
    ports:
    - containerPort: 80
    volumeMounts:
    - name: workdir
      mountPath: /usr/share/nginx/html
  volumes:
  - name: workdir
    emptyDir: {}
  1. 创建Pod资源;
kubectl apply -f nginx-init-container.yaml
  1. 查看Pod运行事件;
kubectl describe pod nginx

image.png
  1. 进入容器目录验证index.html是否为init container生成;
kubectl exec -it nginx /bin/bash

image.png
生命周期钩子函数

生命周期钩子函数(lifecycle hook)是一些框架中常用的手段,它实现了程序运行周期中的关键时刻的可见性,并赋予用户为此采取某种行动的能力。类似地,容器生命周期钩子使它能够感知自身生命周期管理中的事件,并在相应的时刻到来时运行由用户指定的处理程序代码。Kubernetes 为容器提供了两种生命周期钩子:

  1. postStart:在容器创建完成之后立即运行的钩子处理器(handler),不过 Kubernetes 无法确保它一定会于Docker中的 ENTRYPOINT 之前运行;
  2. preStop:于容器终止操作之前立即运行的钩子处理器,它以同步的方式调用,因此在其完成之前会阻塞删除容器的操作的调用;
钩子函数实现方式

容器可以通过实现和注册该回调的处理程序来访问该回调。 针对容器,有两种类型的回调处理程序可供实现:

  1. Exec: 在钩子时间触发时直接在当前容器中运行由用户定义的命令。 命令所消耗的资源计入容器的资源消耗;
  2. HTTP: 在当前容器中向某URL发起HTTP请求;
实战
  1. 删除Pod;
kubectl delete -f nginx-init-container.yaml
  1. 编辑nginx-init-container.yaml,增加postStart和preStop钩子函数;
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  initContainers:
    - name: install
      image: busybox
      command:
      - wget
      - "-O"
      - "/workdir/index.html"
      - http://www.baidu.com
      volumeMounts:
      - name: workdir
        mountPath: /workdir
  containers:
  - name: nginx
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "nginx -s quit; while killall -0 nginx; do sleep 1; done"]
    resources:
      limits:
        memory: "128Mi"
        cpu: "128m"
    ports:
      - containerPort: 80
    volumeMounts:
      - name: workdir
        mountPath: /usr/share/nginx/html
  volumes:
  - name: workdir
    emptyDir: {}
  1. 创建Pod资源;
kubectl apply -f nginx-init-container.yaml
  1. 进入容器目录验证/usr/share/message目录是否输出postStart handler;
kubectl exec -it nginx -- /bin/bash

image.png
健康检查

Kubernetes对Pod的健康状态通过三类探针来检查,其中最主要的探针是LivenessProbe和ReadinessProbe,kubelet会定期执行这两类探针来诊断容器的检查状况,介绍如下:

  1. LivenessProbe: 用于判断容器是否处于Running状态,如果LivenessProbe探针检测到容器处于不健康状态,则kubelet回杀掉该容器的进程,并根据容器的重启策略做相应的处理,如果一个容器不包含LivenessProbe探针,那么kubelet会认为该容器的LivenessProbe探针一直返回值为true;
  2. ReadinessProbe: 用于判断容器的服务是否处于Ready状态,达到Ready状态的Pod才可以接收请求。对于被Service管理的Pod,如果Ready状态变为false, 则 Service是不会负载到该Pod上的。ReadinessProbe是定期触发的,存在Pod整个生命周期中;
  3. StartupProbe: 用于容器启动的健康检查,用于一些启动缓慢的业务,避免业务长时间启动而被前面的探针kill掉;
探针的探测方式

容器探测(container probe)是Pod对象生命周期中的一项重要的日常任务,它是由kubelet对容器周期性执行的健康状态诊断,诊断操作由于容器的处理器(handler)进行定义。Kubernetes 支持三种处理器用于 Pod 探测:

  1. ExecAction: 在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功;
  2. TCPSocketAction: 对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断被认为是成功的;
  3. HTTPGetAction: 对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的状态码大于等于200 且小于 400,则诊断被认为是成功的;
探针探测结果

每类探针都有三种结果:

  1. Success:容器通过检查;
  2. Failure:容器未通过检查;
  3. Unknown:未能执行检查,因此不采取任何措施;
实战
  1. 删除Pod;
kubectl delete -f nginx-init-container.yaml
  1. 新建lifecycle-pod.yaml,继续使用nginx容器,增加postStart和preStop钩子函数,定义LivenessProbe和ReadinessProbe探针,验证主容器的各项事件的执行流程;
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo postStart handler >> /usr/share/message"]
      preStop:
        exec:
          command: ["/bin/sh", "-c", "echo preStop handler >> /usr/share/message"]
    resources:
      limits:
        memory: "128Mi"
        cpu: "128m"
    ports:
      - containerPort: 80
    livenessProbe:
      exec:
        command: ["/bin/sh", "-c", "echo livenessProbe >> /usr/share/message"]
      initialDelaySeconds: 5
      periodSeconds: 5
    readinessProbe:
      exec:
        command: ["/bin/sh", "-c", "echo readinessProbe >> /usr/share/message"]
      initialDelaySeconds: 5
      periodSeconds: 5
  1. 创建Pod资源;
kubectl apply -f lifecycle-pod.yaml
  1. 进入容器目录验证/usr/share/message的输出,到这里我们就验证了整个生命周期对的事件;
kubectl exec -it nginx -- /bin/bash

image.png
Pod重启策略

容器进程发生崩溃或容器申请超出限制的资源等原因都可能会导致 Pod 对象的终止,此时是否应该重建该 Pod 对象则取决于其重启策略restartPolicy属性的定义。


img

Pod重启策略与控制的方式息息相关,可以管理Pod的控制器有Replication Controller,Job,DaemonSet,及kubelet(静态Pod), 对于不同的控制器有注意以下问题:

  1. Replication Controller和DaemonSet:必须设置为Always,需要保证该容器持续运行;
  2. Job:设置为OnFailure或Never,确保容器执行完后不再重启;
  3. kubelet:在Pod失效的时候重启它,不论RestartPolicy设置为什么值,并且不会对Pod进行健康检查;

此外还有一个需要注意的点就是重启的容器的时间,kubelet重启失效容器的时间间隔以指数方式增长,最长延迟时间为300秒。

结束

欢迎大家点点关注,点点赞!

Kubernetes-Pod介绍(二)-生命周期的更多相关文章

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

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

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

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

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

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

  4. Android四大基本组件介绍与生命周期

    Android四大基本组件介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器 ...

  5. android开发3:四大基本组件的介绍与生命周期

    android开发3:四大基本组件的介绍与生命周期 Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver ...

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

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

  7. 17.(转) Android之四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity ...

  8. Android基础_1 四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service(服务),Content Provider(内容提供者),BroadcastReceiver(广播接收器). 一.四大基本组件 Acti ...

  9. 【转】Android四大基本组件介绍与生命周期

    转自:http://www.cnblogs.com/bravestarrhu/archive/2012/05/02/2479461.html Android四大基本组件分别是Activity,Serv ...

  10. android拾遗——四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service服务,Content Provider内容提供者,BroadcastReceiver广播接收器. 一:了解四大基本组件 Activity ...

随机推荐

  1. linux下查看进程占用端口和端口占用进程命令

    Linux下查看进程占用端口: 查看程序对应进程号:ps –ef|grep 进程名 REDHAT :查看进程号所占用的端口号:netstat –nltp|grep 进程号 ubuntu:查看进程占用端 ...

  2. memset的使用

    今天写程序的时候用了memset这个函数,我知道他是关于清空指针的,设置为0.但我用的时候,没有注意到他是以字节为单位进行操作的,改了半天其他程序内容.要注意的是,memset是对字字进行操作,所以以 ...

  3. DataGridView控件中添加ComboBox下拉列表框的实现

    //ComboBox控件拖放到DataGridView控件的某个位置 //添加年龄下拉框 private void BindAge() { //我这里添加的是静态数据,一般都是从数据库读出来的,这里就 ...

  4. javascript 切换动画

    function startMove(obj, json, fn) { clearInterval(obj.timer); obj.timer = setInterval(function() { v ...

  5. 清风注解-Swift程序设计语言:Point11~15

    目录索引 清风注解-Swift程序设计语言 Point 11. 数值型字面量 代码事例: let decimalInteger = // 十进制的17 let binaryInteger = 0b10 ...

  6. .net平台下socket异步通讯(代码实例)

    你应该知道的.net平台下socket异步通讯(代码实例) 1,首先添加两个windows窗体项目,一个作为服务端server,一个作为客户端Client 2,然后添加服务端代码,添加命名空间,界面上 ...

  7. mybatis 基础

    前言 MyBatis作为一款持久层的框架,从最初的ibatis更名,经过五六年的发展更新,如今已经更新到了3.4.5版本.MyBatis通过简单的xml或注解配置,就能将接口和Java的对象映射成数据 ...

  8. oracle 常用(二)

    多表查询: 1.等值连接查询: select a.aa,a.bb,b.qq from XX  a ,   CC  b   where a.aa= b.ee 2.不等值连接: select  *  fr ...

  9. Java第11次实验(数据库)

    参考资料 数据结构实验参考文件 数据库初始化文件 MySQL操作视频 数据库相关jar文件请参考QQ群文件. 第1次实验 1. MySQL数据库基本操作 完整演示一遍登录.打开数据库.建表.插入 常见 ...

  10. nodejs 解决跨域

    1.失败 app.all('*', function (req, res, next) { res.header("Access-Control-Allow-Origin", &q ...