DockOne微信分享(一三六):Kubernetes健康检查策略

简介: 本文讲的是DockOne微信分享(一三六):Kubernetes健康检查策略【编者的话】业务的正常是第一优先保障,所以健康检查是一个重要能力。Kubernetes作为容器编排平台,对于容器以及容器所承载的业务,需要保证其健康,并且在异常情况下能够进行处理。
本文讲的是DockOne微信分享(一三六):Kubernetes健康检查策略【编者的话】业务的正常是第一优先保障,所以健康检查是一个重要能力。Kubernetes作为容器编排平台,对于容器以及容器所承载的业务,需要保证其健康,并且在异常情况下能够进行处理。这次分享将讨论Kubernetes的健康检查策略。 

【烧脑式Kubernetes实战训练营】本次培训理论结合实践,主要包括:Kubernetes架构和资源调度原理、Kubernetes DNS与服务发现、基于Kubernetes和Jenkins的持续部署方案 、Kubernetes网络部署实践、监控、日志、Kubernetes与云原生应用、在CentOS中部署Kubernetes集群、Kubernetes中的容器设计模式、开发Kubernetes原生应用步骤介绍等。

Kubernetes的监控检查支持

在Kubernetes中Pod是最核心的概论,Pod是一个或者多个容器的组合,Pod包含的容器运行在同一台宿主机上,这些容器使用相同的网络命名空间、IP地址和端口,相互之间能通过localhost来发现和通信。另外,这些容器还可共享一块存储卷空间。在Kubernetes中创建、调度和管理的最小单位是Pod,而不是容器,Pod通过提供更高层次的抽象,提供了更加灵活的管理模式,但是同时也增加了健康检查的复杂性。

Pod的生命周期管理

Kubernetes提供了一整套对于Pod的状态机制和生命周期管理,Pod的本质是一组容器,Pod的状态便是容器状态的体现和概括,同时容器的状态变化会影响Pod的状态变化,触发Pod的生命周期阶段转换。

在使用docker run运行容器的时候,首先会下载容器镜像。下载成功后运行容器,当容器运行结束退出后(包括正常和异常退出),容器终止,这是一个容器的生命周期过程。相应的,Kubernetes中对于Pod中的容器进行了状态的记录,其中每种状态下包含的信息如下所示。
  • Waiting:容器正在等待创建,比如正在下载镜像。
  • Running:容器已经创建,并且正在运行。
  • Terminated:容器终止退出。

Pod的生命周期可以简单描述为:首先Pod被创建,紧接着Pod被调度到Node进行部署运行。Pod是非常忠诚的,一旦被分配到Node后,就不会离开这个Node,直到它被删除,生命周期完结。

Pod的生命周期被定义为以下几个阶段。
  • Pending:Pod已经被创建,但是一个或者多个容器还未创建,这包括Pod调度阶段,以及容器镜像的下载过程。
  • Running:Pod已经被调度到Node,所有容器已经创建,并且至少一个容器在运行或者正在重启。
  • Succeeded:Pod中所有容器正常退出。
  • Failed:Pod中所有容器退出,至少有一个容器是一次退出的。

Pod被创建成功后,首先会进入Pending阶段,然后被调度到Node后运行,进入Running阶段。如果Pod中的容器停止(正常或者异常退出),那么Pod根据重启策略的不同会进入不同的阶段,举例如下。

Pod是Running阶段,含有一个容器,容器正常退出:
如果重启策略是Always,那么会重启容器,Pod保持Running阶段。
如果重启策略是OnFailure,Pod进入Succeeded阶段。
如果重启策略是Never,Pod进入Succeeded阶段。

Pod是Running阶段,含有一个容器,容器异常退出:
如果重启策略是Always,那么会重启容器,Pod保持Running阶段。
如果重启策略是OnFailure,Pod保持Running阶段。
如果重启策略是Never,Pod进入Failed阶段。

Pod是Running阶段,含有两个容器,其中一个容器异常退出:
如果重启策略是Always,那么会重启容器,Pod保持Running阶段。
如果重启策略是OnFailure,Pod保持Running阶段。
如果重启策略是Never,Pod保持Running阶段。

Pod是Running阶段,含有两个容器,两个容器都异常退出:
如果重启策略是Always,那么会重启容器,Pod保持Running阶段。
如果重启策略是OnFailure,Pod保持Running阶段。
如果重启策略是Never,Pod进入Failed阶段。

