Kubernetes Liveness and Readiness Probes

简介: 云原生应用程序通常设计为使用微服务架构,其中每个组件都位于容器中。为了确保Kubernetes托管的应用程序高可用,在设计集群时需要遵循一些特定的模式,其中有“健康探测模式”。应用高可观察性原则(HOP)可确保您的应用程序收到的每个请求都能及时找到响应。

在设计关键任务、高可用应用程序时,弹性是要考虑的最重要因素之一。


当应用程序可以快速从故障中恢复时,它便具有弹性。


云原生应用程序通常设计为使用微服务架构,其中每个组件都位于容器中。为了确保Kubernetes托管的应用程序高可用,在设计集群时需要遵循一些特定的模式,其中有“健康探测模式”。应用高可观察性原则(HOP)可确保您的应用程序收到的每个请求都能及时找到响应。


The High Observability Principle (HOP)


高可观察性原则是基于容器的应用程序设计原则之一。微服务体系要求每个服务不关心(也不应该关心)被调用方如何处理请求。


HOP原则要求每个服务必须公开几个API端点,其意义在于揭示服务健康状态,Kubernetes调用这些端点,决定下一步的路由和负载平衡


设计良好的云原生程序应将日志事件记录到STDERR和STDOUT,由logstash、Fluent等日志摄取服务将这些日志运送到集中式监控(例如Prometheus)和日志聚合系统(例如ELK)。下图说明了云原生应用程序如何遵守健康状况探测模式和高可观察性原则。


f34b34c2edd5653a12c2cdc61bc4413c.png


How to Apply Health Probe Pattern in Kubernetes?


我之前写过ASP.NetCore + Docker健康检查的原创:[web程序暴露http健康检查端点,平台轮询探测],Kubernetes针对不同场合细化了探针,更为强大的是给出对应决策。


d7777e9770b497921451cf3923ea49ac.jpg


Liveness Probes


使用[存活探针]判断什么时候重启容器。


使用存活探针检查应用本身是否无响应、死锁, 有时候重启容器常常能解决此类问题。

我们以kubernetes官方demo为例:


apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5   # 指示kubectl等待5s才执行首次探测
      periodSeconds: 5         # 间隔5秒轮询


  • 在第5秒kubectl开始首次liveness探测


  • 在30秒进行的每次探测均成功


  • 30s之后容器内文件被删除,之后间隔5s的探测会失败,根据liveness默认配置连续3次失败就会放弃探测,放弃探测意味着重启容器,故容器会在第45s重启


  • 重启之后又开始以上流程, 故可以看到此探针以重启的决策尝试修复应用问题。


这个探针会体现到kubectl get podRESTARTS


65b5273e00ec30384928440c056fff8c.png


Readiness Probes


使用[就绪探针]判断容器是否就绪,是否可以接受流量。


Pod内所有容器ready,则该Pod被认为ready,当pod没有ready,将会从服务负载均衡中移除。


有些时候,应用程序临时不可用(加载大量数据或者依赖外部服务),这个时候,重启这个Pod无济于事,但你也不希望请求被发送到该Pod


下面的应用强依赖mongodb,我们针对这些依赖项设置了readiness探针


services.AddHealthChecks()
    .AddCheck<MongoHealthCheck>(nameof(MongoHealthCheck), tags: new[] { "readyz" });
// ----------------------
app.UseHealthChecks("/readyz", new HealthCheckOptions
{
        Predicate = (check) => check.Tags.Contains("readyz")
});


以下代码探测Mongodb的连通性


sealed class MongoHealthCheck : IHealthCheck
    {
        private readonly IMongoDatabase _defaultMongoDatabase;
        public MongoHealthCheck(IDefaultMongoDatabaseProvider defaultMongoDatabaseProvider)
        {
            _defaultMongoDatabase = defaultMongoDatabaseProvider.GetDatabase();
        }
        public async Task<HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            var doc = await _defaultMongoDatabase.RunCommandAsync(
                new BsonDocumentCommand<BsonDocument>(
                    new BsonDocument() {
                        { "ping", "1" }
                    }), 
                cancellationToken: cancellationToken);
            var ok = doc["ok"].ToBoolean();
            if (ok)
            {
                return HealthCheckResult.Healthy("OK");
            }
            return HealthCheckResult.Unhealthy("NotOK");
        }
    }


