一、Health Check介绍

        强大的自愈能力是k8s容器编排引擎一个重要特性,自愈能力的默认实现方式为自动重启发生故障的容器,另外还可以利用Liveness和Readiness探测机制设置更精细的健康检查。

  • 零停机部署
  • 避免部署无效的镜像
  • 更加安全的滚动升级

二、K8S健康检查方式

1、k8s默认的健康检查

       每个容器启动时都会执行一个进程,此进程由Dockerfile的CMD或ENTRYPOINT指定。如果进程退出返回码为非0,则认为容器发生故障,k8s会根据restartPolicy重启容器。

①创建应用测试

apiVersion: v1
kind: Pod
metadata:
name: healthcheck
labels:
test: healthcheck
spec:
restartPolicy: OnFailure
containers:
- name: healthcheck
image: busybox
args:
- /bin/sh
- -c
- sleep ;exit

②Pod的restartPolicy设置为OnFailure,默认策略为Always,执行创建Pod

kubectl apply -f healthcheck.yaml

③过几分钟查看Pod状态,发现容器已经重启了3次

[root@k8s-node1 health_check]# kubectl get pods healthcheck
NAME READY STATUS RESTARTS AGE
healthcheck / Error 3 2m

容器进程返回值非0,k8s则认为容器发生故障,需要重启,有不少场景下发生故障,但进程不会退出,比如访问web服务时发生500内部错误,可能是负载过高,也可能是资源死锁,此时httpd进程并没有异常退出,在这种情况下重启容器可能是最直接、最有效的解决方案,处理此类场景那就用到了k8s的Liveness探测。

2、Liveness探测

 Liveness探测让用户可以自定义判断容器是否健康的条件,如果探测失败,k8s就会重启容器。

①创建应用演示

apiVersion: v1
kind: Pod
metadata:
name: liveness
labels:
test: liveness
spec:
restartPolicy: OnFailure
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep ; rm -f /tmp/healthy; sleep
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds:
periodSeconds:

以上yaml文件说明:启动Pod后首先创建文件/tmp/healthy,30秒后删除,如果文件/tmp/healthy存在,则认为容器处于正常状态,反之发生故障。

探测方法:

  • 通过cat命令检查/tmp/healthy文件是否存在,如果命令执行成功,返回值为0,k8s会认为本次Liveness探测成功;如果命令返回值非0,本次Liveness探测失败
  • initialDelaySeconds: 10 指容器启动10秒后开始执行Liveness探测,如果你的应用启动要花30秒,那么initialDelaySeconds的值就应该大于30。
  • periodSeconds: 5 指每5秒执行一次Liveness探测,k8s如果连续执行3次Liveness探测均失败,则会杀掉重启容器

②创建Pod并查看

kubectl apply -f liveness.yaml
kubectl describe pod liveness

③35秒之后,日志显示/tmp/healthy已经不存在了,Liveness连续几次探测失败,容器会被重启

④再次查看pod,发现已经重启1次

[root@k8s-node1 health_check]# kubectl get pods liveness
NAME READY STATUS RESTARTS AGE
liveness / Running 1 1m

3、Readiness探测

Liveness探测可以告诉k8s什么时候通过重启容器实现自愈;Readiness探测告诉k8s什么时候可以将容器加入到service负载均衡池中,对外提供服务。

①Readiness探测配置与Liveness探测完全一样

apiVersion: v1
kind: Pod
metadata:
name: readiness
labels:
test: readiness
spec:
restartPolicy: OnFailure
containers:
- name: readiness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep ; rm -f /tmp/healthy; sleep
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds:
periodSeconds:

②创建并查看

kubectl apply -f readiness.yaml
[root@k8s-node1 health_check]# kubectl get pod readiness
NAME READY STATUS RESTARTS AGE
readiness / Running 8s [root@k8s-node1 health_check]# kubectl get pod readiness
NAME READY STATUS RESTARTS AGE
readiness / Running 18s [root@k8s-node1 health_check]# kubectl get pod readiness
NAME READY STATUS RESTARTS AGE
readiness / Running 49s

