prometheus-operator使用PrometheusRule来代替了规则文件。每个告警规则对应一个PrometheusRule对象。所有的PrometheusRule对象会被Prometheus-Operator转换为规则文件挂载在promtheus pod内部的 /etc/prometheus/rules/prometheus-k8s-rulefiles-0 目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package api

import (
    "errors"
    "fmt"
    operatorV1 "github.com/coreos/prometheus-operator/pkg/apis/monitoring/v1"
    "github.com/coreos/prometheus-operator/pkg/client/versioned"
    jsoniter "github.com/json-iterator/go"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/fields"
    "k8s.io/apimachinery/pkg/types"
    "k8s.io/klog"
)

const ApiVersion = "monitoring.coreos.com/v1"

// ================创建告警规则================
// 查询告警规则是否存在
func GetPrometheusRule(clientSet *versioned.Clientset, namespace string, alertName string) (*operatorV1.PrometheusRule, error) {
    return clientSet.MonitoringV1().PrometheusRules(namespace).Get(alertName, metav1.GetOptions{})
}

// 根据ns查询告警规则
func GetRulesByClusterNs(clientSet *versioned.Clientset, monitorNs, sign, clusterId string) (*operatorV1.PrometheusRuleList, error) {
    return clientSet.MonitoringV1().PrometheusRules(monitorNs).List(metav1.ListOptions{
        LabelSelector: fields.SelectorFromSet(fields.Set(map[string]string{
            "sign":    sign,
            "cluster": clusterId,
        })).String(),
    })
}

// sign, 如果是pod,那么对应pod的namespace,如果是宿主机,那么对应宿主机ip
func CreateRule(clientSet *versioned.Clientset, groups []operatorV1.RuleGroup, monitorNs, sign, cluster, alertName string, showLog bool) (*operatorV1.PrometheusRule, error) {
    if showLog {
        klog.Infof("received create PrometheusRule in namespace:%s, name:%s", monitorNs, alertName)
    }
    pr := &operatorV1.PrometheusRule{
        TypeMeta: metav1.TypeMeta{
            APIVersion: ApiVersion,
            Kind:       "PrometheusRule",
        },
        ObjectMeta: metav1.ObjectMeta{
            Name:      alertName,
            Namespace: monitorNs,
            Labels: map[string]string{
                "prometheus": "k8s",
                "role":       "alert-rules",
                "sign":       sign,
                "cluster":    cluster,
            },
        },
        Spec: operatorV1.PrometheusRuleSpec{
            Groups: groups,
        },
    }
    return clientSet.MonitoringV1().PrometheusRules(monitorNs).Create(pr)
}

// 修改告警规则
func PatchRule(clientSet *versioned.Clientset, groups []operatorV1.RuleGroup, namespace, ruleName string, showLog bool) (*operatorV1.PrometheusRule, error) {
    if showLog {
        klog.Infof("received patch PrometheusRule in namespace:%s, name:%s", namespace, ruleName)
    }
    patch := PathRule{
        Metadata: Metadata{
            Namespace: namespace,
            Name:      ruleName,
        },
        Spec: operatorV1.PrometheusRuleSpec{
            Groups: groups,
        },
    }
    data, err := jsoniter.Marshal(patch)
    if err != nil {
        return nil, errors.New(fmt.Sprintf("update %s rule, but format err:%s ", ruleName, err.Error()))
    }
    return clientSet.MonitoringV1().PrometheusRules(namespace).Patch(ruleName, types.MergePatchType, data)
}

// 删除PrometheusRule
func DeleteRule(clientSet *versioned.Clientset, namespace, name string) error {
    return clientSet.MonitoringV1().PrometheusRules(namespace).Delete(name, &metav1.DeleteOptions{})
}


type PathRule struct {
    Metadata Metadata                      `json:"metadata"`
    Spec     operatorV1.PrometheusRuleSpec `json:"spec"`
}

type Metadata struct {
    Namespace string `json:"namespace"`
    Name      string `json:"name"`
}