pod健康检查详解(liveness,readiness,滚动更新)

环境介绍

主机 IP地址 服务
master 192.168.1.21 k8s+httpd+nginx
node01 192.168.1.22 k8s
node02 192.168.1.23 k8s

基于[ https://blog.51cto.com/14320361/2464655]() 的实验继续进行

一、Pod的liveness和readiness探针

  Kubelet使用liveness probe(存活探针)来确定何时重启容器。例如,当应用程序处于运行状态但无法做进一步操作,liveness探针将捕获到deadlock,重启处于该状态下的容器,使应用程序在存在bug的情况下依然能够继续运行下去
  Kubelet使用readiness probe(就绪探针)来确定容器是否已经就绪可以接受流量。只有当Pod中的容器都处于就绪状态时kubelet才会认定该Pod处于就绪状态。该信号的作用是控制哪些Pod应该作为service的后端。如果Pod处于非就绪状态,那么它们将会被从service的load balancer中移除。

Probe支持以下三种检查方法:

<1>exec-命令

在用户容器内执行一次命令,如果命令执行的退出码为0,则认为应用程序正常运行,其他任务应用程序运行不正常。

  livenessProbe:
    exec:
      command:
      - cat
      - /home/laizy/test/hostpath/healthy

<2>TCPSocket

将会尝试打开一个用户容器的Socket连接(就是IP地址:端口)。如果能够建立这条连接,则认为应用程序正常运行,否则认为应用程序运行不正常。

livenessProbe:
tcpSocket:
   port: 8080

<3>HTTPGet

调用容器内Web应用的web hook,如果返回的HTTP状态码在200和399之间,则认为应用程序正常运行,否则认为应用程序运行不正常。每进行一次HTTP健康检查都会访问一次指定的URL。

  httpGet: #通过httpget检查健康,返回200-399之间,则认为容器正常
    path: / #URI地址
    port: 80 #端口号
    #host: 127.0.0.1 #主机地址
    scheme: HTTP #支持的协议,http或者https
  httpHeaders:’’ #自定义请求的header

参数说明

initialDelaySeconds:容器启动后第一次执行探测是需要等待多少秒。

periodSeconds:执行探测的频率。默认是10秒,最小1秒。

timeoutSeconds:探测超时时间。默认1秒,最小1秒。

successThreshold:探测失败后,最少连续探测成功多少次才被认定为成功。默认是1。对于liveness必须是1。最小值是1。

探针探测的结果有以下三者之一:

Success:Container通过了检查。
Failure:Container未通过检查。
Unknown:未能执行检查,因此不采取任何措施。

1. LivenessProbe(活跃度)

(1)编写一个livenss的yaml文件

[[email protected] ~]# vim livenss.yaml
kind: Pod
apiVersion: v1
metadata:
  name: liveness
  labels:
    test: liveness
spec:
  restartPolicy: OnFailure
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/test; sleep 60; rm -rf /tmp/test; sleep 300
    livenessProbe:              #存活探测
      exec:                     #通过执行命令来检查服务是否正常
        command:                #命令模式
        - cat
        - /tmp/test
      initialDelaySeconds: 10    #pod运行10秒后开始探测
      periodSeconds: 5           #检查的频率,每5秒探测一次

该配置文件给Pod配置了一个容器。periodSeconds 规定kubelet要每隔5秒执行一次liveness probe。initialDelaySeconds 告诉kubelet在第一次执行probe之前要的等待10秒钟。探针检测命令是在容器中执行 cat /tmp/healthy 命令。如果命令执行成功,将返回0,kubelet就会认为该容器是活着的并且很健康。如果返回非0值,kubelet就会杀掉这个容器并重启它。

(2)运行一下

[[email protected] ~]# kubectl apply -f liveness.yaml 

(3)查看一下

[[email protected] ~]# kubectl get pod -w

Liveness活跃度探测,根据探测某个文件是否存在,来确定某个服务是否正常运行,如果存在则正常,负责,它会根据你设置的Pod的重启策略操作Pod。

2. Readiness(敏感探测、就绪性探测)

ReadinessProbe探针的使用场景livenessProbe稍有不同,有的时候应用程序可能暂时无法接受请求,比如Pod已经Running了,但是容器内应用程序尚未启动成功,在这种情况下,如果没有ReadinessProbe,则Kubernetes认为它可以处理请求了,然而此时,我们知道程序还没启动成功是不能接收用户请求的,所以不希望kubernetes把请求调度给它,则使用ReadinessProbe探针。
ReadinessProbe和livenessProbe可以使用相同探测方式,只是对Pod的处置方式不同,ReadinessProbe是将Pod IP:Port从对应的EndPoint列表中删除,而livenessProbe则Kill容器并根据Pod的重启策略来决定作出对应的措施。
ReadinessProbe探针探测容器是否已准备就绪,如果未准备就绪则kubernetes不会将流量转发给此Pod。
ReadinessProbe探针与livenessProbe一样也支持exec、httpGet、TCP的探测方式,配置方式相同,只不过是将livenessProbe字段修改为ReadinessProbe。

(1)编写一个readiness的yaml文件

[[email protected] ~]# vim readiness.yaml
kind: Pod
apiVersion: v1
metadata:
  name: readiness
  labels:
    test: readiness
spec:
  restartPolicy: Never
  containers:
  - name: readiness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/test; sleep 60; rm -rf /tmp/test; sleep 300
    readinessProbe:
      exec:
        command:
        - cat
        - /tmp/test
      initialDelaySeconds: 10
      periodSeconds: 5

(2)运行一下

[[email protected] ~]# kubectl apply -f readiness.yaml 

(3)查看一下

[[email protected] ~]# kubectl get pod -w

3. 总结liveness和readiness探测

(1)liveness和readiness是两种健康检查机制,k8s将两种探测采取相同的默认行为,即通过判断容器启动进程的返回值是否为零,来判断探测是否成功。

(2)两种探测配置方法完全一样,不同之处在于探测失败后的行为。

? liveness探测是根据重启策略操作容器,大多数是重启容器。

? readiness则是将容器设置为不可用,不接收Service转发的请求。

(3)两种探测方法可建议独立存在,也可以同时存在。用livensess判断是否需要重启,实现自愈;用readiness判断容器是否已经准备好对外提供服务。

二、 检测的应用

1. 在scale(扩容/缩容) 中的应用。

(1)编写一个readiness的yaml文件

[[email protected] ~]# vim hcscal.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: web
spec:
  replicas: 3
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - name: web
        image: httpd
        ports:
        - containerPort: 80
        readinessProbe:
          httpGet:
            scheme: HTTP   #探测的协议
            path: /healthy  #访问的目录
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 5

---
kind: Service
apiVersion: v1
metadata:
  name: web-svc
spec:
  type: NodePort
  selector:
    run: web
  ports:
  - protocol: TCP
    port: 90
    targetPort: 80
    nodePort: 30321

在配置文件中,使用httpd镜像,创建出一个Pod,其中periodSeconds字段指定kubelet每5秒执行一次探测,initialDelaySeconds字段告诉kubelet延迟等待10秒,探测方式为向容器中运行的服务发送HTTP GET请求,请求8080端口下的/healthz, 任何大于或等于200且小于400的代码表示成功。任何其他代码表示失败。

(2) httpGet探测方式有如下可选的控制字段

host:要连接的主机名,默认为Pod IP,可以在http request head中设置host头部。
scheme: 用于连接host的协议,默认为HTTP。
path:http服务器上的访问URI。
httpHeaders:自定义HTTP请求headers,HTTP允许重复headers。
port: 容器上要访问端口号或名称。

(3)运行一下

[[email protected] ~]# kubectl apply -f readiness.yaml 

(4)查看一下

[[email protected] ~]# kubectl get pod -w

[[email protected] ~]# kubectl get pod -o wide

[[email protected] ~]# kubectl get service -o wide

(5)访问一下

[[email protected] ~]# curl  10.244.1.21/healthy

(6)pod在指定目录创建一个文件

[[email protected] ~]# kubectl exec web-69d659f974-7s9bc touch /usr/local/apache2/htdocs/healthy

(7)查看一下

[[email protected] ~]# kubectl get pod -w

2. 在更新过程中的使用

(1)编写一个readiness的yaml文件

[[email protected] ~]# vim app.v1.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 10; touch /tmp/healthy; sleep 3000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

(2)运行一下并记录版本信息

[[email protected] ~]# kubectl apply -f readiness.yaml --record 
查看一下
[[email protected] ~]# kubectl rollout history deployment app 

(3)查看一下

[[email protected] ~]# kubectl get pod -w

3.升级一下Deployment

(1)编写一个readiness的yaml文件

[[email protected] ~]# cp app.v1.yaml app.v2.yaml 
[[email protected] ~]# vim app.v2.yaml 

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 3000        #修改命令
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

(2)运行一下并记录版本信息

[[email protected] ~]# kubectl apply -f readiness.yaml --record 
查看一下
[[email protected] ~]# kubectl rollout history deployment app 

(3)查看一下

[[email protected] ~]# kubectl get pod -w

(4)再次升级一下deployment

<1> 编写一个readiness的yaml文件
[[email protected] ~]# cp app.v1.yaml app.v3.yaml 
[[email protected] ~]# vim app.v2.yaml 

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 3000        #修改命令
<2> 运行一下并记录版本信息
[[email protected] ~]# kubectl apply -f readiness.yaml --record 
查看一下
[[email protected] ~]# kubectl rollout history deployment app 

<3> 查看一下
[[email protected] ~]# kubectl get pod -w

4. 回滚v2版本

[[email protected] ~]# kubectl rollout undo deployment app --to-revision=2

查看一下

[[email protected] ~]# kubectl get pod

(1)编写一个readiness的yaml文件

[[email protected] ~]# vim app.v2.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: app
spec:
  strategy:
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 2
  replicas: 10
  template:
    metadata:
      labels:
        run: app
    spec:
      containers:
      - name: app
        image: busybox
        args:
        - /bin/sh
        - -c
        - sleep 3000
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/healthy
          initialDelaySeconds: 10
          periodSeconds: 5

参数介绍

minReadySeconds:

Kubernetes在等待设置的时间后才进行升级
如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
如果没有设置该值,在某些极端情况下可能会造成服务服务正常运行

maxSurge:

升级过程中最多可以比原先设置多出的POD数量
例如:maxSurage=1,replicas=5,则表示Kubernetes会先启动1一个新的Pod后才删掉一个旧的POD,整个升级过程中最多会有5+1个POD。

maxUnavaible:

升级过程中最多有多少个POD处于无法提供服务的状态
当maxSurge不为0时,该值也不能为0
例如:maxUnavaible=1,则表示Kubernetes整个升级过程中最多会有1个POD处于无法服务的状态。

(2) 运行一下并记录版本信息

[[email protected] ~]# kubectl apply -f app.v2.yaml --record 
查看一下
[[email protected] ~]# kubectl rollout history deployment app 

(3) 查看一下

[[email protected] ~]# kubectl get pod -w

三、小实验

1)写一个Deployment资源对象,要求2个副本,nginx镜像。使用Readiness探测,自定义文件/test是否存在,容器开启之后10秒开始探测,时间间隔为10秒。

