成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

解決 Prometheus 監控 Kubernetes Job 誤報的坑

云計算 云原生
要想做到監控報警準確,其實我們只需要去獲取同一個 CronJob 觸發的一組 Job 的最后一次任務,只有該 Job 在執行失敗的時候才觸發報警即可。

昨天在 Prometheus 課程輔導群里面有同學提到一個問題,是關于 Prometheus 監控 Job 任務誤報的問題(已經同步到社區網站),大概的意思就 CronJob 控制的 Job,前面執行失敗了會觸發報警,后面生成的新的 Job 可以正常執行后,但是還是會收到前面的報警:

這是因為一般在執行 Job 任務的時候我們會保留一些歷史記錄方便排查問題,所以如果之前有失敗的 Job 了,即便稍后會變成成功的,那么之前的 Job 也會繼續存在,而大部分直接使用 kube-prometheus 安裝部署的話使用的默認報警規則是kube_job_status_failed > 0,這顯然是不準確的,只有我們去手動刪除之前這個失敗的 Job 任務才可以消除誤報,當然這種方式是可以解決問題的,但是不夠自動化,一開始沒有想得很深入,想去自動化刪除失敗的 Job 來解決,但是這也會給運維人員帶來問題,就是不方便回頭去排查問題。下面我們來重新整理下思路解決下這個問題。

CronJob 會在計劃的每個執行時間創建一個 Job 對象,可以通過 .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit 屬性來保留多少已完成和失敗的 Job,默認分別為3和1,比如下面聲明一個 CronJob 的資源對象:

apiVersion: batch/v1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
successfulJobsHistoryLimit: 1
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
imagePullPolicy: IfNotPresent
command:
- /bin/sh
- -c
- date;
restartPolicy: OnFailure

根據上面的資源對象規范,Kubernetes 將只保留一個失敗的 Job 和一個成功的 Job:

NAME               COMPLETIONS   DURATION   AGE
hello-4111706356 0/1 2m 10d
hello-4111706356 1/1 5s 5s

要解決上面的誤報問題,同樣還是需要使用到 kube-state-metrics 這個服務,它通過監聽 Kubernetes APIServer 并生成有關對象狀態的指標,它并不關注單個 Kubernetes 組件的健康狀況,而是關注內部各種對象的健康狀況,例如 Deployment、Node、Job、Pod 等資源對象的狀態。這里我們將要使用到以下幾個指標:

  • kube_job_owner:用來查找 Job 和觸發它的 CronJob 之間的關系。
  • kube_job_status_start_time:獲取 Job 被觸發的時間。
  • kube_job_status_failed:獲取執行失敗的任務。
  • kube_cronjob_spec_suspend:過濾掉掛起的作業。

下面是一個指標示例,其中包含 CronJob 觸發運行的hello 任務生成的標簽:

kube_job_owner{job_name="hello-1604875860", namespace="myNamespace", owner_is_controller="true", owner_kind="CronJob", owner_name="hello"} 1
kube_job_status_start_time{job_name="hello-1604875860", namespace="myNamespace"} 1604875874
kube_job_status_failed{job_name="hello-1604875860", namespace="myNamespace", reason="BackoffLimitExceeded"} 1
kube_cronjob_spec_suspend{cronjob="hello",job="kube-state-metrics", namespace="myNamespace"} 0

要想做到監控報警準確,其實我們只需要去獲取同一個 CronJob 觸發的一組 Job 的最后一次任務,只有該 Job 在執行失敗的時候才觸發報警即可。

由于 kube_job_status_failed 和 kube_job_status_start_time 指標中并不包含所屬 CronJob 的標簽,所以第一步需要加入這個標簽,而 kube_job_owner 指標中的 owner_name 就是我們需要的,可以用下面的 promql 語句來進行合并:

max(
kube_job_status_start_time
* ON(job_name, namespace) GROUP_RIGHT()
kube_job_owner{owner_name != ""}
)
BY (job_name, owner_name, namespace)

這里我們使用 max 函數是因為我們可能會因為 HA 運行多個 kube-state-metrics,所以用 max 函數來返回每個 Job 任務的一個結果即可。假設我們的 Job 歷史記錄包含 2 個任務(一個失敗,另一個成功),結果將如下所示:

{job_name="hello-1623578940", namespace="myNamespace", owner_name="hello"} 1623578959
{job_name="hello-1617667200", namespace="myNamespace", owner_name="hello"} 1617667204

現在我們知道每個 Job 的所有者了,接著我們需要找出最后執行的任務,我們可以通過按 owner_name 標簽聚合結果來實現這一點:

max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (owner_name)

上面這條語句會找到每個 owner(也就是 CronJob)最新的任務開始時間,然后再和上面的語句進行合并,保留開始時間相同的記錄即為最新執行的 Job 任務了:

max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (job_name, owner_name, namespace)
== ON(owner_name) GROUP_LEFT()
max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (owner_name)

結果將顯示每個 CronJob 最后執行的作業,并且僅顯示最后一個:

{job_name="hello-1623578940", namespace="myNamespace", owner_name="hello"} 1623578959

