• 17、Health Check 健康检查


    强大的自愈能力是kubernetes容器编排引擎的重要特性。 自愈的默认实现方式是自动重启发生故障的容器。除此之外,还可通过 Liveness和Readiness探测机制设置更精细的健康检查,进而实现如下要求:
    1. 零停机部署
    2. 避免部署无效的镜像
    3. 更加安全的滚动升级

    一、Liveness探测 VS Readiness探测

    1. Liveness探测和Readiness探测是两种healthy check机制,若不特意配置,kubernetes将对两种探测采取相同的默认行为,即通过判断容器启动进程的返回值( echo $?)是否为零来判断探测是否成功。
    2. 两种探测的配置方法完全一样,支持的配置参数也一样。 不同之处在于探测失败后的行为:Liveness 探测是重启容器;Readiness 探测则是将容器设置为不可用,不接收 Service 转发的请求
    3. Liveness 探测和 Readiness 探测是独立执行的,二者之间没有依赖,所以 可以单独使用,也可以同时使用用 Liveness 探测判断容器是否需要重启以实现自愈;用 Readiness 探测判断容器是否已经准备好对外提供服务

    1.1、每类探针都支持三种探测方法

    • exec: 通过执行命令来检查服务是否正常, 针对复杂检测或无 HTTP 接口的服务, 命 令返回值为 0 则表示容器健康。
    • httpGet : 通过发送 http 请求检查服务是否正常, 返回 200-400 状态码则表明容器健 康。
    • tcpSocket : 通过容器的 IP 和 Port 执行 TCP 检查, 如果能够建立 TCP 连接, 则表明 容器健康。

    1.2、探针探测的结果

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

    1.3、Pod 重启策略 restartpolicy

    • Always: 总是重启
    • OnFailure: 如果失败就重启
    • Never: 永远不重启

    二、默认的健康检查

    每个容器启动时都会执行一个进程,此进程由Dockerfile的CMD或ENTRYPOINT指定。如果 进程退出时返回码非零,则认为容器发生故障,kubernetes会根据restartPolicy重启容器。
    模拟容器发生故障的场景,Pod配置文件如下:
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4.   name: healthcheck
    5.   labels:
    6.     test: healthcheck
    7. spec:
    8.   restartPolicy: OnFailure # 默认为Always
    9.   containers:
    10.   - name: healthcheck
    11.     image: busybox
    12.     args:
    13.     - /bin/sh
    14.     - -c
    15.     - sleep 10; exit 1   # 模拟容器启动 10 秒后发生故障
    可见容器当前已经重启了3次。
    上述例子是容器进程返回值非0,kubernetes认为容器发生故障,重启。但在某些时候进程并不会退出,比如访问 Web 服务器时显示 500 内部错误,可能是系统超载,也可能是资源死锁,此时进程并没有异常退出,在这种情况下重启容器可能是最直接最有效的解决方案,那我们如何利用 Health Check 机制来处理这类场景呢?-----答案就是 Liveness 探测

     2.1、Liveness探测

    Liveness探测让用户自定义判断容器是否健康的条件,若探测失败,kubernetes就会重启容器。
    Pod配置文件如下:
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4.   name: liveness
    5.   labels:
    6.     test: liveness
    7. spec:
    8.   restartPolicy: OnFailure # 默认为Always
    9.   containers:
    10.   - name: liveness
    11.     image: busybox
    12.     args:
    13.     - /bin/sh
    14.     - -c
    15.     - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    16.     livenessProbe:
    17.       exec:
    18.         command:
    19.         - cat
    20.         - /tmp/healthy
    21.       initialDelaySeconds: 10 # 指定容器启动10s后开始执行Liveness探测
    22.       periodSeconds: 5 # 指定每5s执行一次Liveness探测,默认是10s,最小是1s
    23.      timeoutSeconds: 1 # 探测超时时间,默认是1s,最小是1s

    启动进程首先创建文件/tmp/healthy,30s后删除,如果/tmp/healthy文件存在,则认为容器处于正常状态,反之则发生故障。

    livenessProbe部分定义如何执行Liveness探测:
    1. 探测的方法:通过cat检查/tmp/healthy文件是否存在。若命令执行成功,返回值为0,kubernetes则认为本次Liveness探测成功;若命令返回值非0,本次Liveness探测失败;
    2. initialDelaySeconds:10,指定容器启动10s后开始执行Liveness探测,一般会根据应用启动的准备时间来设置。比如某个应用正常启动要花 30 秒,那么 initialDelaySeconds 的值就应该大于 30;
    3. periodSeconds:5,指定每5s执行一次Liveness探测。 Kubernetes 如果连续执行 3 次 Liveness 探测均失败,则会杀掉并重启容器
    下面创建 Pod liveness:
    从配置文件可知,最开始的 30 秒,/tmp/healthy 存在,cat 命令返回 0,Liveness 探测成功,这段时间 kubectl describe pod liveness 的 Events部分会显示正常的日志:
    35 秒之后,日志会显示 /tmp/healthy 已经不存在,Liveness 探测失败。再过几十秒,几次探测都失败后,容器会被重启。

    2.2、Readiness探测

    用户通过Liveness探测可以告诉kubernetes什么时候通过重启容器实现自愈;
    Readiness探测则是告诉kubernetes什么时候可以将容器加入到Service负载均衡池中,对外提供服务
    readinessProbe探测方法:
    1. exec,通过命令的方式
    2. httpGet,判断成功的方法是http请求返回的代码在200-400之间,若不在此范围,则不接收service请求;每隔 periodSeconds时间探测一次,连续 3次探测失败,容器会从负载均衡中移除,直到下次探测成功加入。探测方式http://[container_ip]:8080/path返回值
    Readiness 探测的 Pod配置文件如下:
    1. apiVersion: v1
    2. kind: Pod
    3. metadata:
    4.   name: readiness
    5.   labels:
    6.     test: readiness
    7. spec:
    8.   restartPolicy: OnFailure # 默认为Always
    9.   containers:
    10.   - name: readiness
    11.     image: busybox
    12.     args:
    13.     - /bin/sh
    14.     - -c
    15.     - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    16.     readinessProbe:
    17.       exec:
    18.         command:
    19.         - cat
    20.         - /tmp/healthy
    21.       initialDelaySeconds: 10 # 指定容器启动10s后开始执行Readiness探测
    22.       periodSeconds: 5 # 指定每5s执行一次Liveness探测
    Pod readiness 的 READY 状态经历了如下变化:
    1. 刚被创建时,READY状态为不可用;
    2. 15s后( initialDelaySeconds+ periodSeconds),第一次进行Readiness探测并成功返回,设置READY为可用;
    3. 30s后,/tmp/healthy被删除,连续3次 Readiness探测均失败后,READY被设置为不可用。
    通过 kubectl describe pod readiness 也可以看到 Readiness 探测失败的日志:

    三、在scale up中使用Healthy Check

        针对多副本应用,当执行Scale Up操作时,新副本会作为backend被添加到Service的负载均衡中,与已有副本一起处理客户请求。考虑到应用程序启动需要准备阶段(加载缓存数据、连接db),从容器启动到真正提供服务需要一段时间, 可以通过Readiness探测判断容器是否就绪,避免将请求发送到还没有ready的backend
    示例应用的配置文件
    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4.   name: web-deployment
    5. spec:
    6.   selector: # 通过标签选择被控制的pod
    7.     matchLabels:
    8.       app: web
    9.   replicas: 2
    10.   template:
    11.     metadata:
    12.       labels:
    13.         app: web
    14.     spec:
    15.       containers:
    16.       - name: web
    17.         image: web:1.0
    18.         ports:
    19.         - containerPort: 8080 # 转发到后端pod的端口号
    20.         readinessProbe:
    21.           httpGet:
    22.             scheme: HTTP
    23.             path: /python
    24.             port: 8080
    25.           initialDelaySeconds: 10
    26.           periodSeconds: 5
    27.          
    28. ---
    29. apiVersion: v1
    30. kind: Service
    31. metadata:
    32.   name: web-svc
    33. spec:
    34.   type: NodePort # 添加NodePort类型的Service
    35.   selector:
    36.     app: web
    37.   ports:   # 将 Service 的 8080 端口映射到 Pod 的 8080 端口,使用 TCP 协议
    38.   - protocol: TCP
    39.     port: 8080   # service监听端口
    40.     targetPort: 8080 # 转发到后端pod的端口号
    readinessProbe使用了不同于exec的另一种探测方法: httpGet
    kubernetes对于httpGet方法探测成功的判断条件是http请求的返回代码在200-400之间。
    • schema 指定协议,支持 HTTP(默认值)和 HTTPS。
    • path 指定访问路径。
    • port 指定端口。
    上面配置的作用是:
    1. 容器启动10s后开始探测;
    2. 如果http://container_ip:8080/python返回代码不是200-400,表示容器没有就绪,不接收Service web-svc的请求;
    3. 每隔5s再探测一次;
    4. 直至代码返回200-400,表明容器已经就绪,然后将其加入到web-svc的负载均衡中,开始处理客户请求;
    5. 探测会继续以5s的间隔请求,若连续3次失败,容器又会从负载均衡中移除。直到下次探测成功重新加入。

    四、在Rolling Update中使用Healthy Check

    现有一个正常运行的多副本应用,接下来对应用进行更新(比如使用更高版本的 image),Kubernetes 会启动新副本,然后发生了如下事件:
    1. 正常情况下新副本需要 10 秒钟完成准备工作,在此之前无法响应业务请求。
    2. 但由于人为配置错误,副本始终无法完成准备工作(比如无法连接后端数据库)。
    先别继续往下看,现在请花一分钟思考这个问题:如果没有配置 Health Check,会出现怎样的情况?-------- 因为新副本本身没有异常退出,默认的 Health Check 机制会认为容器已经就绪,进而会逐步用新副本替换现有副本,其结果就是:当所有旧副本都被替换后,整个应用将无法处理请求,无法对外提供服务。如果这是发生在重要的生产系统上,后果会非常严重。
    如果正确配置了 Health Check,新副本只有通过了 Readiness 探测,才会被添加到 Service;如果没有通过探测,现有副本不会被全部替换,业务仍然正常进行。
    示例应用的配置文件
    1. apiVersion: apps/v1
    2. kind: Deployment
    3. metadata:
    4.   name: app
    5. spec:
    6.   selector: # 通过标签选择被控制的pod
    7.     matchLabels:
    8.       app: app
    9.   replicas: 10
    10.   template:
    11.     metadata:
    12.       labels:
    13.         app: app
    14.     spec:
    15.       containers:
    16.       - name: app
    17.         image: busybox
    18.         args:
    19.         - /bin/sh
    20.         - -c
    21.         - sleep 10; touch /tmp/healthy; sleep 30000
    22.         readinessProbe:
    23.           exec:
    24.             command:
    25.             - cat
    26.             - /tmp/healthy
    27.           initialDelaySeconds: 10
    28.           periodSeconds: 5
    10 秒后副本能够通过 Readiness 探测。
  • 相关阅读:
    (附源码)springboot水利机械厂仓储管理系统 毕业设计 091408
    java 上机练习题
    ICCV2021|你以为这是一个填色模型?其实我是检索模型!
    前端开发:4、JavaScript简介、变量与常量、数据类型及内置方法、运算符、流程控制、循环结构、内置方法
    java-net-php-python-ssh电动车销售系统计算机毕业设计程序
    看DevExpress丰富图表样式,如何为基金公司业务创新赋能
    js_字符串
    Spring Cloud - 手写 Gateway 源码,实现自定义局部 FilterFactory
    选择适合户外篷房企业的企业云盘解决方案
    未来的趋势是什么?为什么说先进计算是未来的趋势?
  • 原文地址:https://blog.csdn.net/leiwuhen92/article/details/128074247