探测方法:

  • 刚创建时,READY状态不可用
  • 15秒后,第一次进行Readiness探测并成功返回,设置READY为可用
  • 30秒后,/tmp/healthy被删除,连续3次Readiness探测失败后,READY被设置为不可用

③查看日志详情

kubectl describe pod readiness

4、Readiness探测与Liveness探测区别

  • Readiness探测与Liveness探测是两种Health Check机制,如果不特意配置,k8s对两种探测采取相同的默认行为,均通过判断容器启动进程的返回值是否为0判断探测是否成功。
  • 两种探测配置方法完全一样,支持的配置参数也一样,不同在于探测失败后,Liveness探测是重启容器,Readiness探测则将容器设置为不可用,不接收service转发的请求
  • Readiness探测与Liveness探测是独立执行的,二者之间没有依赖,可以单独使用,也可以同时使用,用Liveness探测判断容器是否需要重启以实现自愈,用Readiness探测判断容器是否已经准备好对外提供服务

三、Health Check在Scale UP中的应用

            在多副本应用中,当执行Scale Up新增一个副本的场景中,考虑到应用启动需要一些时间,比如加载缓存数据、连接数据库等,这里就可以通过Readiness探测判断容器是否就绪,避免将请求发送到还没准备好的
后端。

1、创建应用测试

apiVersion: apps/v1beta2
kind: Deployment
metadata:
name: web
spec:
replicas:
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: httpd
ports:
- containerPort:
readinessProbe:
httpGet:
scheme: HTTP #指定协议,默认为HTTP
path: /healthy #访问路径
port:
initialDelaySeconfs:
periodSeconds:
---
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
app: web
ports:
- protocol: TCP
port:
targetPort:

注:这里使用了不同与exec的另一种探测方法httpGet,k8s对该方法探测成功的判断是http请求返回码在200~400之间

2、上面配置作用

  • 容器启动10秒后开始探测
  • 如果http://[container_ip]:8080/healthy返回码不是200~400,表示容器没有就绪,不接收Service web-svc的请求。
  • 每隔5秒探测一次
  • 直到返回码为200~400,表明容器已经就绪,然后将其加入到web-svc的负载中,开始处理请求。
  • 探测继续以5秒的间隔执行,如果连续3次失败,容器会从负载中移除,直到再次探测成功后重新加入负载

四、Health Check在滚动更新中的应用

            Health Check另一个重要场景就是滚动更新,现有一个正常运行的多副本应用,接下来要对应用进行更新,比如升级成高版本的image,k8s会启动新副本的过程如下:

  • 正常情况一下启动的新副本需要10秒左右完成准备工作,在此之前无法响应业务请求
  • 由于人为配置错误,副本始终无法完成准备工作,比如无法连接后端的数据库
生产环境中,如果没有配置Health Check,默认Health Check机制会认为容器已经就绪,进行会逐步用新副本替换现有副本,当所有旧副本都被替换后,整个应用将无法处理请求,无法提供服务,
如果正确配置了Health Check,新副本只有通过了Readiness探测才会被添加到Service,如果探测不成功,现有副本不会被会部替换,业务仍然正常进行。

1、创建应用测试

kubectl apply -f app-v1.yaml --record
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas:
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep ; touch /tmp/healthy; sleep
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds:
periodSeconds:

2、10秒后查看所有副本通过了Readiness探测

[root@k8s-node1 health_check]# kubectl get deployment app
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
app 7m
[root@k8s-node1 health_check]# kubectl get pods
NAME READY STATUS RESTARTS AGE
app-58594c894-4bfzn / Running 6m
app-58594c894-5wnxv / Running 6m
app-58594c894-9jspd / Running 6m
app-58594c894-bmgp9 / Running 6m
app-58594c894-d8r72 / Running 6m
app-58594c894-k42zf / Running 6m
app-58594c894-rvnpl / Running 6m
app-58594c894-ssg9w / Running 6m
app-58594c894-z2qd6 / Running 6m
app-58594c894-zb6d8 / Running 6m

