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条件。

 

kubectl describe pods <POD_NAME>

 

示例输出如下:

 

...
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。如果探测失败,超过阈值,它将重新启动,以便重新开始操作。您需要相应地调整initialDelaySecondsperiodSeconds,以确保进程有足够的时间完成。否则,你会发现pod的会不停的循环启动。

Readiness Probes

如果你想控制发送到pod的流量,你应该使用Readiness ProbesReadiness 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/)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值