(1)编写一个readiness的yaml文件
[[email protected] yaml]# vim nginx.yaml

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: web
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - name: readiness
        image: 192.168.1.21:5000/nginx:v1
        readinessProbe:
          exec:
            command:
            - cat
            - /usr/share/nginx/html/test
          initialDelaySeconds: 10
          periodSeconds: 10
(2)运行一下并记录版本信息
[[email protected] ~]# kubectl apply -f nginx.yaml --record 
查看一下
[[email protected] ~]# kubectl rollout history deployment web 

(3)查看一下
[[email protected] ~]# kubectl get pod -w

2)在运行之后两个Pod里,进入一个Pod,创建文件/test。

[[email protected] yaml]# kubectl exec -it web-864c7cf7fc-gpxq4  /bin/bash
[email protected]:/# touch /usr/share/nginx/html/test

查看一下

[[email protected] yaml]# kubectl get pod -w

3)创建一个Service资源对象,跟上述Deployment进行关联,运行之后,查看Service资源详细信息,确认EndPoint负载均衡后端Pod。

(1)编写service的yaml文件

[[email protected] yaml]# vim nginx-svc.yaml
kind: Service
apiVersion: v1
metadata:
  name: web-svc
spec:
  type: NodePort
  selector:
    run: web
  ports:
  - protocol: TCP
    port: 90
    targetPort: 80
    nodePort: 30321