3、进行滚动更新,创建app-v2.yaml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
replicas:
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds:
periodSeconds:

4、验证新副本中不存在/tmp/healthy,能否通过Readiness探测

[root@k8s-node1 health_check]# kubectl get deployment app
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
app 1h
#DESIRED 10:表示期望状态是10个副本
#CURRENT 13: 表示当前副本总数,8个旧副本+5个新副本
#UP-TO-DATE 5:表示当前已完成更新的副本数
#AVAILABLE 8:表示当前处于可用的副本数
[root@k8s-node1 health_check]# kubectl get pods
NAME READY STATUS RESTARTS AGE
app-58594c894-4bfzn / Running 1h
app-58594c894-5wnxv / Running 1h
app-58594c894-9jspd / Running 1h
app-58594c894-bmgp9 / Running 1h
app-58594c894-d8r72 / Running 1h
app-58594c894-k42zf / Running 1h
app-58594c894-ssg9w / Running 1h
app-58594c894-z2qd6 / Running 1h
app-67f89fbd77-4fkq5 / Running 1m
app-67f89fbd77-7fgjg / Running 1m
app-67f89fbd77-krf8w / Running 1m
app-67f89fbd77-r25rx / Running 1m
app-67f89fbd77-wdrsr / Running 1m

5、为什么新创建副本数是5个,同时只销毁2个旧副本

  • 1、maxSurge
  • 此参数控制滚动更新过程中副本总数超过DESIRED的上限,默认值为25%,也可以是具体的整数,上面例子中,DESIRED为10,副本总数CURRENT最大值即为:10+10*25%=13,maxSurge值越大,初始创建的新副本就越多。
  • 2、maxUnavailable
  • 此参数控制滚动更新过程中,不可用的副本占DESIRED的最大比例。同样maxUnavailable默认值也为25%,那么可用的副本至少为10-10*25%=8,maxUnavailable值越大,初始销毁的副本数量就越多

6、正常滚动更新过程

  • 创建3个新副本使副本总数达到13个
  • 销毁2个旧副本使可用的副本数降到8个
  • 当2个旧副本成功销毁后,再创建2个新副本,保持副本总数为13个
  • 当新副本通过Readiness探测后,会使可用副本数增加,超过8个
  • 进而可以继续销毁更多的副本,使可用副本数回到8
  • 旧副本的销毁使副本总数低于13,这样可以继续创建新的副本
  • 这个过程一直持续进行,最终所有的旧副本被新副本替换,滚动更新完成
  • 如果滚动更新失败,使用命令kubectl rollout undo deployment app快速回滚到上一版本

7、自定义maxSurge和maxUnavailable

apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: app
spec:
strategy:
rollingUpdate:
maxSurge: %
maxUnavailable: %
replicas:
template:
metadata:
labels:
run: app
spec:
containers:
- name: app
image: busybox
args:
- /bin/sh
- -c
- sleep ; touch /tmp/healthy; sleep
readinessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds:
periodSeconds:

