BetterManEddy

导航

 

来源:https://www.huaweicloud.com/articles/9c37d95d5ac2cb2e211c9d8cc3bc7c83.html

一、序言

  当你使用kuberentes的时候,有没有遇到过Pod在启动后一会就挂掉然后又重新启动这样的恶性循环?你有没有想过kubernetes是如何检测pod是否还存活?虽然容器已经启动,但是kubernetes如何知道容器的进程是否准备好对外提供服务了呢?让我们通过来一探究竟。首先pod在kubernetes中有5个状态,我们大体了解一下这5个状态,如下表:

名称 描述
Pending 系统已经接受pod实例的创建,但其中所包含容器的一个或者多个image还没有创建成功。Pending包含调度计算与通过网络创建image,所以此phase的时间可能会有点长。
Running Pod已经被调度到某个node上,pod包含的所有容器已经创建完成,至少有一个容器正常运行或者处于启动与重启动过程。
Succeeded  Pod中的所有容器正常终止,并且不会再次启动。
Failed Pod中所有容器已终止运行,至少有一个容器非正常结束,比如退出码非零,被系统强制杀死等。
Unknow  无法取得pod状态,一般是网络问题引起。

我们可以通过kubectl describe pods {podName}来查看status状态,了解到pod状态以后,达到这个状态的过程是如何呢?pod的生命周期到底是如何的呢?我们下面来一探究竟。

二、pod的生命周期

pod周期的过程如下5步:

1.初始化容器阶段初始化pod中每一个容器,他们是串行执行的,执行完成后就退出了

2.启动主容器main container

3.在main container刚刚启动之后可以执行post start命令

4.在整个main container执行的过程中可以做两类探测:liveness probe(存活探测)和readiness probe(就绪探测)

5.在main container结束前可以执行pre stop命令

如下图:

kubernetes(k8s)从入门到精通--pod生命周期及重启策略-第一章-第四节【入门篇】1

 其中liveness probe(存活探测)和readiness probe(就绪探测)、post start 、pre stop我们将详细说明。

三、liveness probe和readiness

定义liveness probe探针

曾经的我在部署海量docker服务时遇到过这样的问题,某台服务器上跑了100个docker服务。有一天有1个docker宕机了,需要重新部署,这时候我花了很多时间找出问题节点并重新删除、安装,这时候我在想如果有一种方式能自动检测并重启,那该多好。

毫无疑问,liveness probe能帮我们解决这个问题,它的作用是确定何时重启容器。例如,当应用程序处于运行状态但无法做进一步操作,liveness探针将捕获到deadlock,重启处于该状态下的容器,使应用程序在存在bug的情况下依然能够继续运行下去(谁的程序还没几个bug呢)。

在K8S中 我们只需在yaml文件中定义liveness probe字段便可解决。如下:

我们在运行容器时执行command命令  touch一个文件,再过60秒后,删除这个文件

然后让liveness probe 每隔5s检测一次,我们将会看到容器在运行一段时间后,restart。

apiVersion: v1
kind: Pod
metadata :
 name: liveness
 namespace: default
spec:
 containers:
 - name: livenesscontainers image: nginx imagePullPolicy: IfNotPresent command: ["/bin/bash","-c","touch /tmp/health;sleep 60;rm -rf /tmp/health;sleep 3600;"] livenessProbe: exec: command: ["test","-e","/tmp/health"] initialDelaySeconds: 1 periodSeconds: 3

其中command: ["test","-e","/tmp/health"] 为探测的命令,如果命令执行成功,将返回0,kubelet就会认为该容器是活着的并且很健康.。

initialDelaySeconds: X (代表开启容器后X秒后再进行生命探测,如果结果为0,kubelet就会杀掉这个容器并重启它。)
periodSeconds: Y (代表每隔Y秒后探测一次)

定义一个liveness HTTP请求

该探针将向容器中的server的8080端口发送一个HTTP GET请求。如果server的/healthz路径的handler返回一个成功的返回码,kubelet就会认定该容器是活着的并且很健康。如果返回失败的返回码,kubelet将杀掉该容器并重启它。

apiVersion: v1
kind: Pod
metadata :
 name: liveness
 namespace: default
spec:
 containers:
 - name: livenesscontainers image: nginx imagePullPolicy: IfNotPresent ports: - name:http containersPort:8080 command: ["/bin/bash","-c","touch /tmp/health;sleep 60;rm -rf /tmp/health;sleep 3600;"] livenessProbe: httpGet: path: /healthz port: http initialDelaySeconds: 3 periodSeconds: 3

定义readiness探针

有时,应用程序暂时无法对外部流量提供服务。 例如,应用程序可能需要在启动期间加载大量数据或配置文件。 在这种情况下,你不想杀死应用程序,但你也不想发送请求。 Kubernetes提供了readiness probe来检测和减轻这些情况。 Pod中的容器可以报告自己还没有准备,不能处理Kubernetes服务发送过来的流量。

Readiness probe的配置跟liveness probe很像。唯一的不同是使用 readinessProbe而不是livenessProbe

readinessProbe:
  exec: command: - cat - /tmp/healthy
  initialDelaySeconds: 5
  periodSeconds: 5

四、postStart和preStop(用的比较少)

   如pod生命周期图,当容器启动以后Kubernetes会发送一个postStart事件,并且在容器退出之前理解发送一个preStop事件。这两个钩子,我们也可以运用起来,比如,您需要在下载github上的文件后再做一些事情....

下面是这个Pod的配置文件:

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container image: nginx lifecycle: postStart: exec: command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"] preStop: exec: command: ["/usr/sbin/nginx","-s","quit"]
posted on 2021-06-15 17:09  BetterManEddy  阅读(217)  评论(0编辑  收藏  举报