(2)执行一下

[[email protected] yaml]# kubectl apply -f nginx-svc.yaml 

(3)给两个pod刚更改页面

查看一下pod
[[email protected] yaml]# kubectl get pod -o wide
更改页面
[[email protected] yaml]# kubectl exec -it  web-864c7cf7fc-gpxq4  /bin/bash
[email protected]:/# echo "123">/usr/share/nginx/html/test
[email protected]:/# exit

[[email protected] yaml]# kubectl exec -it  web-864c7cf7fc-pcrs9   /bin/bash
[email protected]:/# echo "321">/usr/share/nginx/html/test
[email protected]:/# exit

4)观察状态之后,尝试将另一个Pod也写入/test文件,然后再去查看SVC对应的EndPoint的负载均衡情况。

(1)查看一下service

[[email protected] yaml]# kubectl get service

(2)访问一下

[[email protected] ~]# curl 192.168.1.21:30321/test

5)通过httpGet的探测方式,重新运行一下deployment资源,总结对比一下这两种Readiness探测方式。

(1)修改deployment的yaml文件

[[email protected] yaml]# vim nginx.yaml
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: web
spec:
  replicas: 2
  template:
    metadata:
      labels:
        run: web
    spec:
      containers:
      - name: readiness
        image: 192.168.1.21:5000/nginx:v1
        readinessProbe:
          httpGet:
            scheme: HTTP
            path: /usr/share/nginx/html/test
            port: 80
          initialDelaySeconds: 10
          periodSeconds: 10

