【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的架构,非常易懂。
※上面的圖片是從上述文章中引用的。
此外,雖然不是必需的,但如果在集群中安裝kube-state-metrics,可以方便地使用在官方文件:Kubernetes Data Collected中列出的Kubernetes state的指標。(本次警報不需要使用)
如果您对Kubernetes监控一无所知,以下的文章是一个全4部分的学习资料。我强烈推荐阅读。
似乎可以用来监视OOMKilled的指标。
我們現在進入了本題。
Kubernetes数据收集的公式文档中列出了四个看起来很有用的指标。我会先直接引用如下:
说明较少呢… 对像我这样的业余者来说太严格了。
在实际中,我探索了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}
我将所有选项都设为默认值零。
正如前面所述,上述的kubernetes.containers.state.terminated几乎无法被检测到(即使下图上升时,上图仍保持为0的情况也无法被检测到)。
此外,从kubernetes.containers.last_state.terminated下方可以清楚地看出,除非Pod经历重启,否则该值是不会减少的。
总结
在监视Kubernetes的OOMKilled时,可以使用Datadog指标kubernetes.containers.last_state.terminated{reason:oomkilled},但是这个指标在用于警报时有很多不方便之处。