Kubernetes入门 五、深入Pod:探针和生命周期

探针

所谓的探针就是容器内应用的监测机制,为了确保容器在部署后确实处在正常运行状态。

比如Pod内的容器因为内存等其他原因挂掉了,但是其实Pod还是在的,但是其实已经不可用了,需要做一定的处理,比如重启(基于重启策略)。那么Pod是如何知道容器是否还可用,就是通过存活探针来检测这个容器。

探针类型

可根据不同的探针来判断容器应用当前的状态,有以下三种类型:

LivenessProbe

存活探针。

作用:用于探测容器中的应用是否运行,如果探测失败,kubelet 会根据配置的重启策略进行重启,若没有配置,默认就认为容器启动成功,不会执行重启策略。

配置如下:

livenessProbe:
  failureThreshold: 5
  httpGet:
    path: /health
    port: 8080
    scheme: HTTP
  initialDelaySeconds: 60  # 第一次检测的延迟时间
  periodSeconds: 10  # 间隔时间
  successThreshold: 1  # 检测成功1次就代表成功了
  timeoutSeconds: 5 

注意:如果配置了这个探针,需要注意periodSeconds时间,如果Pod的启动时间大于这个时间,到时间发现还没启动成功,就会出现一直重启的情况。

ReadinessProbe

就绪探针。

作用:探测应用是否启动完成并且处于正常服务状态,它的返回值如果返回 success,那么就认为该容器已经完全启动,并且该容器是可以接收外部流量的,如果不正常则不会接收来自 Kubernetes Service 的流量,即将该Pod从Service的endpoint中移除。

readinessProbe:
  failureThreshold: 3 # 错误次数
  httpGet:
    path: /ready
    port: 8181
    scheme: HTTP
  periodSeconds: 10 # 间隔时间
  successThreshold: 1
  timeoutSeconds: 1

StartupProbe:

启动探针。

k8s 1.16 版本新增的探针,用于判断应用程序是否已经启动了。

当配置了 startupProbe 后,会先禁用其他探针,直到 startupProbe 成功后,其他探针才会继续。

作用:由于有时候不能准确预估应用一定是多长时间启动成功,因此配置另外两种方式不方便配置初始化时长来检测,而配置了 statupProbe 后,只有在应用启动成功了,才会执行另外两种探针,可以更加方便的结合使用另外两种探针使用。

配置如下:

startupProbe:
  httpGet:
    path: /api/startup
    port: 80

探测方式

ExecAction

在容器内部执行一个命令,如果返回值为 0,则任务容器时健康的。

配置如下:

livenessProbe:
  exec:
    command:
      - cat
      - /health

TCPSocketAction

通过 tcp 连接监测容器内端口是否开放,如果开放则证明该容器健康。

配置如下:

livenessProbe:
  tcpSocket:
    port: 80

HTTPGetAction

生产环境用的较多的方式,发送 HTTP 请求到容器内的应用程序,如果接口返回的状态码在 200~400 之间,则认为容器健康。

配置如下:

livenessProbe:
  failureThreshold: 5
  httpGet:
    path: /health
    port: 8080
    scheme: HTTP
    httpHeaders:
      - name: xxx
        value: xxx

参数配置

  1. initialDelaySeconds

初始化延迟时间。即等待这么长时间后才开始探测。一般LivenessProbe和ReadinessProbe探针配置。在一定程度上可以代替StartupProbe探针,但是一般我们是不知道容器到底需要启动多久的,时间设置短了,可能出现前面说的一直重启,设置长了,又有无效等待。所以并不能完全替代StartupProbe探针。

  1. timeoutSeconds

超时时间。即执行检测的时候,如果等待这么多时间还没有返回,就认为失败。

  1. periodSeconds

监测间隔时间。即上次检测完成后,间隔多长时间再去检测。

  1. successThreshold

成功次数阈值。比如配置成1,则认为检查 1 次成功就成功了。

  1. failureThreshold

失败次数阈值。比如配置成3,则认为检查了3次失败就算失败了。如果设置1次,可能不太准确,可能由于网络等其他原因,有延迟,下一次可能就好了。

操作示例

下面我们在上面Nginx的pod 的yaml文件的基础上加上启动探针,如下:

apiVersion: v1 # api 文档版本
kind: Pod  # 资源对象类型,也可以配置为像Deployment、StatefulSet这一类的对象
metadata: # Pod 相关的元数据,用于描述 Pod 的数据
  name: nginx-pod # Pod 的名称
  labels: # 定义 Pod 的标签
    type: app # 自定义 label 标签,名字为 type,值为 app
    test: 1.0.0 # 自定义 label 标签,描述 Pod 版本号
  namespace: 'default' # 命名空间的配置
