十一、可观测性——你的应用健康吗

需求来源

当把应用迁移到 K8S 后,如何保障应用的健康与稳定?

  1. 提高应用的可观测性

    1. 资源使用情况
    2. 应用自身的健康
    3. 实时日志,方便进行问题的诊断和分析
  2. 提高应用的可恢复能力

    1. 出现问题时首先是降低影响范围

      例如 pod 不可用时,service 会在负载均衡里去掉该 pod

    2. 理想情况是通过 k8s 集成的自愈机制进行完整的恢复

      例如 node 故障,k8s 会将该 node 上的 pod 进行迁移

应用健康状态

Readiness probe

就绪探针,用来判断 pod 是否就绪,就绪状态时service才会分发流量给该pod。

适用于启动后无法立即对外提供服务。

Liveness probe

存活探针,用来判断 pod 是否存活。如果处于非存活状态下,会触发 kubelet 杀掉该容器,再由上层的判断机制来判断这个 pod 是否需要重新被拉起,例如重启策略配置的是:always。

适用于支持重新拉起的应用。

两种探针都包含在 ProbeManager 的组件中

探测方式和使用

Liveness 指针和 Readiness 指针支持三种不同的探测方式:

  1. httpGet。它是通过发送 http Get 请求来进行判断的,当返回码是 200-399 之间的状态码时,标识这个应用是健康的;

    image-20220228143718025

    可能会遇到鉴权问题,返回401

  2. Exec。它是通过执行容器中的一个命令来判断当前的服务是否是正常的,当命令行的返回结果是 0,则标识容器是健康的;

    image-20220228143750966

  3. tcpSocket。它是通过探测容器的 IP 和 Port 进行 TCP 健康检查,如果这个 TCP 的链接能够正常被建立,那么标识当前这个容器是健康的。

    image-20220228144011653

    web应用适合这个

相关 Global 参数

  • initialDelaySeconds,表示这个 pod 启动延迟多久才开始进行检查

  • periodSeconds,表示的是检测的时间间隔,默认是 10 秒

  • timeoutSeconds,它表示的是检测的超时时间,当超时时间之内没有检测成功,那它会认为是失败的一个状态;

  • successThreshold,它表示的是:当这个 pod 从探测失败到再一次判断探测成功,所需要的阈值次数,默认情况下是 1 次,表示原本是失败的,那接下来探测这一次成功了,就会认为这个 pod 是处在一个探针状态正常的一个状态;

    失败转成功的阀值

  • failureThreshold,它表示的是探测失败的重试次数,默认值是 3,表示的是当从一个健康的状态连续探测 3 次失败,那此时会判断当前这个pod的状态处在一个失败的状态。

    定义失败的阀值

探测结果

从探测结果来讲主要分为三种:

  • success,通过健康检查
  • Failure,表示的是这个 container 没有通过健康检查,此时就会进行相应的一个处理,那在 Readiness 处理的一个方式就是通过 service。service 层将没有通过 Readiness 的 pod 进行摘除,而 Liveness 就是将这个 pod 进行重新拉起,或者是删除。
  • Unknown,表示当前的执行的机制没有进行完整的一个执行,可能是因为类似像超时或者像一些脚本没有及时返回,那么此时 Readiness-probe 或 Liveness-probe 会不做任何的一个操作,会等待下一次的机制来进行检验。

应用故障排查

K8S 的状态机制

面向状态机,通过 yaml 的方式来定义一个期望到达的状态,而真正这个 yaml 在执行过程中会由各种各样的 controller 来负责整体状态之间的一个转换。

img

而不同状态之间的转化都会在相应的 K8s对象上面留下来类似像 Status 或者像 Conditions 的一些字段来进行表示。

img
在 K8s 里面不同的状态之间的这个转换都会发生相应的事件,而事件分为两种: 一种叫做 normal 的事件,一种是 warning 事件。

常见应用异常

Pod 停留在 Pending