(2)执行一下

[[email protected] yaml]# kubectl apply -f nginx.yaml 

(3)查看一下pod

[[email protected] yaml]# kubectl get pod -w

maxSurge:此参数控制滚动更新过程中,副本总数超过预期数的值。可以是整数,也可以是百分比,默认是1。所以现在是3台pod

(4)访问一下

[[email protected] yaml]# curl 192.168.1.21:30321/test

6)总结对比liveness和readiness探测的相同和不同之处,以及它们的使用场景。

<1>readiness和liveness的核心区别

实际上readiness 和liveness 就如同字面意思。readiness 就是意思是否可以访问,liveness就是是否存活。如果一个readiness 为fail 的后果是把这个pod 的所有service 的endpoint里面的改pod ip 删掉,意思就这个pod对应的所有service都不会把请求转到这pod来了。但是如果liveness 检查结果是fail就会直接kill container,当然如果你的restart policy 是always 会重启pod。

<2>什么样才叫readiness/liveness检测失败呢?

实际上k8s提供了3中检测手段,

http get 返回200-400算成功,别的算失败
tcp socket 你指定的tcp端口打开,比如能telnet 上
cmd exec 在容器中执行一个命令 推出返回0 算成功。
每中方式都可以定义在readiness 或者liveness 中。比如定义readiness 中http get 就是意思说如果我定义的这个path的http get 请求返回200-400以外的http code 就把我从所有有我的服务里面删了吧,如果定义在liveness里面就是把我kill 了。

<3>readiness和readiness的使用环境

比如如果一个http 服务你想一旦它访问有问题我就想重启容器。那你就定义个liveness 检测手段是http get。反之如果有问题我不想让它重启,只是想把它除名不要让请求到它这里来。就配置readiness。

注意,liveness不会重启pod,pod是否会重启由你的restart policy(重启策略)控制。

参考:
https://www.jianshu.com/p/16a375199cf2

原文地址:https://blog.51cto.com/14320361/2466479

时间: 2024-08-30 17:03:52

pod健康检查详解(liveness,readiness,滚动更新)的相关文章

kubernetes之pod健康检查

