【Datadog】监控Kubernetes的OOMKilled指标

总结

这篇文章的内容如下所示。

    • KubernetesのコンテナのStateとLast Stateの違い

 

    • Datadogでkubernetes.containers.state.terminatedを使う際の注意事項

kubernetes.containers.last_state.terminatedを用いたOOMKilledの監視方法

想做的事情 zuò de

在这篇文章中,我们将实现以下内容。

    • KubernetesのコンテナでOOMKilledが起きたときに、Datadog Monitorでアラートを飛ばしたい

 

    そのためにOOMKilledだけをメトリクスとして取得したい(他のエラーとは混ぜたくない)

准备:将Datadog Agent安装在Kubernetes集群上。

本章不是主要内容,它只是按照官方文件的规定而编写,您可以根据需要略过阅读。

要收集Kubernetes的指标数据到Datadog中,需要将Datadog Agent安装到集群中。有三种安装方式(Helm、DeamonSet、Operator)。

请阅读以下的日文文章以了解Datadog Agent的工作原理。此文章是关于Datadog Cluster Agent的解释,但在“无法使用Datadog Cluster Agent时的集群监控”这一章中介绍了Datadog Agent的架构,非常易懂。

Datadog Agentのアーキテクチャ。上記記事より引用

※上面的圖片是從上述文章中引用的。

此外,雖然不是必需的,但如果在集群中安裝kube-state-metrics,可以方便地使用在官方文件:Kubernetes Data Collected中列出的Kubernetes state的指標。(本次警報不需要使用)

如果您对Kubernetes监控一无所知,以下的文章是一个全4部分的学习资料。我强烈推荐阅读。

似乎可以用来监视OOMKilled的指标。

我們現在進入了本題。

Kubernetes数据收集的公式文档中列出了四个看起来很有用的指标。我会先直接引用如下:

メトリクス説明kubernetes.containers.state.terminatedThe number of currently terminated containerskubernetes.containers.last_state.terminatedThe number of containers that were previously terminatedkubernetes_state.container.terminatedWhether the container is currently in terminated statekubernetes_state.container.status_report.count.terminatedCount of the containers currently reporting a in terminated state with the reason as a tag

说明较少呢… 对像我这样的业余者来说太严格了。

在实际中,我探索了Datadog的Metrics Explorer和Monitor,以便找出哪个可以用来监视OOMKilled。

由于上面提到的两个(以kubernetes.containers开头的指标)是无需kube-state-metrics的,因此本文将针对这两个指标进行讨论。

Kubernetes的容器状态已终止。

kubernetes.containers.state.terminated是指“当前状态为terminated的容器数量”(适用于sum情况)。请注意,它表示的是容器的数量,而不是从running变成terminated的次数。即使同一个容器一直在running和terminated之间切换,此指标仍然保持为1。

另外,在此提到的”State”指的是.status.containerStatuses[].state。容器具有三种状态:Waiting(等待)、Running(运行)和Terminated(终止)(根据官方文档)。在Waiting和Terminated状态下,还带有Reason,并且其取值如下(根据stackoverflow)。

    • WaitingのReason

ContainerCreating
CrashLoopBackOff
ErrImagePull
ImagePullBackOff
CreateContainerConfigError
InvalidImageName
CreateContainerError

TerminatedのReason

OOMKilled
Error
Completed
ContainerCannotRun
DeadlineExceeded

因此,Datadog的指标中除了kubernetes.containers.state.terminated状态之外,还有(省略).state.waiting和(省略).state.running状态。

另外,最重要的是,您还可以获取等待状态和终止状态的原因。

如果将Monitor查询设置为sum:kubernetes.containers.state.terminated{reason:oomkilled},那么它的意思是“当前状态为已终止,并且原因为OOMKilled的容器数量”。

太好了!与我想要做的事情相匹配呢。我立刻制作了一个监控器。

请将以下内容改为中文的同义句,只需提供一种选项:

请将以下内容改为中文的同义句,只需提供一种选项:

有时候会出现警报没有发出的情况……

是的,原本计划的事情没能顺利进行。不仅仅是OOMKilled,还遇到了sum:kubernetes.containers.state.terminated计数不正确的问题(有时候会增加,有时候不会)。这是为什么呢?

