alertrule
Create PrometheusRule objects for the alerting. One rule is created per instance while one podmonitor is created per type. Change-Id: I43d436fd46ecd1ad92547dec972fdab3fd2ae05e
This commit is contained in:
parent
f59f1e4d0c
commit
f97dbdcff0
@ -11,12 +11,15 @@ const (
|
|||||||
PodMonitorsKind = "PodMonitor"
|
PodMonitorsKind = "PodMonitor"
|
||||||
PodMonitorName = "podmonitors"
|
PodMonitorName = "podmonitors"
|
||||||
PodMonitorKindKey = "podmonitor"
|
PodMonitorKindKey = "podmonitor"
|
||||||
|
|
||||||
|
PrometheusRuleKind = "PrometheusRule"
|
||||||
|
PrometheusRuleName = "prometheusrules"
|
||||||
|
PrometheusRuleKindKey = "prometheusrule"
|
||||||
)
|
)
|
||||||
|
|
||||||
// PodMonitor defines monitoring for a set of pods.
|
// PodMonitor defines monitoring for a set of pods.
|
||||||
// +genclient
|
// +genclient
|
||||||
// +k8s:openapi-gen=true
|
// +k8s:openapi-gen=true
|
||||||
|
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
type PodMonitor struct {
|
type PodMonitor struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
@ -44,7 +47,6 @@ type PodMonitorSpec struct {
|
|||||||
|
|
||||||
// PodMonitorList is a list of PodMonitors.
|
// PodMonitorList is a list of PodMonitors.
|
||||||
// +k8s:openapi-gen=true
|
// +k8s:openapi-gen=true
|
||||||
|
|
||||||
// +kubebuilder:object:root=true
|
// +kubebuilder:object:root=true
|
||||||
type PodMonitorList struct {
|
type PodMonitorList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
@ -125,9 +127,67 @@ type NamespaceSelector struct {
|
|||||||
// implementation to support label selections.
|
// implementation to support label selections.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PrometheusRuleList is a list of PrometheusRules.
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
type PrometheusRuleList struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
// Standard list metadata
|
||||||
|
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||||
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
|
// List of Rules
|
||||||
|
Items []*PrometheusRule `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrometheusRule defines alerting rules for a Prometheus instance
|
||||||
|
// +genclient
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
// +kubebuilder:object:root=true
|
||||||
|
type PrometheusRule struct {
|
||||||
|
metav1.TypeMeta `json:",inline"`
|
||||||
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
// Specification of desired alerting rule definitions for Prometheus.
|
||||||
|
Spec PrometheusRuleSpec `json:"spec"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrometheusRuleSpec contains specification parameters for a Rule.
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
type PrometheusRuleSpec struct {
|
||||||
|
// Content of Prometheus rule file
|
||||||
|
Groups []RuleGroup `json:"groups,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RuleGroup and Rule are copied instead of vendored because the
|
||||||
|
// upstream Prometheus struct definitions don't have json struct tags.
|
||||||
|
|
||||||
|
// RuleGroup is a list of sequentially evaluated recording and alerting rules.
|
||||||
|
// Note: PartialResponseStrategy is only used by ThanosRuler and will
|
||||||
|
// be ignored by Prometheus instances. Valid values for this field are 'warn'
|
||||||
|
// or 'abort'. More info: https://github.com/thanos-io/thanos/blob/master/docs/components/rule.md#partial-response
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
type RuleGroup struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Interval string `json:"interval,omitempty"`
|
||||||
|
Rules []Rule `json:"rules"`
|
||||||
|
PartialResponseStrategy string `json:"partial_response_strategy,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rule describes an alerting or recording rule.
|
||||||
|
// +k8s:openapi-gen=true
|
||||||
|
type Rule struct {
|
||||||
|
Record string `json:"record,omitempty"`
|
||||||
|
Alert string `json:"alert,omitempty"`
|
||||||
|
Expr intstr.IntOrString `json:"expr"`
|
||||||
|
For string `json:"for,omitempty"`
|
||||||
|
Labels map[string]string `json:"labels,omitempty"`
|
||||||
|
Annotations map[string]string `json:"annotations,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors/status,verbs=get;update;patch
|
||||||
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules,verbs=get;list;watch;create;update;patch;delete
|
||||||
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules/status,verbs=get;update;patch
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
SchemeBuilder.Register(&PodMonitor{}, &PodMonitorList{})
|
SchemeBuilder.Register(&PodMonitor{}, &PodMonitorList{}, &PrometheusRule{}, &PrometheusRuleList{})
|
||||||
}
|
}
|
||||||
|
@ -203,6 +203,90 @@ func (in *PodMonitorSpec) DeepCopy() *PodMonitorSpec {
|
|||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PrometheusRule) DeepCopyInto(out *PrometheusRule) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||||
|
in.Spec.DeepCopyInto(&out.Spec)
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusRule.
|
||||||
|
func (in *PrometheusRule) DeepCopy() *PrometheusRule {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PrometheusRule)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *PrometheusRule) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PrometheusRuleList) DeepCopyInto(out *PrometheusRuleList) {
|
||||||
|
*out = *in
|
||||||
|
out.TypeMeta = in.TypeMeta
|
||||||
|
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||||
|
if in.Items != nil {
|
||||||
|
in, out := &in.Items, &out.Items
|
||||||
|
*out = make([]*PrometheusRule, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
if (*in)[i] != nil {
|
||||||
|
in, out := &(*in)[i], &(*out)[i]
|
||||||
|
*out = new(PrometheusRule)
|
||||||
|
(*in).DeepCopyInto(*out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusRuleList.
|
||||||
|
func (in *PrometheusRuleList) DeepCopy() *PrometheusRuleList {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PrometheusRuleList)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||||
|
func (in *PrometheusRuleList) DeepCopyObject() runtime.Object {
|
||||||
|
if c := in.DeepCopy(); c != nil {
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *PrometheusRuleSpec) DeepCopyInto(out *PrometheusRuleSpec) {
|
||||||
|
*out = *in
|
||||||
|
if in.Groups != nil {
|
||||||
|
in, out := &in.Groups, &out.Groups
|
||||||
|
*out = make([]RuleGroup, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PrometheusRuleSpec.
|
||||||
|
func (in *PrometheusRuleSpec) DeepCopy() *PrometheusRuleSpec {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(PrometheusRuleSpec)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *RelabelConfig) DeepCopyInto(out *RelabelConfig) {
|
func (in *RelabelConfig) DeepCopyInto(out *RelabelConfig) {
|
||||||
*out = *in
|
*out = *in
|
||||||
@ -222,3 +306,55 @@ func (in *RelabelConfig) DeepCopy() *RelabelConfig {
|
|||||||
in.DeepCopyInto(out)
|
in.DeepCopyInto(out)
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *Rule) DeepCopyInto(out *Rule) {
|
||||||
|
*out = *in
|
||||||
|
out.Expr = in.Expr
|
||||||
|
if in.Labels != nil {
|
||||||
|
in, out := &in.Labels, &out.Labels
|
||||||
|
*out = make(map[string]string, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
(*out)[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if in.Annotations != nil {
|
||||||
|
in, out := &in.Annotations, &out.Annotations
|
||||||
|
*out = make(map[string]string, len(*in))
|
||||||
|
for key, val := range *in {
|
||||||
|
(*out)[key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Rule.
|
||||||
|
func (in *Rule) DeepCopy() *Rule {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(Rule)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
|
func (in *RuleGroup) DeepCopyInto(out *RuleGroup) {
|
||||||
|
*out = *in
|
||||||
|
if in.Rules != nil {
|
||||||
|
in, out := &in.Rules, &out.Rules
|
||||||
|
*out = make([]Rule, len(*in))
|
||||||
|
for i := range *in {
|
||||||
|
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RuleGroup.
|
||||||
|
func (in *RuleGroup) DeepCopy() *RuleGroup {
|
||||||
|
if in == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
out := new(RuleGroup)
|
||||||
|
in.DeepCopyInto(out)
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
63
builders/prometheus_rule.go
Executable file
63
builders/prometheus_rule.go
Executable file
@ -0,0 +1,63 @@
|
|||||||
|
package builders
|
||||||
|
|
||||||
|
import (
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
monitoringv1 "opendev.org/vexxhost/openstack-operator/api/monitoring/v1"
|
||||||
|
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PrometheusRuleBuilder provides an interface to build PrometheusRules
|
||||||
|
type PrometheusRuleBuilder struct {
|
||||||
|
obj *monitoringv1.PrometheusRule
|
||||||
|
ruleGroups []*RuleGroupBuilder
|
||||||
|
owner metav1.Object
|
||||||
|
scheme *runtime.Scheme
|
||||||
|
}
|
||||||
|
|
||||||
|
// PrometheusRule returns a new PrometheusRule builder
|
||||||
|
func PrometheusRule(existing *monitoringv1.PrometheusRule, owner metav1.Object, scheme *runtime.Scheme) *PrometheusRuleBuilder {
|
||||||
|
return &PrometheusRuleBuilder{
|
||||||
|
obj: existing,
|
||||||
|
owner: owner,
|
||||||
|
scheme: scheme,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RuleGroups returns the ruleGroups
|
||||||
|
func (pm *PrometheusRuleBuilder) RuleGroups(ruleGroups ...*RuleGroupBuilder) *PrometheusRuleBuilder {
|
||||||
|
pm.ruleGroups = ruleGroups
|
||||||
|
return pm
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns the object after making certain assertions
|
||||||
|
func (pm *PrometheusRuleBuilder) Build() error {
|
||||||
|
pm.obj.Spec.Groups = []monitoringv1.RuleGroup{}
|
||||||
|
for _, rgBuilder := range pm.ruleGroups {
|
||||||
|
ruleGroup, err := rgBuilder.Build()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
pm.obj.Spec.Groups = append(pm.obj.Spec.Groups, ruleGroup)
|
||||||
|
}
|
||||||
|
if !pm.isOwnedByOthers() {
|
||||||
|
return controllerutil.SetControllerReference(pm.owner, pm.obj, pm.scheme)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// isOwnedByOthers checks if this podMonitor has been possessed by an another object already.
|
||||||
|
func (pm *PrometheusRuleBuilder) isOwnedByOthers() bool {
|
||||||
|
ownerName := pm.owner.GetName()
|
||||||
|
|
||||||
|
existingRefs := pm.obj.GetOwnerReferences()
|
||||||
|
for _, r := range existingRefs {
|
||||||
|
if r.Name == ownerName {
|
||||||
|
return false
|
||||||
|
} else if r.Controller != nil && *r.Controller {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
53
builders/rule.go
Executable file
53
builders/rule.go
Executable file
@ -0,0 +1,53 @@
|
|||||||
|
package builders
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/intstr"
|
||||||
|
monitoringv1 "opendev.org/vexxhost/openstack-operator/api/monitoring/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RuleBuilder provides an interface to build rule
|
||||||
|
type RuleBuilder struct {
|
||||||
|
obj *monitoringv1.Rule
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rule returns a new podmonitor builder
|
||||||
|
func Rule() *RuleBuilder {
|
||||||
|
Rule := &monitoringv1.Rule{
|
||||||
|
Annotations: map[string]string{},
|
||||||
|
}
|
||||||
|
return &RuleBuilder{
|
||||||
|
obj: Rule,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleBuilder) Alert(alert string) *RuleBuilder {
|
||||||
|
r.obj.Alert = alert
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleBuilder) Expr(expr string) *RuleBuilder {
|
||||||
|
r.obj.Expr = intstr.FromString(expr)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleBuilder) For(duration string) *RuleBuilder {
|
||||||
|
r.obj.For = duration
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleBuilder) Priority(p int) *RuleBuilder {
|
||||||
|
r.obj.Annotations["priority"] = "P" + strconv.Itoa(p)
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleBuilder) Message(m string) *RuleBuilder {
|
||||||
|
r.obj.Annotations["message"] = m
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns the object after making certain assertions
|
||||||
|
func (r *RuleBuilder) Build() (monitoringv1.Rule, error) {
|
||||||
|
return *r.obj, nil
|
||||||
|
}
|
55
builders/rule_group.go
Executable file
55
builders/rule_group.go
Executable file
@ -0,0 +1,55 @@
|
|||||||
|
package builders
|
||||||
|
|
||||||
|
import (
|
||||||
|
monitoringv1 "opendev.org/vexxhost/openstack-operator/api/monitoring/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
// RuleGroupBuilder provides an interface to build RuleGroup
|
||||||
|
type RuleGroupBuilder struct {
|
||||||
|
obj *monitoringv1.RuleGroup
|
||||||
|
rules []*RuleBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
// RuleGroup returns a new rulegroup builder
|
||||||
|
func RuleGroup() *RuleGroupBuilder {
|
||||||
|
RuleGroup := &monitoringv1.RuleGroup{}
|
||||||
|
return &RuleGroupBuilder{
|
||||||
|
obj: RuleGroup,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleGroupBuilder) Name(Name string) *RuleGroupBuilder {
|
||||||
|
r.obj.Name = Name
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleGroupBuilder) Interval(Interval string) *RuleGroupBuilder {
|
||||||
|
r.obj.Interval = Interval
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleGroupBuilder) Rules(Rules ...*RuleBuilder) *RuleGroupBuilder {
|
||||||
|
r.rules = Rules
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *RuleGroupBuilder) PartialResponseStrategy(prs string) *RuleGroupBuilder {
|
||||||
|
r.obj.PartialResponseStrategy = prs
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build returns the object after making certain assertions
|
||||||
|
func (r *RuleGroupBuilder) Build() (monitoringv1.RuleGroup, error) {
|
||||||
|
|
||||||
|
r.obj.Rules = []monitoringv1.Rule{}
|
||||||
|
for _, rBuilder := range r.rules {
|
||||||
|
rule, err := rBuilder.Build()
|
||||||
|
if err != nil {
|
||||||
|
return monitoringv1.RuleGroup{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
r.obj.Rules = append(r.obj.Rules, rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
return *r.obj, nil
|
||||||
|
}
|
@ -17,6 +17,7 @@ spec:
|
|||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
validation:
|
validation:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
|
description: PodMonitor defines monitoring for a set of pods.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: 'APIVersion defines the versioned schema of this representation
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
97
chart/crds/monitoring.coreos.com_prometheusrules.yaml
Normal file
97
chart/crds/monitoring.coreos.com_prometheusrules.yaml
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.2.5
|
||||||
|
creationTimestamp: null
|
||||||
|
name: prometheusrules.monitoring.coreos.com
|
||||||
|
spec:
|
||||||
|
group: monitoring.coreos.com
|
||||||
|
names:
|
||||||
|
kind: PrometheusRule
|
||||||
|
listKind: PrometheusRuleList
|
||||||
|
plural: prometheusrules
|
||||||
|
singular: prometheusrule
|
||||||
|
scope: Namespaced
|
||||||
|
validation:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: PrometheusRule defines alerting rules for a Prometheus instance
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
of an object. Servers should convert recognized schemas to the latest
|
||||||
|
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: 'Kind is a string value representing the REST resource this
|
||||||
|
object represents. Servers may infer this from the endpoint the client
|
||||||
|
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: Specification of desired alerting rule definitions for Prometheus.
|
||||||
|
properties:
|
||||||
|
groups:
|
||||||
|
description: Content of Prometheus rule file
|
||||||
|
items:
|
||||||
|
description: 'RuleGroup is a list of sequentially evaluated recording
|
||||||
|
and alerting rules. Note: PartialResponseStrategy is only used by
|
||||||
|
ThanosRuler and will be ignored by Prometheus instances. Valid
|
||||||
|
values for this field are ''warn'' or ''abort''. More info: https://github.com/thanos-io/thanos/blob/master/docs/components/rule.md#partial-response'
|
||||||
|
properties:
|
||||||
|
interval:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
partial_response_strategy:
|
||||||
|
type: string
|
||||||
|
rules:
|
||||||
|
items:
|
||||||
|
description: Rule describes an alerting or recording rule.
|
||||||
|
properties:
|
||||||
|
alert:
|
||||||
|
type: string
|
||||||
|
annotations:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
expr:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: string
|
||||||
|
x-kubernetes-int-or-string: true
|
||||||
|
for:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
record:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- expr
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- rules
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
version: v1
|
||||||
|
versions:
|
||||||
|
- name: v1
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -103,3 +103,23 @@ rules:
|
|||||||
- get
|
- get
|
||||||
- patch
|
- patch
|
||||||
- update
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- monitoring.coreos.com
|
||||||
|
resources:
|
||||||
|
- prometheusrules
|
||||||
|
verbs:
|
||||||
|
- create
|
||||||
|
- delete
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- monitoring.coreos.com
|
||||||
|
resources:
|
||||||
|
- prometheusrules/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
|
@ -17,6 +17,7 @@ spec:
|
|||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
validation:
|
validation:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
|
description: PodMonitor defines monitoring for a set of pods.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: 'APIVersion defines the versioned schema of this representation
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
97
config/crd/bases/monitoring.coreos.com_prometheusrules.yaml
Normal file
97
config/crd/bases/monitoring.coreos.com_prometheusrules.yaml
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1beta1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.2.5
|
||||||
|
creationTimestamp: null
|
||||||
|
name: prometheusrules.monitoring.coreos.com
|
||||||
|
spec:
|
||||||
|
group: monitoring.coreos.com
|
||||||
|
names:
|
||||||
|
kind: PrometheusRule
|
||||||
|
listKind: PrometheusRuleList
|
||||||
|
plural: prometheusrules
|
||||||
|
singular: prometheusrule
|
||||||
|
scope: Namespaced
|
||||||
|
validation:
|
||||||
|
openAPIV3Schema:
|
||||||
|
description: PrometheusRule defines alerting rules for a Prometheus instance
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: 'APIVersion defines the versioned schema of this representation
|
||||||
|
of an object. Servers should convert recognized schemas to the latest
|
||||||
|
internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: 'Kind is a string value representing the REST resource this
|
||||||
|
object represents. Servers may infer this from the endpoint the client
|
||||||
|
submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: Specification of desired alerting rule definitions for Prometheus.
|
||||||
|
properties:
|
||||||
|
groups:
|
||||||
|
description: Content of Prometheus rule file
|
||||||
|
items:
|
||||||
|
description: 'RuleGroup is a list of sequentially evaluated recording
|
||||||
|
and alerting rules. Note: PartialResponseStrategy is only used by
|
||||||
|
ThanosRuler and will be ignored by Prometheus instances. Valid
|
||||||
|
values for this field are ''warn'' or ''abort''. More info: https://github.com/thanos-io/thanos/blob/master/docs/components/rule.md#partial-response'
|
||||||
|
properties:
|
||||||
|
interval:
|
||||||
|
type: string
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
partial_response_strategy:
|
||||||
|
type: string
|
||||||
|
rules:
|
||||||
|
items:
|
||||||
|
description: Rule describes an alerting or recording rule.
|
||||||
|
properties:
|
||||||
|
alert:
|
||||||
|
type: string
|
||||||
|
annotations:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
expr:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: string
|
||||||
|
x-kubernetes-int-or-string: true
|
||||||
|
for:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
record:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- expr
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
- rules
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
version: v1
|
||||||
|
versions:
|
||||||
|
- name: v1
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
status:
|
||||||
|
acceptedNames:
|
||||||
|
kind: ""
|
||||||
|
plural: ""
|
||||||
|
conditions: []
|
||||||
|
storedVersions: []
|
@ -5,6 +5,7 @@ resources:
|
|||||||
- bases/infrastructure.vexxhost.cloud_mcrouters.yaml
|
- bases/infrastructure.vexxhost.cloud_mcrouters.yaml
|
||||||
- bases/infrastructure.vexxhost.cloud_memcacheds.yaml
|
- bases/infrastructure.vexxhost.cloud_memcacheds.yaml
|
||||||
- bases/monitoring.coreos.com_podmonitors.yaml
|
- bases/monitoring.coreos.com_podmonitors.yaml
|
||||||
|
- bases/monitoring.coreos.com_prometheusrules.yaml
|
||||||
# +kubebuilder:scaffold:crdkustomizeresource
|
# +kubebuilder:scaffold:crdkustomizeresource
|
||||||
|
|
||||||
patchesStrategicMerge:
|
patchesStrategicMerge:
|
||||||
|
@ -103,3 +103,23 @@ rules:
|
|||||||
- get
|
- get
|
||||||
- patch
|
- patch
|
||||||
- update
|
- update
|
||||||
|
- apiGroups:
|
||||||
|
- monitoring.coreos.com
|
||||||
|
resources:
|
||||||
|
- prometheusrules
|
||||||
|
verbs:
|
||||||
|
- create
|
||||||
|
- delete
|
||||||
|
- get
|
||||||
|
- list
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
|
- watch
|
||||||
|
- apiGroups:
|
||||||
|
- monitoring.coreos.com
|
||||||
|
resources:
|
||||||
|
- prometheusrules/status
|
||||||
|
verbs:
|
||||||
|
- get
|
||||||
|
- patch
|
||||||
|
- update
|
||||||
|
@ -28,7 +28,7 @@ type McrouterReconciler struct {
|
|||||||
|
|
||||||
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=mcrouters,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=mcrouters,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=mcrouters/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=mcrouters/status,verbs=get;update;patch
|
||||||
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=core,resources=configmaps;services,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=core,resources=configmaps;services,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
|
||||||
@ -47,6 +47,7 @@ func (r *McrouterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"app.kubernetes.io/name": "mcrouter",
|
"app.kubernetes.io/name": "mcrouter",
|
||||||
"app.kubernetes.io/instance": req.Name,
|
"app.kubernetes.io/instance": req.Name,
|
||||||
|
"app.kubernetes.io/managed-by": "openstack-operator",
|
||||||
}
|
}
|
||||||
|
|
||||||
// ConfigMap
|
// ConfigMap
|
||||||
@ -58,6 +59,7 @@ func (r *McrouterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
}
|
}
|
||||||
op, err := utils.CreateOrUpdate(ctx, r, configMap, func() error {
|
op, err := utils.CreateOrUpdate(ctx, r, configMap, func() error {
|
||||||
b, err := json.Marshal(mcrouter.Spec)
|
b, err := json.Marshal(mcrouter.Spec)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -131,6 +133,7 @@ func (r *McrouterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
Name: fmt.Sprintf("mcrouter-podmonitor"),
|
Name: fmt.Sprintf("mcrouter-podmonitor"),
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"app.kubernetes.io/name": "mcrouter",
|
"app.kubernetes.io/name": "mcrouter",
|
||||||
|
"app.kubernetes.io/managed-by": "openstack-operator",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -151,7 +154,40 @@ func (r *McrouterReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return ctrl.Result{}, err
|
return ctrl.Result{}, err
|
||||||
}
|
}
|
||||||
log.WithValues("resource", "podmonitor").WithValues("op", op).Info("Reconciled")
|
log.WithValues("resource", "mcrouter-podmonitor").WithValues("op", op).Info("Reconciled")
|
||||||
|
|
||||||
|
// Alertrule
|
||||||
|
alertRule := &monitoringv1.PrometheusRule{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: req.Namespace,
|
||||||
|
Name: fmt.Sprintf("mcrouter-alertrule"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
op, err = utils.CreateOrUpdate(ctx, r, alertRule, func() error {
|
||||||
|
|
||||||
|
return builders.PrometheusRule(alertRule, &mcrouter, r.Scheme).
|
||||||
|
RuleGroups(builders.RuleGroup().
|
||||||
|
Name("mcrouter-rule").
|
||||||
|
Rules(
|
||||||
|
|
||||||
|
builders.Rule().
|
||||||
|
Alert("McrouterBackendDown").
|
||||||
|
Message("Backend Memcached servers are down.").
|
||||||
|
Priority(1).
|
||||||
|
Expr("mcrouter_servers{state='down'}!=0"),
|
||||||
|
builders.Rule().
|
||||||
|
Alert("McrouterBackendTimeout").
|
||||||
|
Message("Backend Memcached servers are timeout.").
|
||||||
|
Priority(1).
|
||||||
|
Expr("mcrouter_server_memcached_timeout_count>0"),
|
||||||
|
).
|
||||||
|
Interval("1m")).
|
||||||
|
Build()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
log.WithValues("resource", "mcrouter-alertrule").WithValues("op", op).Info("Reconciled")
|
||||||
|
|
||||||
// Service
|
// Service
|
||||||
service := &corev1.Service{
|
service := &corev1.Service{
|
||||||
|
@ -47,7 +47,7 @@ type MemcachedReconciler struct {
|
|||||||
|
|
||||||
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=memcacheds,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=memcacheds/status,verbs=get;update;patch
|
// +kubebuilder:rbac:groups=infrastructure.vexxhost.cloud,resources=memcacheds/status,verbs=get;update;patch
|
||||||
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=prometheusrules,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=monitoring.coreos.com,resources=podmonitors,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch;create;update;patch;delete
|
||||||
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
|
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
|
||||||
@ -69,6 +69,7 @@ func (r *MemcachedReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
labels := map[string]string{
|
labels := map[string]string{
|
||||||
"app.kubernetes.io/name": "memcached",
|
"app.kubernetes.io/name": "memcached",
|
||||||
"app.kubernetes.io/instance": req.Name,
|
"app.kubernetes.io/instance": req.Name,
|
||||||
|
"app.kubernetes.io/managed-by": "openstack-operator",
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deployment
|
// Deployment
|
||||||
@ -129,6 +130,7 @@ func (r *MemcachedReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
Name: fmt.Sprintf("memcached-podmonitor"),
|
Name: fmt.Sprintf("memcached-podmonitor"),
|
||||||
Labels: map[string]string{
|
Labels: map[string]string{
|
||||||
"app.kubernetes.io/name": "memcached",
|
"app.kubernetes.io/name": "memcached",
|
||||||
|
"app.kubernetes.io/managed-by": "openstack-operator",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -175,6 +177,34 @@ func (r *MemcachedReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
|
|||||||
return ctrl.Result{Requeue: true}, nil
|
return ctrl.Result{Requeue: true}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alertrule
|
||||||
|
alertRule := &monitoringv1.PrometheusRule{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Namespace: req.Namespace,
|
||||||
|
Name: fmt.Sprintf("memcached-alertrule"),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
op, err = utils.CreateOrUpdate(ctx, r, alertRule, func() error {
|
||||||
|
|
||||||
|
return builders.PrometheusRule(alertRule, &memcached, r.Scheme).
|
||||||
|
RuleGroups(builders.RuleGroup().
|
||||||
|
Name("memcached-rule").
|
||||||
|
Rules(
|
||||||
|
|
||||||
|
builders.Rule().
|
||||||
|
Alert("MemcachedConnectionLimit").
|
||||||
|
Message("This memcached connection is over max.").
|
||||||
|
Priority(1).
|
||||||
|
Expr("memcached_current_connections/memcached_max_connections*100 >90"),
|
||||||
|
).
|
||||||
|
Interval("1m")).
|
||||||
|
Build()
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
log.WithValues("resource", "memcached-alertrule").WithValues("op", op).Info("Reconciled")
|
||||||
|
|
||||||
// Make sure that they're sorted so we're idempotent
|
// Make sure that they're sorted so we're idempotent
|
||||||
sort.Strings(servers)
|
sort.Strings(servers)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user