pending 表示调度器没有进行介入。此时可以通过 kubectl describe pod 来查看相应的事件,如果由于资源或者说端口占用,或者是由于 node selector 造成 pod 无法调度的时候,可以在相应的事件里面看到相应的结果,这个结果里面会表示说有多少个不满足的 node,有多少是因为 CPU 不满足,有多少是由于 node 不满足,有多少是由于 tag 打标造成的不满足。

Pod 停留在 waiting

通常表示说这个 pod 的镜像没有正常拉取,原因可能是由于这个镜像是私有镜像,但是没有配置 Pod secret;那第二种是说可能由于这个镜像地址是不存在的,造成这个镜像拉取不下来;还有一个是说这个镜像可能是一个公网的镜像,造成镜像的拉取失败。

Pod 不断被拉取并且可以看到 crashing

pod 不断被拉起,而且可以看到类似像 backoff。这个通常表示说 pod 已经被调度完成了,但是启动失败,那这个时候通常要关注的应该是这个应用自身的一个状态,并不是说配置是否正确、权限是否正确,此时需要查看的应该是 pod 的具体日志

Pod 处在 Runing 但是没有正常工作

可能是由于一些非常细碎的配置,类似像有一些字段可能拼写错误,造成了 yaml 下发下去了,但是有一段没有正常地生效,从而使得这个 pod 处在 running 的状态没有对外服务,那此时可以通过 apply-validate-f pod.yaml 的方式来进行判断当前 yaml 是否是正常的,如果 yaml 没有问题,那么接下来可能要诊断配置的端口是否是正常的,以及 Liveness 或 Readiness 是否已经配置正确。

Service 无法正常的工作

比较常见的 service 出现问题的时候,是自己的使用上面出现了问题。因为 service 和底层的 pod 之间的关联关系是通过 selector 的方式来匹配的,也就是说 pod 上面配置了一些 label,然后 service 通过 match label 的方式和这个 pod 进行相互关联。如果这个 label 配置的有问题,可能会造成这个 service 无法找到后面的 endpoint,从而造成相应的 service 没有办法对外提供服务,那如果 service 出现异常的时候,第一个要看的是这个 service 后面是不是有一个真正的 endpoint,其次来看这个 endpoint 是否可以对外提供正常的服务。

应用远程调试

Service 远程调试

让集群调用本地应用

开源组件 Telepresence,它可以将本地的应用代理到远程集群中的一个 service 上面

暴露集群服务,让本地调用

通过 port-forward 的方式将远程的应用映射到本地的端口上,通过访问本地端口就可以访问远程的服务。

使用方式是 kubectl port-forward,然后 service 加上远程的 service name,再加上相应的 namespace,后面还可以加上一些额外的参数,比如说端口的一个映射。

kubectl port-forward svc/app -n app-namespace

开源的调试工具 - kubectl-debug

在 K8s 里面,底层的容器 runtime 比较常见的就是类似像 docker 或者是 containerd,不论是 docker 还是 containerd,它们使用的一个机制都是基于 Linux namespace 的一个方式进行虚拟化和隔离的。

通常情况下 ,并不会在镜像里面带特别多的调试工具,类似像 netstat telnet 等 ,因为这个会造成应用整体非常冗余。

kubectl-debug 这个工具是依赖于 Linux namespace 的方式来去做的,是kubectl 的一个插件。它可以 attach 一个 Linux namespace 到一个额外的 container,然后在这个 container 里面执行任何的 debug 动作,其实和直接去 debug 这个 Linux namespace 是一致的。可以查看类似像 hostname、进程、netstat 等等。

问题解答

  1. 重启策略有为always的场景吗?应用处于failed状态,没有定位到原因,再拉起一次不还是会failed?

    1. 应用一般不会马上 failed,在特定情况下才会挂,这种时候再拉起就能再撑一阵,否则影响整个服务。
    2. 会保留日志,供后续排查。
  2. k8s 的弹性扩展如何使用?

    Kubernetes 中 Pod 弹性伸缩详解与使用

作者:Yuyy
博客:https://yuyy.info
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