目录 kubernetes之pod健康检查 1.概述和分类 2.LivenessProbe探针(存活性探测) 3.ReadinessProbe探针(就绪型探测) 4.探针的实现方式 4.1.ExecAction 4.2.HTTPGetAction 4.3.TCPSocketAction 5.探测行为属性 6.扩展的探测机制 kubernetes之pod健康检查 1.概述和分类 pod通过两类探针来检查容器的健康状态.分别是LivenessProbe(存活性探测)和ReadinessProbe(就

PySide2(PyQt5) 实现tab切换及方法详解(不定时更新)

更多分享:www.catbron.cn tab的实现用到的是QTabWidget控件,以下仅做简单的演示 源码: import sys from PySide2 import QtCore, QtGui, QtWidgets class MainWindow(): def __init__(self): self.window = QtWidgets.QMainWindow() self.initSize(0.6) self.mainWidget = QtWidgets.QWidget() se

k8s探测机制之pod健康检查

一:需求来源: 首先来看一下,整个需求的来源:当把应用迁移到 Kubernetes 之后,要如何去保障应用的健康与稳定呢?其实很简单,可以从两个方面来进行增强: 1,首先是提高应用的可观测性:2,第二是提高应用的可恢复能力. 从可观测性上来讲,可以在三个方面来去做增强: 1,首先是应用的健康状态上面,可以实时地进行观测:2,第二个是可以获取应用的资源使用情况:3,第三个是可以拿到应用的实时日志,进行问题的诊断与分析. 当出现了问题之后,首先要做的事情是要降低影响的范围,进行问题的调试与诊断.最后

pod健康检查(LivenessProbe和ReadinessProbe)

LivenessProbe:用于判断容器是否存活(running状态),如果LivenessProbe探针探测到容器不健康,则kubelet杀掉该容器,并根据容器的重启策略做相应的处理.如果一个容器不包含LivenessProbe探针,则kubelet认为该容器的LivenessProbe探针返回的值永远是“Success”. ReadinessProbe:用于判断容器是否启动完成(ready状态),可以接收请求.如果ReadinessProbe探针检测到失败,则Pod的状态被修改.Endpoi

5 详解MySQL数据库之更新语句

用于操作数据库的SQL一般分为两种,一种是查询语句,也就是我们所说的 SELECT语句,另外一种就是更新语句,也叫做数据操作语句.言外之 意,就是对数据进行修改.在标准的SQL中有3个语句,它们是INSERT.UPDATE以及DELETE.在MySQL中又多了一个REPLACE语句,因此,本文以MySQL为背景来讨论如何使有SQL中的更新语句. 一.INSERT和REPLACE INSERT和REPLACE语句的功能都是向表中插入新的数据.这两条语句的语法类似.它们的主要区别是如何处理重复的数据

doraemon的python django框架的路由详解(国庆大更新)

### 11.8 路由 #### 11.8.1 urlconf ```python from django.conf.urls import url from app01 import views urlpatterns = [ url(r'^admin/',admin.site.urls), #这里用到了正则 url(r'^home',views.home,{},name='home'), ] ``` #### 11.8.2 分组和命名分组 url上捕获的都是字符串 分组 ```python

Knative Serving 健康检查机制分析

作者|??阿里云智能事业群技术专家牛秋霖(冬岛) 导读:从头开发一个 Serverss 引擎并不是一件容易的事情,今天咱们就从 Knative 的健康检查说起.通过健康检查这一个点来看看 Serverless 模式和传统的模式都有哪些不同,以及 Knative 针对 Serverless 场景都做了什么思考. Knative Serving 模块的核心原理如下图所示,图中的 Route 可以理解成是 Istio Gateway 的角色. 当缩容到零时进来的流量就会指到 Activator 上面:

ScrollView详解

创建方式 1:StoryBoard/Xib 这里StoarBoard就不多说,直接拖就可以,说太多没意思,如果连这个都不会我只能先给你跪了! 2:代码: 1 2 3 CGRect bounds = [ [ UIScreen mainScreen ] applicationFrame ] ; UIScrollView* scrollView = [ [UIScrollView alloc ] initWithFrame:bounds ]; 当你创建完滚动视图后,你可以将另一个视图的内容粘合到滚动视

iOS开发——UI篇&amp;ScrollView详解

ScrollView详解 创建方式 1:StoryBoard/Xib 这里StoarBoard就不多说,直接拖就可以,说太多没意思,如果连这个都不会我只能先给你跪了! 2:代码: CGRect bounds = [ [ UIScreen mainScreen ] applicationFrame ] ; UIScrollView* scrollView = [ [UIScrollView alloc ] initWithFrame:bounds ]; 当你创建完滚动视图后,你可以将另一个视图的内