linux运维、架构之路-K8s健康检查Health Check的更多相关文章

  1. linux运维架构师职业规划

    1.假如你从来未接触过Linux的话,首先要做的就找一本指导书来学习.现在公认的Linux的入门书籍是“鸟哥的私房菜”,讲的很全面,鸟哥的私房菜一共分为两部,一部是基础篇,一部是服务器篇.“鸟哥的私房 ...

  2. linux运维面试前,先来检查这些基础知识忘了没?

    知乎上有这样一个问题:一个新手面试 Linux 运维工作至少需要知道哪些知识?其中有一个答案对这一话题的解读非常深入,今天特别分享给大家. 一.什么是大型网站运维? 首先明确一下,全文所讲的”运维“是 ...

  3. 从苦逼到牛逼,详解Linux运维工程师的打怪升级之路

    做运维也快四年多了,就像游戏打怪升级,升级后知识体系和运维体系也相对变化挺大,学习了很多新的知识点. 运维工程师是从一个呆逼进化为苦逼再成长为牛逼的过程,前提在于你要能忍能干能拼,还要具有敏锐的嗅觉感 ...

  4. Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Discuz!

    Nginx+Lua+Redis整合实现高性能API接口 - 网站服务器 - LinuxTone | 运维专家网论坛 - 最棒的Linux运维与开源架构技术交流社区! - Powered by Disc ...

  5. Linux运维企业架构实战系列

    Linux运维企业架构项目实战系列 项目实战1-LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2-LVS.nginx实现负载均衡系列 2.1 项目实战2.1-实现基于LVS负载均衡集 ...

  6. Linux运维企业架构项目实战系列

    Linux运维企业架构项目实战系列 项目实战1—LNMP的搭建.nginx的ssl加密.权限控制的实现 项目实战2—LVS.nginx实现负载均衡系列2.1 项目实战2.1—实现基于LVS负载均衡集群 ...

  7. Linux 运维入门到跑路书单推荐

    一.基础入门 <鸟哥的Linux私房菜基础学习篇>:最具知名度的Linux入门书<鸟哥的Linux私房菜基础学习篇>,全面而详细地介绍了Linux操作系统. https://b ...

  8. linux运维工程师面试题收集

    面试必考 mysql5和mysql6 有什么区别 mysql-server-5.5:默认引擎改为Innodb,提高了性能和扩展性,提高实用性(中继日志自动恢复) mysql-server-5.6:In ...

  9. 面试 Linux 运维工作至少需要知道哪些知识?

    前言 我们已经发过不少 Linux 面试题,但是单独的面试题总感觉会过于零碎,没有体系化内容给人的帮助大. 知乎上有这样一个问题:一个新手面试 Linux 运维工作至少需要知道哪些知识?其中有一个答案 ...

随机推荐

  1. 【VS开发】字符,字节和编码

    字符,字节和编码 [原创文章,转载请保留或注明出处:http://www.regexlab.com/zh/encoding.htm] 级别:中级 摘要:本文介绍了字符与编码的发展过程,相关概念的正确理 ...

  2. (转)python基础学习-----生成器和迭代器

    在Python中,很多对象都是可以通过for语句来直接遍历的,例如list.string.dict等等,这些对象都可以被称为可迭代对象.至于说哪些对象是可以被迭代访问的,就要了解一下迭代器相关的知识了 ...

  3. unsigned char 与unsigned long互换

    unsigned long UCharToULong(unsigned char * pucVar ){unsigned long ulTemp=0;ulTemp=(unsigned long)(*p ...

  4. 第五周课程总结&试验报告三

    第五周课程总结 一.第五周课程总结 1.this关键字 this可用于任何实例方法内指向当前对象,也可指向对其调用当前方法的对象,或者在需要当前类型对象引用时使用.当一个类的属性(成员变量)名与访问该 ...

  5. robot-framework 利用evaluate关键字生成随机数

    robot-framework 利用evaluate关键字生成随机数 最近用RF(robot-framework简称)操作MangoDB,需要直接将数据写到数据库里,又不想每次写的数据完全相同,就想到 ...

  6. SqlServer中union 和 union all的区别

    ⒈UNION和UNION ALL关键字都是将两个结果集合并为一个,但这两者从使用和效率上来说都有所不同.⒉对重复结果的处理:UNION在进行表链接后会筛选掉重复的数据,UNION ALL不会去除重复的 ...

  7. redis在php中实际应用-list

    1.LPUSH Redis Lpush 命令将一个或多个值插入到列表头部. 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作. 当 key 存在但不是列表类型时,返回一个错误.(在Re ...

  8. python_0基础开始_day13

    第十三节 一,匿名函数 匿名函数 == 一行函数 lambda == def == 关键字 函数体中存放的是代码 生成器体中存放的也是代码 就是yield导致函数和生成器的结果不统一 lambda x ...

  9. 二维数组中的查找——牛客剑指offer

    题目描述: 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整 ...

  10. MySQL性能优化(四):SQL优化

    原文:MySQL性能优化(四):SQL优化 版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/ ...