一旦被分配到Node,Pod就不会离开这个Node,直到被删除。删除可能是人为地删除,或者被Replication Controller删除,也有可能是当Pod进入Succeeded 或者Failed 阶段过期,被Kubernetes清理掉。总之Pod被删除后,Pod的生命周期就算结束,即使被Replication Controller进行重建,那也是新的Pod,因为Pod的ID已经发生了变化,所以实际上Pod迁移,准确的说法是在新的Node上重建Pod。

健康检查Probe机制

对于Pod是否健康,即Pod中的容器是否健康,默认情况下只是检查容器是否正常运行。但有时候容器正常运行不代表应用健康,有可能应用的进程已经阻塞住无法正常处理请求,所以为了提供更加健壮的应用,往往需要定制化的健康检查。

除此之外,有的应用启动后需要进行一系列初始化处理,在初始化完成之前应用是无法正常处理请求的。如果应用初始化需要较长时间,而实际上容器创建的时间是可以忽略不计的。

默认情况下,Kubernetes发现容器创建成功并运行,就会认为其准备就绪,真实情况是容器里的应用可能还处于初始化阶段,无法正常接受请求。如果用户访问就会得到错误响应,这不是我们希望看到的情况。同样的,我们需要更加精确的检查机制来判断Pod和容器是否准备就绪,从而让Kubernetes判断是否分发请求给Pod。

针对这些需求,Kubernetes中提供了Probe机制,有以下两种类型的Probe。
  • Liveness Probe:用于容器的自定义健康检查,如果Liveness Probe检查失败,Kubernetes将杀死容器,然后根据Pod的重启策略来决定是否重启容器。
  • Readiness Probe:用于容器的自定义准备状况检查,如果Readiness Probe检查失败,Kubernetes将会把Pod从服务代理的分发后端移除,即不会分发请求给该Pod。

Probe支持以下三种检查方法。
  • ExecAction:在容器中执行指定的命令进行检查,当命令执行成功(返回码为0),检查成功。

示例:
exec:
        command:
        - cat
        - /tmp/health

  • TCPSocketAction:对于容器中的指定TCP端口进行检查,当TCP端口被占用,检查成功。

示例:
tcpSocket:
        port: 8080

  • HTTPGetAction: 发生一个HTTP请求,当返回码介于200~400之间时,检查成功。

示例:
httpGet:
        path: /healthz
        port: 8080


结合Supervisor优化问题排查

一般情况下我们是一个容器运行一个进程,即将应用进程的启动命令作为容器的CMD,这样一来当应用进程退出的时候,容器也就退出,可以第一时间发现异常,我们是统一设置 Pod中容器的重启策略为Always, Kubernetes中重启就是重新创建容器,毕竟新建一个容器的成本很低。所以当容器退出的时候,Kubernetes就会重建容器,这样一来就无法查看应用的第一事发现场,因为旧的容器已经被停止了,极端情况下,容器一直在重建,根本无法登陆到容器去排除;因此,我们希望对容器内应用的健康进行监控,并且根据监控情况,做出保留故障现场和故障恢复等策略,为此我们考虑结合Supervisor进行优化。

Supervisor 是由 Python 语言编写、基于 Linux 操作系统的一款服务器管理工具,用于监控服务器的运行,发现问题能立即自动预警及自动重启等。在Linux系统启动之后,第一个启动的用户态进程是/sbin/init ,它的PID是1,其余用户态的进程都是init进程的子进程。Supervisor在docker容器里面充当的就类似init进程的角色,其它的应用进程都是Supervisor进程的子进程。

Supervisor维护着进程的状态机,并且支持着丰富的重启策略。
  • autostart=true; 如果是true的话,子进程将在supervisord启动后被自动启动默认就是true 。
  • autorestart=unexpected; 这个是设置子进程挂掉后自动重启的情况,有三个选项,false、unexpected和true。如果为false的时候,无论什么情况下,都不会被重新启动,如果为unexpected,只有当进程的退出码不在下面exitcodes里面定义的退出码的时候,才会被自动重启。当为true的时候,只要子进程挂掉,将会被无条件的重启 startsecs=1; 这个选项是子进程启动多少秒之后,此时状态如果是running,则我们认为启动成功了。
  • startretries=3; 当进程启动失败后,最大尝试启动的次数。。当超过次数后,supervisor将把此进程的状态置为FAIL
  • exitcodes=0,2; 和autorestart=unexpected对应。exitcodes里面的定义的退出码是expected的。