spec: # 期望 Pod 按照这里面的描述进行创建
  containers: # 对于 Pod 中的容器描述
  - name: nginx # 容器的名称
    image: nginx:1.7.9 # 指定容器的镜像
    imagePullPolicy: IfNotPresent # 镜像拉取策略,指定如果本地有就用本地的,如果没有就拉取远程的
    startupProbe:  # 启动探针
      httpGet:   # 采用http的方式
        path: /api/path  # http的请求路径
        port: 80  # 请求端口
      periodSeconds: 5 # 监测间隔时间
      successThreshold: 1 # 检查 1 次成功就表示成功
      failureThreshold: 3 # 监测失败 2 次就表示失败
      timeoutSeconds: 5  # 超时时间
    command: # 指定容器启动时执行的命令
    - nginx
    - -g
    - 'daemon off;' # nginx -g 'daemon off;'
    workingDir: /usr/share/nginx/html # 定义容器启动后的工作目录
    ports:
    - name: http # 端口名称
      containerPort: 80 # 描述容器内要暴露什么端口
      protocol: TCP # 描述该端口是基于哪种协议通信的
    env: # 环境变量
    - name: JVM_OPTS # 环境变量名称
      value: '-Xms128m -Xmx128m' # 环境变量的值
    resources:
      requests: # 最少需要多少资源
        cpu: 100m # 限制 cpu 最少使用 0.1 个核心
        memory: 128Mi # 限制内存最少使用 128兆
      limits: # 最多可以用多少资源
        cpu: 200m # 限制 cpu 最多使用 0.2 个核心
        memory: 256Mi # 限制 最多使用 256兆
  restartPolicy: OnFailure # 重启策略,只有失败的情况才会重启

上面文件中,我们添加了启动探针,采用的方式是http。

注意,这里故意写了一个不存在的请求路径,为了演示启动探针失败时是神经样子的。

下面创建pod:

kubectl apply -f nginx-pod.yaml

然后查看pod的状态:

kubectl get po

结果如下:

NAME         READY   STATUS    RESTARTS   AGE
nginx-pod    0/1     Running   0          3s

现在状态是非Ready的,然后我们隔一段时间继续查看:

NAME         READY   STATUS    RESTARTS     AGE
nginx-pod    0/1     Running   3 (8s ago)   53s

# 最终的状态如下:
NAME         READY   STATUS      RESTARTS   AGE
nginx-pod    0/1     Completed   3          9m17s

可以看到,RESTARTS是3,也就是重启了3次,而且最终的READY还是0。

下面看下具体的信息:

kubectl describe po nginx-pod

可以看到具体的探针信息:

在这里插入图片描述

然后翻到最后的Events,可以看到最后一行打印出检测失败:

在这里插入图片描述

看完启动失败的情况,再看下检测成功的情况,修改http的请求路径如下:

apiVersion: v1 # api 文档版本
kind: Pod  # 资源对象类型,也可以配置为像Deployment、StatefulSet这一类的对象
metadata: # Pod 相关的元数据,用于描述 Pod 的数据
  name: nginx-pod # Pod 的名称
  labels: # 定义 Pod 的标签
    type: app # 自定义 label 标签,名字为 type,值为 app
    test: 1.0.0 # 自定义 label 标签,描述 Pod 版本号
  namespace: 'default' # 命名空间的配置
spec: # 期望 Pod 按照这里面的描述进行创建
  containers: # 对于 Pod 中的容器描述
  - name: nginx # 容器的名称
    image: nginx:1.7.9 # 指定容器的镜像
    imagePullPolicy: IfNotPresent # 镜像拉取策略,指定如果本地有就用本地的,如果没有就拉取远程的
    startupProbe:  # 启动探针
      httpGet:   # 采用http的方式
        path: /index.html #http的请求路径
        port: 80  # 请求端口
      periodSeconds: 5 # 监测间隔时间
      successThreshold: 1 # 检查 1 次成功就表示成功
      failureThreshold: 3 # 监测失败 2 次就表示失败
      timeoutSeconds: 5  # 超时时间
    command: # 指定容器启动时执行的命令
    - nginx
    - -g
    - 'daemon off;' # nginx -g 'daemon off;'
    workingDir: /usr/share/nginx/html # 定义容器启动后的工作目录
    ports:
    - name: http # 端口名称
      containerPort: 80 # 描述容器内要暴露什么端口
      protocol: TCP # 描述该端口是基于哪种协议通信的
    env: # 环境变量
    - name: JVM_OPTS # 环境变量名称
      value: '-Xms128m -Xmx128m' # 环境变量的值
    resources:
      requests: # 最少需要多少资源
        cpu: 100m # 限制 cpu 最少使用 0.1 个核心
        memory: 128Mi # 限制内存最少使用 128兆
      limits: # 最多可以用多少资源
        cpu: 200m # 限制 cpu 最多使用 0.2 个核心
        memory: 256Mi # 限制 最多使用 256兆
  restartPolicy: OnFailure # 重启策略,只有失败的情况才会重启

然后删除以前的pod,重启创建:

kubectl apply -f nginx-pod.yaml

查看状态:

$ kubectl get po
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          7s

可以看到pod正常创建出来了。

然后查看下下容器的具体信息,也是没有任何问题的。

也可以试下TCP方式和命令行的方式,配置如下:

# 1.tcp方式
startupProbe:  # 启动探针
  tcpSocket:   # 采用tcp的方式
  	port: 80  # 请求端口
  periodSeconds: 5 # 监测间隔时间
  successThreshold: 1 # 检查 1 次成功就表示成功
  failureThreshold: 3 # 监测失败 2 次就表示失败
  timeoutSeconds: 5  # 超时时间
# 2.命令行的方式
startupProbe:  # 启动探针
  exec:   # 采用命令行的方式
  	command:
  	-sh
  	- -c
  	- "sleep 3; echo 'success' > /inited"
  periodSeconds: 5 # 监测间隔时间
  successThreshold: 1 # 检查 1 次成功就表示成功
  failureThreshold: 3 # 监测失败 2 次就表示失败
  timeoutSeconds: 5  # 超时时间

生命周期

钩子函数

钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码。

支持两种钩子:

  • postStart:容器创建之后执行,如果失败会重启容器。
  • preStop:容器终止前执行,常用于资源清理。如果失败,容器同样也会被杀死。

而钩子的回调函数支持两种方式:

  • exec:在容器内执行命令,如果命令的退出状态码是 0 表示执行成功,否则表示失败
  • httpGet:向指定 URL 发起 GET 请求,如果返回的 HTTP 状态码在 [200, 400) 之间表示请求成功,否则表示失败
  • tcpSocket:在当前容器尝试访问指定的 socket 。

postStart不能保证该操作一定在容器的 command 之前执行,一般不使用。

preStop一般用于注册中心下线、数据清理、数据销毁等。

注意:当pod删除时,变为删除中的状态后,会给 pod 一个宽限期,让 pod 去执行一些清理或销毁操作。

配置参数:terminationGracePeriodSeconds: 30

也就是当删除时,会等30s后才真的删除pod,而且删除到30s也不会管preStop有没有执行完,都会删除。

示例:

apiVersion: v1 # api 文档版本
kind: Pod  # 资源对象类型,也可以配置为像Deployment、StatefulSet这一类的对象
metadata: # Pod 相关的元数据,用于描述 Pod 的数据
  name: nginx-pod # Pod 的名称
  labels: # 定义 Pod 的标签
    type: app # 自定义 label 标签,名字为 type,值为 app
    test: 1.0.0 # 自定义 label 标签,描述 Pod 版本号
  namespace: 'default' # 命名空间的配置
spec: # 期望 Pod 按照这里面的描述进行创建
  containers: # 对于 Pod 中的容器描述
  - name: nginx # 容器的名称
    image: nginx:1.7.9 # 指定容器的镜像
    imagePullPolicy: IfNotPresent # 镜像拉取策略,指定如果本地有就用本地的,如果没有就拉取远程的
    lifecycle: # 生命周期配置
    	postStart: # 容器创建之后执行,如果失败会重启容器
      	exec: # 在容器启动的时候,执行一条命令,修改掉Nginx的首页内容
        	command: ["/bin/sh","-c","echo postStart ... > /usr/share/nginx/html/index.html"]
      preStop: # 容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作
        exec: # 在容器停止之前停止Nginx的服务
          command: ["/usr/sbin/nginx","-s","quit"]
    command: # 指定容器启动时执行的命令
    - nginx
    - -g
    - 'daemon off;' # nginx -g 'daemon off;'
    workingDir: /usr/share/nginx/html # 定义容器启动后的工作目录
    ports:
    - name: http # 端口名称
      containerPort: 80 # 描述容器内要暴露什么端口
      protocol: TCP # 描述该端口是基于哪种协议通信的
    env: # 环境变量
    - name: JVM_OPTS # 环境变量名称
      value: '-Xms128m -Xmx128m' # 环境变量的值
    resources:
      requests: # 最少需要多少资源
        cpu: 100m # 限制 cpu 最少使用 0.1 个核心
        memory: 128Mi # 限制内存最少使用 128兆
      limits: # 最多可以用多少资源
        cpu: 200m # 限制 cpu 最多使用 0.2 个核心
        memory: 256Mi # 限制 最多使用 256兆
  restartPolicy: OnFailure # 重启策略,只有失败的情况才会重启

生命周期

Pod的状态(Status)有以下几种:

  • 挂起(Pending):Pod 已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间,这可能需要花点时间。
  • 运行中(Running):该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。
  • 成功(Succeeded):Pod 中的所有容器都被成功终止,并且不会再重启。
  • 失败(Failed):Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。
  • 未知(Unknown):因为某些原因无法取得 Pod 的状态,通常是因为与 Pod 所在主机通信失败。

在这里插入图片描述

一个Pod从启动到结束有如下几个步骤:

  • 初始化容器执行(如果有的话)
  • 执行启动探针
  • 执行command命令(定义在yaml中的command标签下)和postStart钩子函数,两个没有先后顺序
  • 就绪探针和存活探针执行
  • 执行preStop钩子函数
  • 删除Pod

如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rGnKwUuc-1692189492504)(./imgs/5-3.png)]

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值