只是我的猜测,可能是因为Datadog Agent在获取数据时,容器的状态还没有变为已终止。

除非Pod的restartPolicy设置为Never,否则如果容器死亡,它将立即重新启动。因此,状态变为终止只是一瞬间的事情。如果这个时机与Datadog Agent的数据获取时间重叠,则会反映在指标上,否则不会(这只是我个人的猜测,欢迎纠正和补充)。

因此,我认识到这个指标很难用于警报,所以我想使用另一个选项。

kubernetes.containers.last_state.terminated 可以被归纳为以下的方式:

kubernetes.containers.last_state.terminated 最后状态为已终止

kubernetes.containers.last_state.terminated在(sum情况下)表示”处于terminated状态的容器数量”。

State和Last State是不同的东西。当State为terminated的容器重新启动时,Last State会记录终止时间和原因。让我们从kubectl get pod的结果中比较State和Last State。容器”xxx”是一个发生了OOMKilled的容器,而容器”yyy”是一个从未重新启动过的容器。

※省略了不相关的行。

"status": {
  "containerStatuses": [
    {
      "containerID": "xxx",
      "image": "xxx",
      "imageID": "xxx",
      "lastState": {
        "terminated": {
          "containerID": "xxx",
          "exitCode": 0,
          "finishedAt": "2021-12-02T18:09:45Z",
          "reason": "OOMKilled",
          "startedAt": "2021-11-29T08:47:55Z"
        }
      },
      "name": "xxx",
      "ready": true,
      "restartCount": 10,
      "started": true,
      "state": {
        "running": {
          "startedAt": "2021-12-02T18:09:48Z"
        }
      }
    },
    {
      "containerID": "yyy",
      "image": "yyy",
      "imageID": "yyy",
      "lastState": {},
      "name": "yyy",
      "ready": true,
      "restartCount": 0,
      "started": true,
      "state": {
        "running": {
          "startedAt": "2021-09-14T05:31:22Z"
        }
      }
    }
  ]
}

“容器 ‘yyy’ 从未重启过,其 Last State 是空的。”

因此,例如将Monitor的查询设置为sum:kubernetes.containers.last_state.terminated{reason:oomkilled},意思是“处于终止状态且原因为OOMKilled的容器数量”,可以检测到OOMKilled事件的发生。

然而,以下几点需要注意。

OOMKilledが起きた回数ではない。同じコンテナがOOMKilledを繰り返していても、この値は1のまま
一度1になったら、Podが生まれ変わらない限り0に戻らない。なぜならLast Stateが空に戻ることはないから(※reasonが別の理由になることはあり得る)
よって、OOMKilledが発生しなくなったタイミングは検知できない。また、同じPodでOOMKilledが再発しても検知できない

总结起来就是相当不方便。

对于我们的团队来说,一旦发生OOMKilled,我们必定会进行调查和处理。在许多情况下,我们会修改清单并应用kubectl来增加容器的内存限制。这意味着Pod会重新生成,所以它会回到初始状态。因此,虽然我们不会陷入麻烦……但是我们应该避免依赖”通过运维来解决”这种方式吧…

虽然我还没有开始尝试,但在Datadog监控功能方面可能有很多努力的空间。

比较两个度量标准

让我们在仪表板上并排显示两个指标。

【上】sum:kubernetes.containers.state.terminated{reason:oomkilled}

【上】sum:kubernetes.containers.state.terminated{reason:oomkilled}可以被改写为【上】sum:kubernetes容器状态终止{原因:oomkilled}。

【下】的【sum】:kubernetes.containers.last_state.terminated{reason:oomkilled}

我将所有选项都设为默认值零。

2つのメトリクスの比較

正如前面所述,上述的kubernetes.containers.state.terminated几乎无法被检测到(即使下图上升时,上图仍保持为0的情况也无法被检测到)。

此外,从kubernetes.containers.last_state.terminated下方可以清楚地看出,除非Pod经历重启,否则该值是不会减少的。

总结

在监视Kubernetes的OOMKilled时,可以使用Datadog指标kubernetes.containers.last_state.terminated{reason:oomkilled},但是这个指标在用于警报时有很多不方便之处。

广告
将在 10 秒后关闭
bannerAds