这样一来当进程退出的时候,我们可以利用Supervisor去重启进程,并且当进程已经无法正常运行的时候,还可以保留容器现场,方便登录容器进行问题定位。要注意的是我们使用Supervisor的初衷并不是去支持一个容器运行多个进程,本质上我们要求一个容器只运行一个应用进程(比如Tomcat),然后可以运行几个附属进程(crontab、rsyslog)。

另外当应用异常的时候,更重要的是要能够快速恢复。这时候我们就要利用Kubernetes的Readiness Probe去对Pod进行健康检查,检查的维度最好是以上层业务的健康性为标准,比如业务提供健康状态的Restful API /health。

当Readiness Probe检查失败的时候,Pod就设置为NotReady状态,为了保证业务是不中断的,我们可以新建一个Pod出来顶替,当然如果新建的Pod仍是异常,就没必要一直新建了。

整体来说利用Supervisor和Kubernetes Readiness Probe来优化问题排查的支持,逻辑图:
QQ截图20170809170514.png

Q&A

Q:请问Pod的状态是crashbackoff 除了下载镜像失败有哪些可能? 下载的镜像能否指定registry? pod如果有一个容器是exit 0, 那是否就是您之前提到的succeed? 使用livenessProbe检测失败的是failed还是crashbackoff?
A:Crashbackoff大部分情况下是容器的启动命令失败,比如tomcat启动失败了,初学者比较容器犯的错误是CMD的命令是一个非阻塞命令,这样容器一运行就马上退出了。下载的镜像可以指定registry,根据镜像的命令来的,比如 test.registry.com/image:version。容器exit 0了,得根据重启策略来判断。而livenessProbe检测是业务层面的检测。
Q:请问readinessProbe检测失败后,是手动Scale添加Pod确保业务稳定还是可以在ReplicationController的yaml里面定义?
A:这部分 Kubernetes并不支持,是我们自己准备开发的功能。就是发现Pod NotReady后,一来保留问题容器,二来新增一个Pod顶替。
Q:请问Supervisord是手动在Pod里面的容器里面添加么? 还是有专门的镜像已经自带?谢谢! 容器出错后收集的现场信息都保存在哪里?
A:Supervisord就安装到容器里面就行了,比如我们是CentOS基础镜像,然后yum install即可。当进程异常的时候,Supervisord可以重启进程并且保证容器不会退出,这样一来就可以登录到容器里面排查问题,信息的话根据组件的情况来定了。
Q:请问,如果一个deployment有三个副本,分别部署再三个Node上,当其中一个Node宕机了,这时候对应的service中的endpoint更新需要一定的时间,用户在这个时间段访问就会有1/3的错误可能,这种情况怎么办?
A:当Pod异常的时候,比如是NotReady,Service的endpoint了马上就会剔除这个Pod了。Kubernetes的实现都是实时watch的。
Q:保留容器现场如果造成多个僵尸容器怎么办?
A:当Pod NotReady的时候,新建Pod顶替,新建的Pod也异常的话,就不能一直重建。然后定位完成后,只能手动去清理Pod了。
Q:用Supervisor来启动服务,应用的日志是打到指定的目录的还是直接std输出然后再处理的啊?
A:应用的日志打印到文件处理。Stdout被Supervisor占用了
Q: 一个容器里面推荐只跑一个进程,对于遇到一个项目要跑多个服务的情况,是每个服务都单独生成一个容器吗?如果是这样的话代码是怎么管理的?每个服务一个分支吗?而且往往开发、测试、生产是不同的分支,这样服务多了的话对于代码管理很麻烦,如果一个容器里面用Supervisor来跑多个进程的话理论上可以,但是显然做法不好。
A:每个服务可以做成一个容器。那这个是管理的成本了,可以通过一些工具和脚本来自动化。至于要不要跑多进程,看实际场景,都是可以的,其实只要保证Pod提供的业务是正常的即可,所以我们用Probe来对业务检查,
Q:请问Kubernetes的应用的日志是怎么管理的,用的网络文件系统还是其他的方式?
A:我们是要求应用的日志全部输出到指定目录,比如/var/log。然后我们针对容器里面的日志目录统一挂载到Ceph存储。
Q:是否可以通过preStop元素在pod failed被移除前执行一些收集现场信息的命令?
A:也是可以的。但是大部分人定位问题还是希望能够登录到容器里面定位,这样是最快最方便的方式。
Q:Supervisor的方式打乱了Kubernetes原来的容器重启方式,可能会带来更大的问题。不如考虑在Kubernetes的基础上修改增强。
A:是个问题。可以说Supervisor就覆盖了Kubernetes的重启方式,但是一方面Supervisor的重启方式更加灵活,另一方面修改Kubernetes的话侵入性比较大。所以我们选择用Supervisor。
Q:你们的应用日志统一挂载存储的话,存储上是为每个容器新建一个目录吗?
A:这部门我们是修改了Kubernetes的代码,为每个pod在宿主机创建一个目录,然后宿主机的这个目录是挂载Cephfs的。
Q:假如APP不能正常进行业务处理(连不上数据等原因),而health check依然正常返回。怎么办?你们会强制要求开发对APP的状态进行管理,在health check里返回吗?
A:这是个好问题。我们会尽量要求应用提供的health接口尽量准确,但是这也很难保证100%的业务正常,所以目前就是需要权衡,这部门我们也在细化中。

