【问题标题】:Is there a way to monitor kube cron jobs using prometheus有没有办法使用 prometheus 监控 kube cron 作业
【发布时间】:2017-11-17 05:29:14
【问题描述】:

有没有办法监控 kube cronjob。

我有一个 kube cronjob,它在我的集群上每 10 分钟运行一次。有没有办法在每次我的 cronjob 由于某些错误而失败时收集指标,或者在一段时间后我的 cronjob 未完成时通知。

【问题讨论】:

    标签: kubernetes prometheus


    【解决方案1】:

    我将这些规则与kube-state-metrics 一起使用:

    groups:
    - name: job.rules
      rules:
      - alert: CronJobRunning
        expr: time() -kube_cronjob_next_schedule_time > 3600
        for: 1h
        labels:
          severity: warning
        annotations:
          description: CronJob {{$labels.namespaces}}/{{$labels.cronjob}} is taking more than 1h to complete
          summary: CronJob didn't finish after 1h
    
      - alert: JobCompletion
        expr: kube_job_spec_completions - kube_job_status_succeeded  > 0
        for: 1h
        labels:
          severity: warning
        annotations:
          description: Job completion is taking more than 1h to complete
            cronjob {{$labels.namespaces}}/{{$labels.job}}
          summary: Job {{$labels.job}} didn't finish to complete after 1h
    
      - alert: JobFailed
        expr: kube_job_status_failed  > 0
        for: 1h
        labels:
          severity: warning
        annotations:
          description: Job {{$labels.namespaces}}/{{$labels.job}} failed to complete
          summary: Job failed
    

    【讨论】:

    • 这个问题是它会无限期地发出警报,因为 CronJobs 会一直保留这些作业,直到达到历史记录限制。
    【解决方案2】:

    这里的棘手部分是 cronjobs 本身没有有用的状态,您必须将它们与它们创建的作业相匹配。我写了一篇关于如何实现这一点的文章:

    https://medium.com/@tristan_96324/prometheus-k8s-cronjob-alerts-94bee7b90511

    文章详细介绍了事情的工作原理,但警报配置如下:

    groups:
    - name: kube-cron
      rules:
      - record: job_cronjob:kube_job_status_start_time:max
        expr: |
          label_replace(
            label_replace(
              max(
                kube_job_status_start_time
                * ON(exported_job) GROUP_RIGHT()
                kube_job_labels{label_cronjob!=""}
              ) BY (exported_job, label_cronjob)
              == ON(label_cronjob) GROUP_LEFT()
              max(
                kube_job_status_start_time
                * ON(exported_job) GROUP_RIGHT()
                kube_job_labels{label_cronjob!=""}
              ) BY (label_cronjob),
              "job", "$1", "exported_job", "(.+)"),
            "cronjob", "$1", "label_cronjob", "(.+)")
    
      - record: job_cronjob:kube_job_status_failed:sum
        expr: |
      clamp_max(
            job_cronjob:kube_job_status_start_time:max,
          1)
          * ON(job) GROUP_LEFT()
          label_replace(
            label_replace(
              (kube_job_status_failed != 0),
              "job", "$1", "exported_job", "(.+)"),
            "cronjob", "$1", "label_cronjob", "(.+)")
    
    
      - alert: CronJobStatusFailed
        expr: |
          job_cronjob:kube_job_status_failed:sum
          * ON(cronjob) GROUP_RIGHT()
          kube_cronjob_labels
          > 0
        for: 1m
        annotations:
          description: '{{ $labels.cronjob }} last run has failed {{$value }} times.'
    

    jobTemplate 必须包含一个名为 cronjob 的标签,该标签与 cronjob 对象的名称相匹配。

    【讨论】:

      【解决方案3】:

      使用 Prometheus 监控 cronjobs 的方法是让它们推送一个指标,指示它们最后一次成功推送到推送网关的时间。然后,您可以提醒 cronjob 最近是否成功。

      【讨论】:

      • 不鼓励在指标上使用时间戳。有一个值为时间戳的指标(例如process_start_time_seconds)就可以了。
      【解决方案4】:

      您可以从here获取您想要的信息。

      CronJobs 按计划创建作业,因此您可以简单地查看创建的作业的 kube_job_status_failed,需要注意的是作业名称最后有一个纪元时间。

      为确保警报自行解决,我在警报管理器中使用以下查询:

      increase(kube_job_status_failed{job=~"mytestjob-.*"}[5m]) > 1
      

      我的 cron 是:

      */5 * * * *`, and I set `backoffLimit: 2
      

      限制每次运行的失败次数。

      【讨论】:

        【解决方案5】:

        到目前为止,所有答案都不知道命名空间,并且依赖于 Job 中的自定义标签。

        后者可以修复,因为 kube-state-metrics 版本 1.6.0 引入了一个新的指标 kube_job_owner,它解决了匹配 Jobs 和 CronJobs 的问题。

        注意:在 kube-state-metrics 1.4.0 中,job 标签已重命名为 job_name,以避免与 Prometheus 发生标签冲突。

        clamp_max(
          max by (namespace, owner_name, job_name) (
            max by (namespace, owner_name, job_name) (
              kube_job_status_start_time
              *
              on (job_name) group_left(owner_name) max by (namespace, owner_name, job_name) (kube_job_owner{owner_kind="CronJob"})
            )
            ==
            on (namespace, owner_name) group_left max by (namespace, owner_name) (
              kube_job_status_start_time
              *
              on (job_name) group_left(owner_name) max by (namespace, owner_name, job_name) (kube_job_owner{owner_kind="CronJob"})
            )
          ),
          1
        )
        *
        on (namespace, job_name) group_left kube_job_status_failed
        

        通过重命名owner_name 可以进一步改进输出 通过用

        包围表达式来标记cronjob
        max without (owner_name) (
          label_replace(
            <expression from above>
          ,
          "cronjob", "$1", "owner_name", "(.+)"
          )
        )
        
        

        label_replace() 函数添加一个新的cronjob 标签,而max() 删除owner_name 标签)

        【讨论】:

        • 你能解释一下这个查询吗?
        【解决方案6】:

        kube-state-metrics 导出器还包括各种与 CronJob 相关的指标:https://github.com/kubernetes/kube-state-metrics/blob/master/Documentation/cronjob-metrics.md,但不幸的是似乎不包括成功 CronJob 成功/失败。

        【讨论】:

          【解决方案7】:

          我能够简化这个中型帖子(label_replace 出于某种原因对我不起作用) https://medium.com/@tristan_96324/prometheus-k8s-cronjob-alerts-94bee7b90511

          我的 cron 查询看起来像这样(我们在所有 cronjobs 上都有“组件”标签而不是“cronjob”,但您可以使用自己喜欢的标签)

          clamp_max(max(
              kube_job_status_start_time
              * ON(job) GROUP_RIGHT()
              kube_job_labels{label_component!=""}
            ) BY (job, label_component)
            == ON(label_component) GROUP_LEFT()
            max(
              kube_job_status_start_time
              * ON(job) GROUP_RIGHT()
              kube_job_labels{label_component!=""}
          ) BY (label_component), 1) * ON(job) GROUP_LEFT() 
          kube_job_status_failed
          

          将其插入 prometheus 表达式仪表板以确保获得结果(1 表示 cron 上次失败,0 表示成功或尚未运行)。

          对于警报,添加 != 0,查询将返回任何失败的 cronjob。

          【讨论】:

          • 这给出了一个错误:Error executing query: found duplicate series for the match group
          • 当工作再次开始(计划,而不是重试)时,该警报不会消失吗?因此,如果一个工作因为真的坏了而失败,你会看到警报清除,直到下一次失败?
          最近更新 更多