• Kubernetes的Startup, Liveness, Readiness深入探索

    云管理服务专家新钛云服祝祥原创

    Kubernetes在增加了云部署的可扩展性、可移植性和可观察性的同时,也增加了故障风险。虽然它带来了一个具有强大功能和选择的生态系统,以及简化了复杂的应用部署,但它也面临着很多的挑战。Kubernetes给我们带来的一个重要特性就是高可用性。

    Kubernetes中有许多高可用性选项。在本文中,我们将讨论用于应用程序/微服务本身的高可用性选项。Pods是Kubernetes中最小的可部署单元,一旦应用了声明式配置,Pods就会被调度。Kube-scheduler负责计算和调度,一旦调度被接受,它就处于一个受控和计算的环境中,根据pod条件,它被视为服务就绪或不就绪。通过使用startup、readiness和liveness探针,我们可以控制pod何时应该被视为已启动、准备就绪或处于活动状态。我们将探讨这些条件和触发因素。

    Pod与Container状态


    Pod具有阶段性和条件性;容器有状态。这些状态属性可以并且将根据探测结果进行更改,因此让我们对其进行研究。

    Pod阶段

    Pod状态对象包括一个阶段字段。这个阶段字段告诉Kubernetes和我们pod的执行周期在那个阶段。

    • Pengding:群集已接受,但尚未配置容器。
    • Running:至少一个容器处于运行,启动或重新启动状态。
    • Succeeded:所有容器退出,状态码为零;pod不会重新启动。
    • Failed:所有容器都已终止,并且至少一个容器的状态代码为非零。
    • Unknown:无法确定容器的状态。

    Pod条件

    除Pod阶段外,还有Pod条件。这些还提供有关Pod所在状态的信息。

    • PodScheduled:已成功选择一个节点来调度Pod,并且调度已完成。
    • ContainersReady:所有容器均已准备就绪。
    • Initialized:启动了初始化容器。
    • Ready: pod能够为请求提供服务;因此它需要包含在服务和负载均衡中。

    我们可以通过kubectl describe pods <POD_NAME>命令查看pod条件。

    示例输出如下:


    Conditions:
    Type             Status
    Initialized       True
    Ready             True
    ContainersReady   True
    PodScheduled     True

    Container States

    容器具有三个简单状态。

    • Waiting:正在运行启动进程。
    • Running:容器正在正常运行。
    • Terminated:容器开始执行,并以成功或失败结束。

    探索Pod对象的状态

    通过Kubernetes get pods -o yaml命令,我们可以从pod对象中看到pod条件和容器状态。


    status:
    conditions:
    – lastProbeTime: null
    lastTransitionTime: “2021-02-08T11:11:53Z”
    status: “True”
    type: Initialized
    – lastProbeTime: null
    lastTransitionTime: “2021-02-08T11:14:20Z”
    status: “True”
    type: Ready
    – lastProbeTime: null
    lastTransitionTime: “2021-02-08T11:14:20Z”
    status: “True”
    type: ContainersReady
    – lastProbeTime: null
    lastTransitionTime: “2021-02-08T11:11:52Z”
    status: “True”
    type: PodScheduled
    containerStatuses:
    – containerID: containerd://7fc67a850ba439f64ecb51a129a2d7dcbc4a3402b253daa3a6827787f7c80e40
    image: docker.io/library/nginx:latest
    imageID: docker.io/library/nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa
    lastState:
    terminated:
    containerID: containerd://c4416e69b7348a7e7be3f7046dc9745dfb38ba537e5b8c06da5020c67b12b3d8
    exitCode: 137
    finishedAt: “2021-02-08T11:14:52Z”
    reason: Error
    startedAt: “2021-02-08T11:14:05Z”
    name: nginx
    ready: true
    restartCount: 1
    started: true
    state:
    running:
    startedAt: “2021-02-08T11:16:28Z”
    hostIP: x.x.x.x
    phase: Running
    podIP: 10.1.239.205
    podIPs:
    – ip: 10.1.239.205
    qosClass: BestEffort
    startTime: “2021-02-08T11:11:53Z”

    如果您更喜欢JSON的输出,则可以使用 kubectl get pods <POD_NAME> -o jsonpath='{.status}’ | jq

    {
    “conditions”: [
    {
    “lastProbeTime”: null,
    “lastTransitionTime”: “2021-02-08T11:11:53Z”,
    “status”: “True”,
    “type”: “Initialized”
    },
    {
    “lastProbeTime”: null,
    “lastTransitionTime”: “2021-02-08T11:14:20Z”,
    “status”: “True”,
    “type”: “Ready”
    },
    {
    “lastProbeTime”: null,
    “lastTransitionTime”: “2021-02-08T11:14:20Z”,
    “status”: “True”,
    “type”: “ContainersReady”
    },
    {
    “lastProbeTime”: null,
    “lastTransitionTime”: “2021-02-08T11:11:52Z”,
    “status”: “True”,
    “type”: “PodScheduled”
    }
    ],
    “containerStatuses”: [
    {
    “containerID”: “containerd://7fc67a850ba439f64ecb51a129a2d7dcbc4a3402b253daa3a6827787f7c80e40”,
    “image”: “docker.io/library/nginx:latest”,
    “imageID”: “docker.io/library/nginx@sha256:10b8cc432d56da8b61b070f4c7d2543a9ed17c2b23010b43af434fd40e2ca4aa”,
    “lastState”: {
    “terminated”: {
    “containerID”: “containerd://c4416e69b7348a7e7be3f7046dc9745dfb38ba537e5b8c06da5020c67b12b3d8”,
    “exitCode”: 137,
    “finishedAt”: “2021-02-08T11:14:52Z”,
    “reason”: “Error”,
    “startedAt”: “2021-02-08T11:14:05Z”
    }
    },
    “name”: “nginx”,
    “ready”: true,
    “restartCount”: 1,
    “started”: true,
    “state”: {
    “running”: {
    “startedAt”: “2021-02-08T11:16:28Z”
    }
    }
    }
    ],
    “hostIP”: “x.x.x.x”,
    “phase”: “Running”,
    “podIP”: “10.1.239.205”,
    “podIPs”: [
    {
    “ip”: “10.1.239.205”
    }
    ],
    “qosClass”: “BestEffort”,
    “startTime”: “2021-02-08T11:11:53Z”
    }

     

    Kubernetes中的探针


    Kubernetes提供了探针——health checks——来监控和操作pods的状态或状况,以确保只有健康的pods才能提供正常服务。Kubelet是运行health checks的主要组件,同时更新API服务器。

    探针处理器

    共有三种可用的处理程序,几乎可以涵盖所有情况。

    Exec Action

    ExecAction在容器内执行命令;这也是一个网关功能,可以处理任何事情,因为我们可以运行任意可执行文件;这可能是一个curl请求以确定状态的脚本,也可能是调用外部链接的可执行文件。同时,需要确保可执行文件不会创建僵尸进程。

    TCP Socket Action

    TCPSocketAction连接到已定义的端口以检查该端口是否打开,主要用于不使用HTTP的端点。HTTPGetAction将HTTP Get请求作为探针发送到定义的路径,HTTP响应代码确定探针是否成功。

    通用探针参数

    每种探针都有共同的可配置字段:

    • initialDelaySeconds:容器启动之后和探测开始之前的秒数。(默认值:0)
    • periodSeconds:Pod的频率。(默认值:10)
    • timeoutSeconds:预期响应的超时。(默认值:1)
    • successThreshold:从失败状态过渡到健康状态所获得的成功结果数。(默认值:1)
    • failureThreshold:从正常状态转换为故障状态时收到了多少个失败结果。(默认值:3)

    如您所见,我们可以详细配置探针。为了成功进行探针配置,我们需要分析应用程序/微服务的需求和依赖性。

    Startup Probes

    如果您的进程需要时间来准备、读取文件、解析大型配置、准备一些数据等等,那么应该使用Startup Probes。如果探测失败,超过阈值,它将重新启动,以便重新开始操作。您需要相应地调整initialDelaySeconds和periodSeconds,以确保进程有足够的时间完成。否则,你会发现pod的会不停的循环启动。

    Readiness Probes

    如果你想控制发送到pod的流量,你应该使用Readiness Probes。Readiness Probes可以修改Pod条件:确认Pod是否应包含在服务和负载均衡中。当探测成功足够的次数(阈值)时,这意味着pod可以接收流量,那么它应该包含在服务和负载平均衡中,从而正常提供业务访问。如果您的流程能够使自己脱离服务进行维护、读取大量用于服务的数据等,那么您应该再次使用Readiness Probes。这样pod就可以通过Readiness Probes向Kubelet发出信号,表示它希望暂时退出服务。

    Liveness Probes

    如果发生意外错误时容器本身无法崩溃,则使用liveness probes。使用liveness probes可以解决流程可能存在的一些缺陷。一旦liveness probes失败,Kubelet就会重启pod。如果您的进程可以通过退出来处理这些错误,则不需要使用liveness probes;但是,在修复未知错误之前,使用它们是有利的。

    示例:Kubernetes API


    Kubernetes API还包括运行endpoints的health check:healthz(不建议使用),readyz,livez。让我们看一下readyz旨在与现成探针一起使用的endpoint。kubectl get –raw=’/readyz?verbose’
    将各个服务的运行状况合并以显示运行状况。

    [+]ping ok
    [+]log ok
    [+]etcd ok
    [+]informer-sync ok
    [+]poststarthook/start-kube-apiserver-admission-initializer ok
    [+]poststarthook/generic-apiserver-start-informers ok
    [+]poststarthook/start-apiextensions-informers ok
    [+]poststarthook/start-apiextensions-controllers ok
    [+]poststarthook/crd-informer-synced ok
    [+]poststarthook/bootstrap-controller ok
    [+]poststarthook/scheduling/bootstrap-system-priority-classes ok
    [+]poststarthook/start-cluster-authentication-info-controller ok
    [+]poststarthook/aggregator-reload-proxy-client-cert ok
    [+]poststarthook/start-kube-aggregator-informers ok
    [+]poststarthook/apiservice-registration-controller ok
    [+]poststarthook/apiservice-status-available-controller ok
    [+]poststarthook/kube-apiserver-autoregistration ok
    [+]autoregister-completion ok
    [+]poststarthook/apiservice-openapi-controller ok
    [+]shutdown ok
    healthz check passed

    让我们看一下livez endpoint。kubectl get –raw=’/livez?verbose’
    将各个服务的运行状况合并以显示运行状况。

    [+]ping ok
    [+]log ok
    [+]etcd ok
    [+]poststarthook/start-kube-apiserver-admission-initializer ok
    [+]poststarthook/generic-apiserver-start-informers ok
    [+]poststarthook/start-apiextensions-informers ok
    [+]poststarthook/start-apiextensions-controllers ok
    [+]poststarthook/crd-informer-synced ok
    [+]poststarthook/bootstrap-controller ok
    [+]poststarthook/scheduling/bootstrap-system-priority-classes ok
    [+]poststarthook/start-cluster-authentication-info-controller ok
    [+]poststarthook/aggregator-reload-proxy-client-cert ok
    [+]poststarthook/start-kube-aggregator-informers ok
    [+]poststarthook/apiservice-registration-controller ok
    [+]poststarthook/apiservice-status-available-controller ok
    [+]poststarthook/kube-apiserver-autoregistration ok
    [+]autoregister-completion ok
    [+]poststarthook/apiservice-openapi-controller ok
    healthz check passed

     

    结论:

    我们已经研究了Kubernetes探针技术;它们是应用高可用方案的重要组成部分。另一方面,很明显,错误的配置会对应用程序/微服务的可用性产生不利影响。最重要的是要适当地配置和测试不同的场景以找到最佳值;我们需要考虑外部源的稳定性,以及我们是否会在探测响应端点上包含此检查。我们已经看到Readiness Probe是用于在服务和负载均衡中删除异常pod,而liveness Probe则是在故障时重新启动pod。您可以在“进一步阅读”部分找到以前文章的链接,其中详细介绍了 Readiness, Liveness与Startup Probes。

    进一步阅读:

    • Kubernetes启动探针-示例和常见陷阱(https://loft.sh/blog/kubernetes-startup-probes-examples-common-pitfalls/)
    • Kubernetes活力探针-示例和常见陷阱(https://loft.sh/blog/kubernetes-liveness-probes-examples-common-pitfalls/index-1/)
    • Kubernetes准备就绪探针-示例和常见陷阱(https://loft.sh/blog/kubernetes-readiness-probes-examples-common-pitfalls/)
    • Kubernetes核心探针文档(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#probe-v1-core)
    • 配置Liveness, Readiness 与Startup Probes(https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/)
    • Kubernetes容器探针说明文件(https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#container-probes)
    • 容器Lifecycle Hooks文档(https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)

    原文:

    https://loft.sh/blog/kubernetes-probes-startup-liveness-readiness/

    «
    »
以专业成就每一位客户,让企业IT只为效果和安全买单

以专业成就每一位客户,让企业IT只为效果和安全买单