以上内容根据2017年08月08日晚微信群分享内容整理。分享人吴龙辉,网宿科技云计算架构师,负责设计开发PaaS平台,《Kubernetes实战》作者。 DockOne每周都会组织定向的技术分享,欢迎感兴趣的同学加微信:liyingjiesa,进群参与,您有想听的话题或者想分享的话题都可以给我们留言。

原文发布时间为:2017-08-09

本文作者: DockOne

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:DockOne微信分享(一三六):Kubernetes健康检查策略

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
4月前
|
Kubernetes Cloud Native 应用服务中间件
云原生|kubernetes|networkPolicy网络策略详解
云原生|kubernetes|networkPolicy网络策略详解
34 0
|
6月前
|
Kubernetes 网络协议 前端开发
k8s更新策略-系列文章第一篇:蓝绿发布
k8s更新策略-系列文章第一篇:蓝绿发布
|
1月前
|
存储 Kubernetes 监控
Kubernetes(k8s)集群健康检查常用的五种指标
Kubernetes(k8s)集群健康检查常用的五种指标
86 1
|
8月前
|
存储 Kubernetes 数据安全/隐私保护
kubernetes 中pv的回收策略
在Kubernetes中,持久卷(Persistent Volume,PV)的回收策略可以通过`persistentVolumeReclaimPolicy`字段来定义。这个字段有以下几个可选值:1. `Retain`:保留持久卷,不进行自动回收。当持久卷使用完成后,需要手动进行清理和释放。2. `Delete`:删除持久卷,当持久卷不再被使用时,Kubernetes会自动删除并释放它。3. `Recycle`:回收持久卷,当持久卷不再被使用时,Kubernetes会自动进行回收操作。这种回收策略主要适用于一些旧的存储后端,它会尝试清空持久卷中的数据,但不会保证数据安全。需要注意的是,`Recy
298 0
|
4月前
|
Kubernetes Cloud Native 调度
云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度
云原生|kubernetes |一文带你搞懂pod调度策略,驱逐策略,污点、容忍调度
218 0
|
4月前
|
Kubernetes 容器 Perl
k8s学习-CKA真题-网络策略NetworkPolicy
k8s学习-CKA真题-网络策略NetworkPolicy
39 0
|
5月前
|
Kubernetes 网络协议 API
k8s教程(pod篇)-生命周期、重启策略及健康检查
k8s教程(pod篇)-生命周期、重启策略及健康检查
66 0
|
8月前
|
Kubernetes 容器 Perl
k8s--重启策略
k8s--重启策略
|
10月前
|
Kubernetes 监控 网络协议
【探索 Kubernetes|作业管理篇 系列 10】Pod 健康检查和恢复机制
【探索 Kubernetes|作业管理篇 系列 10】Pod 健康检查和恢复机制
117 0
|
11月前
|
Kubernetes 网络协议 数据可视化
「容器平台」Kubernetes网络策略101
「容器平台」Kubernetes网络策略101