对于依赖项的探测,探测周期和超时时间可以设置的稍长一点


readinessProbe:
  httpGet:
    path: /readyz
    port: 80
  initialDelaySeconds: 5
  periodSeconds: 60     # 60s探测一次
  timeoutSeconds: 30    # 每次探测30s超时,与应用建立与依赖项的连接超时时间一致
  failureThreshold: 3   # 连续3次探测失败,该Pod会被标记为`Unready`


Startup Probes


使用[启动探针]判断容器应用是否已经启动。如果配置了这个探针,则该探针成功之前将会禁用存活和就绪探针。


配置探针


  • initialDelaySeconds:容器启动,探针延后工作,默认是0s


  • periodSeconds 探针探测周期,默认10s


  • timeoutSeconds:探针工作的超时时间,默认1s


  • successThreshold:连续几次探测成功,该探针被认为是成功的,默认1次


  • failureThreshold:连续几次探测失败,该探针被认为最终失败,对于livenes探针最终失败意味着重启,对于readiness探针意味着该pod Unready, 默认3次。


强烈建议根据应用结构合理设置探针参数,避免不切实际的认定失败导致的频繁重启或 Unready。


结束语:


Kubernetes生态这么庞大,为啥单独拎出k8s探针, 是因为k8s探针是与应用程序结构密切相关的机制。就使用方式看:


存活探针:用于快速判断应用进程是否无响应,尝试重启修复;


就绪探针:判断应用及依赖项是否就绪,是否可以分配流量,如果不能就标记Unready,从负载均衡器中移除该Pod。


Kubernetes存活、就绪探针可以极大地提高服务的健壮性和弹性,并提供出色的最终用户体验。


相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务&nbsp;ACK 容器服务&nbsp;Kubernetes&nbsp;版(简称&nbsp;ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情:&nbsp;https://www.aliyun.com/product/kubernetes
相关文章
|
4月前
|
Kubernetes 监控 调度
|
26天前
|
存储 Kubernetes 应用服务中间件
Kubernetes Pod
Kubernetes Pod
81 0
Kubernetes Pod
|
Kubernetes 监控 网络性能优化
Kubernetes Pod 驱逐详解
QoS 等级为 Guaranteed 的 Pod 会在 QoS 等级为 Burstable 的 Pod 之前被驱逐吗?
2110 0
|
4月前
|
存储 Kubernetes 网络协议
Kubernetes Pod 介绍
Kubernetes Pod 介绍
|
11月前
|
存储 JSON Kubernetes
k8s初探(2)-kubernetes Pod(1)
k8s初探(2)-kubernetes Pod(1)
134 0
|
11月前
|
Kubernetes 前端开发 网络协议
k8s初探(2)-kubernetes Pod(2)
k8s初探(2)-kubernetes Pod(2)
134 0
|
12月前
|
Kubernetes API 容器
【kubernetes】kubelet 之 Pod 管理
【kubernetes】kubelet 之 Pod 管理
130 0
|
JSON Kubernetes 监控
kubernetes kubelet Overiview
kubernetes kubelet Overiview
kubernetes kubelet Overiview
|
Kubernetes 应用服务中间件 调度
Kubernetes-Pod介绍(四)-Deployment
在生产的环境中,当我们需要给某个服务升级时候,需要停止与该服务相关的所有应用Pod,然后下载最新应用的镜像并创建新Pod,这样当我们服务的规模很大的时候,会照成长时间的服务不可用,对于这种情况Kubernetes提出了滚动升级和滚动回滚概念来帮助我们解决该问题。
|
存储 Kubernetes 安全
Kubernetes-Pod介绍(-)
Pod是一个或一个以上的 容器(例如Docker容器)组成的,且具有共享存储/网络/UTS/PID的能力,以及运行容器的规范。并且在Kubernetes中,Pod是最小的可被调度的原子单位。