為了增加可讀性我們還可以將 job_name、owner_name 標簽替換為 job 和 cronjob,這樣更容易看明白:

label_replace(
label_replace(
max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (job_name, owner_name, namespace)
== ON(owner_name) GROUP_LEFT()
max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (owner_name),
"job", "$1", "job_name", "(.+)"),
"cronjob", "$1", "owner_name", "(.+)")

現在將會看到類似于下面的結果:

{job="hello-1623578940", cronjob="hello", job_name="hello-1623578940", namespace="myNamespace", owner_name="hello"} 1623578959

由于上面的查詢語句比較復雜,如果每次報警評估的時候都去進行一次實時計算會對 Prometheus 產生非常大的壓力,這里我們可以借助記錄規則來實現類離線計算的方式,大大提高效率,創建如下所示的記錄規則,用來表示獲取每個 CronJob 最后執行的作業記錄:

- record: job:kube_job_status_start_time:max
expr: |
label_replace(
label_replace(
max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (job_name, owner_name, namespace)
== ON(owner_name) GROUP_LEFT()
max(
kube_job_status_start_time
* ON(job_name,namespace) GROUP_RIGHT()
kube_job_owner{owner_name!=""}
)
BY (owner_name),
"job", "$1", "job_name", "(.+)"),
"cronjob", "$1", "owner_name", "(.+)")

現在我們知道了 CronJob 最近開始執行的 Job 了,那么想要過濾出失敗的,則再使用 kube_job_status_failed 指標就可以了:

- record: job:kube_job_status_failed:sum
expr: |
clamp_max(job:kube_job_status_start_time:max, 1)
* ON(job) GROUP_LEFT()
label_replace(
(kube_job_status_failed > 0),
"job", "$1", "job_name", "(.+)"
)

這里使用 clamp_max 函數將 job:kube_job_status_start_time:max 的結果轉換為一組上限為 1 的時間序列,使用它來通過乘法過濾失敗的作業,得到包含一組最近失敗的 Job 任務,這里我們也添加到名為 kube_job_status_failed:sum 的記錄規則中。

最后一步就是直接為失敗的 Job 任務添加報警規則,如下所示:

- alert: CronJobStatusFailed
expr: |
job:kube_job_status_failed:sum
* ON(cronjob, namespace) GROUP_LEFT()
(kube_cronjob_spec_suspend == 0)

為避免誤報,我們已將掛起的任務排除在外了。到這里我們就解決了 Prometheus 監控 CronJob 的任務誤報的問題,雖然 kube-prometheus 為我們內置了大量的監控報警規則,但是也不能完全迷信,有時候并不一定適合實際的需求。

責任編輯:姜華 來源: k8s技術圈
相關推薦

2021-07-01 11:29:45

KubernetesGrafana監控

2024-02-23 16:10:29

KubernetesPrometheus開源

2022-07-26 09:34:23

監控系統

2021-08-19 09:30:03

Kubernetes集群IPVS

2022-05-02 18:15:04

KubernetesLinux開源

2022-11-08 00:00:00

監控系統Prometheus

2020-09-15 08:46:26

Kubernetes探針服務端

2022-05-18 08:32:05

服務監控Prometheus開源

2020-12-30 08:09:46

運維Prometheus 監控

2024-04-24 13:45:00

2020-05-11 08:00:00

監控工具加密開源

2019-10-17 21:14:08

Kubernetes節點Python

2020-05-18 12:04:17

PrometheusMySQL監控

2020-10-20 09:07:11

監控PrometheusZabbix

2022-07-08 08:00:31

Prometheus監控

2022-07-11 09:36:38

SpringJava開發

2023-10-09 07:31:25

2022-05-19 08:21:02

vmalert監控

2020-11-20 08:15:40

Grafana + P

2022-12-13 08:01:06

監控黑盒集成
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产欧美一区二区三区久久人妖 | 精品国产三级 | 成人三级影院 | 丁香六月激情 | 亚洲欧美一区二区三区1000 | 国产中文字幕在线观看 | 国产一区久久 | 久久国产成人午夜av影院武则天 | 日韩中文字幕av | 亚洲一区二区三区在线播放 | 我要看免费一级毛片 | 国产精品永久免费观看 | 国产精品美女久久久久久久久久久 | 国产成人一区二区 | 日韩在线 | 亚洲成人一区二区三区 | 中文字字幕一区二区三区四区五区 | 免费在线观看av片 | 久久久久久久国产精品 | 亚洲欧洲日韩 | 欧美一级毛片在线播放 | 国产 日韩 欧美 在线 | 国产精品永久免费 | 日韩电影免费在线观看中文字幕 | 日日干天天干 | 中文字幕乱码一区二区三区 | 欧美在线视频网 | 精品视频一区二区 | 视频一区在线 | 国产精品一区二区久久久久 | 一区二区久久精品 | 中文字幕免费中文 | 国产精品免费大片 | 久久久不卡网国产精品一区 | 国产精品中文字幕在线 | 日韩免费在线 | 精品欧美一区二区三区精品久久 | 国产三级国产精品 | 天天操精品视频 | 中文字幕在线观看一区 | 欧美激情视频网站 |