@leverege/build-tools 2.65.1 → 2.66.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/package.json +3 -3
  2. package/src/clone-cnpg-from-snapshot.mjs +5 -3
  3. package/src/helm-charts/cnpg-operator/cnpg-cleanup-cronjob.yaml.ovh +67 -0
  4. package/src/helm-charts/cnpg-operator/cnpg-cleanup-script.sh +73 -0
  5. package/src/helm-charts/cnpg-operator/gitignore +1 -0
  6. package/src/helm-charts/cnpg-operator/helmup-1.26.0-rc1.plugin +28 -0
  7. package/src/helm-charts/cnpg-operator/helmup.plugin +2 -3
  8. package/src/helm-charts/elasticsearch8/helmup.plugin +1 -1
  9. package/src/helm-charts/prom-operator/helmup.plugin +1 -1
  10. package/src/helm-charts/prom-operator/prometheus-stack.yaml.ovh +1 -1
  11. package/src/helm-charts/prom-operator/rules/awesome-base/elasticsearch-rules.yaml +219 -0
  12. package/src/helm-charts/prom-operator/rules/awesome-base/etcd-exporter.yaml +153 -0
  13. package/src/helm-charts/prom-operator/rules/awesome-base/google-cadvisor.yaml +108 -0
  14. package/src/helm-charts/prom-operator/rules/{new-awesome.yaml → awesome-base/kubestate-exporter.yaml} +2 -1
  15. package/src/helm-charts/prom-operator/rules/awesome-base/prometheus-rules.yaml +318 -0
  16. package/src/helm-charts/prom-operator/rules/awesome-base/redis-rules.yaml +142 -0
  17. package/src/helm-charts/prom-operator/rules/awesome-base/traefik-rules.yaml +43 -0
  18. package/src/helm-charts/prom-operator/rules/cadvisor-rules.yaml +109 -0
  19. package/src/helm-charts/prom-operator/rules/elasticsearch-rules.yaml +213 -95
  20. package/src/helm-charts/prom-operator/rules/etcd-rulte.yaml +153 -0
  21. package/src/helm-charts/prom-operator/rules/kubestate-rules.yaml +412 -0
  22. package/src/helm-charts/prom-operator/rules/prometheus-rules.yaml +312 -73
  23. package/src/helm-charts/prom-operator/rules/redis-rules.yaml +136 -75
  24. package/src/helm-charts/prom-operator/rules/traefik-rules.yaml +48 -21
  25. package/src/helm-charts/prom-operator/stackdriver-exporter.yaml.ovh +21 -1
  26. package/src/helm-charts/redis/helmup.plugin +1 -1
  27. package/src/helm-charts/traefik/helmup.plugin +1 -1
  28. package/src/helm-charts/velero/helmup.plugin +1 -1
  29. package/src/helm-charts/velero/{velero-local.yaml → values-local.yaml} +1 -1
  30. package/src/helmup.sh +43 -10
  31. package/src/templates/cloudBuildSteps.hbs +6 -2
  32. package/src/helm-charts/cnpg-operator/cnpg-cleanup-snapshot-cronjob.yaml +0 -73
  33. package/src/helm-charts/prom-operator/rules/awesome-k8s.yaml +0 -326
  34. package/src/helm-charts/prom-operator/rules/kubernetes-rules.yaml +0 -109
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leverege/build-tools",
3
- "version": "2.65.1",
3
+ "version": "2.66.1",
4
4
  "description": "A collection of build / support tools for Leverege developers",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -83,10 +83,10 @@
83
83
  "semver": "^7.7.1",
84
84
  "simple-git": "^3.27.0",
85
85
  "toml": "^3.0.0",
86
- "zx": "^8.5.0"
86
+ "zx": "^8.5.2"
87
87
  },
88
88
  "devDependencies": {
89
89
  "@leverege/eslint-config-leverege": "^5.0.1",
90
- "npm": "^11.2.0"
90
+ "npm": "^11.3.0"
91
91
  }
92
92
  }
@@ -83,7 +83,7 @@ const touchFile = async ( filename ) => {
83
83
 
84
84
  // generates an executable script to use for defining the volume on k8s
85
85
  const writeApplyScript = async ( dir ) => {
86
- const applyScript = `#!/ust/bin/env bash
86
+ const applyScript = `#!/usr/bin/env bash
87
87
  #
88
88
  # Apply VolumeSnapshot resources prior to deploying the CNPG cluster
89
89
  #
@@ -387,7 +387,7 @@ const main = async () => {
387
387
  log( `
388
388
  ✅ Done. Snapshot: ${chalk.cyan( destSnapshot )}
389
389
  Recovery YAMLs written to: ${chalk.cyan( emitYamlDir )}
390
- Run '${chalk.yellow( './apply-recovery-yaml.sh' )}' to prep the cluster for recovery.
390
+ Run '${chalk.yellow( './apply-volumesnapshots.sh' )}' to prep the cluster for recovery.
391
391
  ` )
392
392
  }
393
393
 
@@ -434,7 +434,7 @@ const cleanupResources = async () => {
434
434
  } ) )
435
435
  )
436
436
 
437
- log( chalk.green( ' [✓] Parallel complete. Final GCE snapshot retained for CNPG bootstrapping.' ) )
437
+ log( chalk.green( '\n [✓] Parallel cleanup complete - final GCE snapshot retained for CNPG bootstrapping\n' ) )
438
438
  }
439
439
 
440
440
  if ( cleanupOnly ) {
@@ -447,3 +447,5 @@ await main().catch( err => errorExit( err.message || err ) )
447
447
  if ( cleanup ) {
448
448
  await cleanupResources()
449
449
  }
450
+
451
+ log( chalk.green( ` [✓] Cloning complete - recovery image name is => ${chalk.bold.yellow( k8sSnapshotName )}\n` ) )
@@ -0,0 +1,67 @@
1
+ apiVersion: v1
2
+ kind: ServiceAccount
3
+ metadata:
4
+ name: cnpg-cleanup-sa
5
+ namespace: cnpg-operands
6
+ annotations:
7
+ # wire up this KSA to the GSA to hook into IAM for workload identity
8
+ iam.gke.io/gcp-service-account: cnpg-cleanup-sa@${PROJECT_ID}.iam.gserviceaccount.com
9
+ ---
10
+ apiVersion: rbac.authorization.k8s.io/v1
11
+ kind: Role
12
+ metadata:
13
+ name: cnpg-cleanup-role
14
+ namespace: cnpg-operands
15
+ rules:
16
+ - apiGroups: ["postgresql.cnpg.io"]
17
+ resources: ["backups"]
18
+ verbs: ["get", "list", "delete"]
19
+ - apiGroups: ["snapshot.storage.k8s.io"]
20
+ resources: ["volumesnapshots"]
21
+ verbs: ["get", "list", "delete"]
22
+ ---
23
+ apiVersion: rbac.authorization.k8s.io/v1
24
+ kind: RoleBinding
25
+ metadata:
26
+ name: cnpg-cleanup-rolebinding
27
+ namespace: cnpg-operands
28
+ subjects:
29
+ - kind: ServiceAccount
30
+ name: cnpg-cleanup-sa
31
+ namespace: cnpg-operands
32
+ roleRef:
33
+ kind: Role
34
+ name: cnpg-cleanup-role
35
+ apiGroup: rbac.authorization.k8s.io
36
+ ---
37
+ apiVersion: batch/v1
38
+ kind: CronJob
39
+ metadata:
40
+ name: cnpg-cleanup-snapshot
41
+ namespace: cnpg-operands
42
+ spec:
43
+ schedule: "0 11 * * *" # 11 UTC is ~7AM EST
44
+ # schedule: "*/5 * * * *" # every 5 minutes for testing
45
+ successfulJobsHistoryLimit: 1
46
+ jobTemplate:
47
+ spec:
48
+ template:
49
+ spec:
50
+ restartPolicy: Never
51
+ serviceAccountName: cnpg-cleanup-sa
52
+ containers:
53
+ - name: cnpg-cleanup
54
+ image: gcr.io/google.com/cloudsdktool/cloud-sdk:latest
55
+ env:
56
+ - name: DRY_RUN
57
+ value: "false"
58
+ - name: RETENTION_DAYS
59
+ value: "21"
60
+ command:
61
+ - /bin/bash
62
+ - -c
63
+ - |
64
+ echo "🚀 Fetching cleanup script from GCS..."
65
+ apt-get update -qq
66
+ apt-get install -y jq libjq1 libonig5 --no-install-recommends -o=Dpkg::Use-Pty=0 -o=APT::Get::Assume-Yes=1 -o=Debug::pkgProblemResolver=1
67
+ gsutil cat gs://${PROJECT_ID}-k8s-cronjobs/cnpg-cleanup-script.sh | bash
@@ -0,0 +1,73 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ KUBECTL_DELETE_ARGS=""
5
+ [[ "$DRY_RUN" == "true" ]] && KUBECTL_DELETE_ARGS="--dry-run=server"
6
+
7
+ # volumesnapshots namespace can be set here but if we need more than just the
8
+ # cnpg-operands then we'll need to the Role with a ClusterRole and bind it
9
+ # differently as well.
10
+ VSNAPS_NS="-n cnpg-operands"
11
+
12
+ # Default retention period (can override with env)
13
+ RETENTION_DAYS="${RETENTION_DAYS:-21}"
14
+ CURRENT_DATE=$(date +%s)
15
+
16
+ log() {
17
+ echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] $*"
18
+ }
19
+
20
+ should_delete() {
21
+ local creation_ts="$1"
22
+ local age_days
23
+ local created_secs
24
+ created_secs=$(date -d "$creation_ts" +%s)
25
+ age_days=$(( (CURRENT_DATE - created_secs) / 86400 ))
26
+ if (( age_days > RETENTION_DAYS )); then
27
+ echo "$age_days"
28
+ return 0
29
+ fi
30
+ return 1
31
+ }
32
+
33
+ cleanup_cnpg_backups() {
34
+ log "🔍 Cleaning CNPG backups older than $RETENTION_DAYS days"
35
+ kubectl get backups.postgresql.cnpg.io -n cnpg-operands -o json | jq -c '.items[]' | while read -r item; do
36
+ name=$(echo "$item" | jq -r '.metadata.name')
37
+ created=$(echo "$item" | jq -r '.metadata.creationTimestamp')
38
+ [[ "$name" != *"-backup-"* ]] && log "Skipping manual backup: $name" && continue
39
+
40
+ if age=$(should_delete "$created"); then
41
+ log "🗑 Deleting CNPG backup: $name (Age: $age days)"
42
+ kubectl delete backups.postgresql.cnpg.io "$name" -n cnpg-operands --ignore-not-found --wait=false $KUBECTL_DELETE_ARGS
43
+ fi
44
+ done
45
+ log "✅ CNPG backup cleanup complete"
46
+ }
47
+
48
+ cleanup_volume_snapshots() {
49
+ log "🔍 Cleaning VolumeSnapshots older than $RETENTION_DAYS days"
50
+ kubectl get volumesnapshots $VSNAPS_NS -o json | jq -c '.items[]' | while read -r item; do
51
+ ns=$(echo "$item" | jq -r '.metadata.namespace')
52
+ name=$(echo "$item" | jq -r '.metadata.name')
53
+ created=$(echo "$item" | jq -r '.metadata.creationTimestamp')
54
+ ready=$(echo "$item" | jq -r '.status.readyToUse // false')
55
+
56
+ [[ "$ready" != "true" ]] && continue
57
+
58
+ if age=$(should_delete "$created"); then
59
+ log "🗑 Deleting VolumeSnapshot: $ns/$name (Age: $age days)"
60
+ kubectl delete volumesnapshot -n "$ns" "$name" --ignore-not-found --wait=false $KUBECTL_DELETE_ARGS
61
+ fi
62
+ done
63
+ log "✅ VolumeSnapshot cleanup complete"
64
+ }
65
+
66
+ main() {
67
+ log "🚀 Starting cleanup job (retention: $RETENTION_DAYS days)"
68
+ cleanup_cnpg_backups
69
+ cleanup_volume_snapshots
70
+ log "🏁 All cleanup tasks complete"
71
+ }
72
+
73
+ main
@@ -0,0 +1 @@
1
+ cnpg-cleanup-cronjob.yaml
@@ -0,0 +1,28 @@
1
+ #!/bin/bash
2
+ #
3
+ # See => https://cloudnative-pg.io/documentation/current/installation_upgrade/
4
+ #
5
+ # OPVER="1.25.1"
6
+ OPVER="1.26.0-rc1" # 03/28/2025
7
+
8
+ createNamespaceIfNeeded cnpg-system
9
+
10
+ kubectl apply --server-side -f \
11
+ https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-${OPVER}.yaml $K8S_WHAT
12
+
13
+ # Legacy terraformed clusters (like sandbox) may need a special firewall rule
14
+ # added to the network layer on k8s. It should look like this:
15
+ #
16
+ # Name : cnpg-operator
17
+ # Ports : 8000,9443 <= kubectl cnpg status and webhooks
18
+ # Filters: 172.16.0.0/28 <= k8s control plane
19
+ #
20
+ # Old approach used the helm chart.
21
+ #
22
+ #addHelmRepo cnpg https://cloudnative-pg.github.io/charts
23
+ #
24
+ #helm upgrade --install cnpg cnpg/cloudnative-pg \
25
+ # --namespace cnpg-system --create-namespace \
26
+ # --set webhook.port="10250" $HELM_WHAT
27
+ #
28
+ #removeHelmRepo cnpg
@@ -2,13 +2,12 @@
2
2
  #
3
3
  # See => https://cloudnative-pg.io/documentation/current/installation_upgrade/
4
4
  #
5
- # OPVER="1.25.1"
6
- OPVER="1.26.0-rc1" # 03/28/2025
5
+ OPVER="1.25.1"
7
6
 
8
7
  createNamespaceIfNeeded cnpg-system
9
8
 
10
9
  kubectl apply --server-side -f \
11
- https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/main/releases/cnpg-${OPVER}.yaml $K8S_WHAT
10
+ https://raw.githubusercontent.com/cloudnative-pg/cloudnative-pg/release-${OPVER%.*}/releases/cnpg-${OPVER}.yaml $K8S_WHAT
12
11
 
13
12
  # Legacy terraformed clusters (like sandbox) may need a special firewall rule
14
13
  # added to the network layer on k8s. It should look like this:
@@ -2,7 +2,7 @@
2
2
  #
3
3
  showInstalling "Elastic Search 8"
4
4
 
5
- [ -z "$ELASTIC_CHART_VERSION" ] && ELASTIC_CHART_VERSION="21.4.8"
5
+ [ -z "$ELASTIC_CHART_VERSION" ] && ELASTIC_CHART_VERSION="21.5.0"
6
6
 
7
7
  OCI_CHART="oci://registry-1.docker.io/bitnamicharts/elasticsearch"
8
8
 
@@ -4,7 +4,7 @@ showInstalling "The Prometheus Operator and Components"
4
4
  addHelmRepo prometheus-community https://prometheus-community.github.io/helm-charts
5
5
 
6
6
  showInstalling "The Prometheus Operator (kube-prometheus-stack)"
7
- [ -z "$PROMETHEUS_STACK_CHART_VERSION" ] && PROMETHEUS_STACK_CHART_VERSION="69"
7
+ [ -z "$PROMETHEUS_STACK_CHART_VERSION" ] && PROMETHEUS_STACK_CHART_VERSION="70"
8
8
 
9
9
  NS="--namespace prometheus"
10
10
 
@@ -19,7 +19,7 @@ defaultRules:
19
19
  kubePrometheusGeneral: false
20
20
  kubePrometheusNodeRecording: false
21
21
  kubernetesApps: false
22
- kubernetesResources: false
22
+ kubernetesResources: true
23
23
  kubernetesStorage: false
24
24
  kubernetesSystem: false
25
25
  kubeScheduler: false
@@ -0,0 +1,219 @@
1
+ # https://samber.github.io/awesome-prometheus-alerts/rules#elasticsearch
2
+ apiVersion: monitoring.coreos.com/v1
3
+ kind: PrometheusRule
4
+ metadata:
5
+ name: prometheus-community-elasticsearch-exporter
6
+ namespace: prometheus
7
+ spec:
8
+ groups:
9
+ - name: Elasticsearch (awesome) # PrometheusCommunityElasticsearchExporter-rules
10
+ rules:
11
+ - alert: ElasticsearchHeapUsageTooHigh
12
+ expr: (elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"}) * 100 > 90
13
+ for: 2m
14
+ labels:
15
+ severity: critical
16
+ annotations:
17
+ summary: Elasticsearch Heap Usage Too High (instance {{ $labels.instance }})
18
+ description: |-
19
+ The heap usage is over 90%
20
+ VALUE = {{ $value }}
21
+ LABELS = {{ $labels }}
22
+ - alert: ElasticsearchHeapUsageWarning
23
+ expr: (elasticsearch_jvm_memory_used_bytes{area="heap"} / elasticsearch_jvm_memory_max_bytes{area="heap"}) * 100 > 80
24
+ for: 2m
25
+ labels:
26
+ severity: warning
27
+ annotations:
28
+ summary: Elasticsearch Heap Usage warning (instance {{ $labels.instance }})
29
+ description: |-
30
+ The heap usage is over 80%
31
+ VALUE = {{ $value }}
32
+ LABELS = {{ $labels }}
33
+ - alert: ElasticsearchDiskOutOfSpace
34
+ expr: elasticsearch_filesystem_data_available_bytes / elasticsearch_filesystem_data_size_bytes * 100 < 10
35
+ for: 0m
36
+ labels:
37
+ severity: critical
38
+ annotations:
39
+ summary: Elasticsearch disk out of space (instance {{ $labels.instance }})
40
+ description: |-
41
+ The disk usage is over 90%
42
+ VALUE = {{ $value }}
43
+ LABELS = {{ $labels }}
44
+ - alert: ElasticsearchDiskSpaceLow
45
+ expr: elasticsearch_filesystem_data_available_bytes / elasticsearch_filesystem_data_size_bytes * 100 < 20
46
+ for: 2m
47
+ labels:
48
+ severity: warning
49
+ annotations:
50
+ summary: Elasticsearch disk space low (instance {{ $labels.instance }})
51
+ description: |-
52
+ The disk usage is over 80%
53
+ VALUE = {{ $value }}
54
+ LABELS = {{ $labels }}
55
+ - alert: ElasticsearchClusterRed
56
+ expr: elasticsearch_cluster_health_status{color="red"} == 1
57
+ for: 0m
58
+ labels:
59
+ severity: critical
60
+ annotations:
61
+ summary: Elasticsearch Cluster Red (instance {{ $labels.instance }})
62
+ description: |-
63
+ Elastic Cluster Red status
64
+ VALUE = {{ $value }}
65
+ LABELS = {{ $labels }}
66
+ - alert: ElasticsearchClusterYellow
67
+ expr: elasticsearch_cluster_health_status{color="yellow"} == 1
68
+ for: 0m
69
+ labels:
70
+ severity: warning
71
+ annotations:
72
+ summary: Elasticsearch Cluster Yellow (instance {{ $labels.instance }})
73
+ description: |-
74
+ Elastic Cluster Yellow status
75
+ VALUE = {{ $value }}
76
+ LABELS = {{ $labels }}
77
+ - alert: ElasticsearchHealthyNodes
78
+ expr: elasticsearch_cluster_health_number_of_nodes < 3
79
+ for: 0m
80
+ labels:
81
+ severity: critical
82
+ annotations:
83
+ summary: Elasticsearch Healthy Nodes (instance {{ $labels.instance }})
84
+ description: |-
85
+ Missing node in Elasticsearch cluster
86
+ VALUE = {{ $value }}
87
+ LABELS = {{ $labels }}
88
+ - alert: ElasticsearchHealthyDataNodes
89
+ expr: elasticsearch_cluster_health_number_of_data_nodes < 3
90
+ for: 0m
91
+ labels:
92
+ severity: critical
93
+ annotations:
94
+ summary: Elasticsearch Healthy Data Nodes (instance {{ $labels.instance }})
95
+ description: |-
96
+ Missing data node in Elasticsearch cluster
97
+ VALUE = {{ $value }}
98
+ LABELS = {{ $labels }}
99
+ - alert: ElasticsearchRelocatingShards
100
+ expr: elasticsearch_cluster_health_relocating_shards > 0
101
+ for: 0m
102
+ labels:
103
+ severity: info
104
+ annotations:
105
+ summary: Elasticsearch relocating shards (instance {{ $labels.instance }})
106
+ description: |-
107
+ Elasticsearch is relocating shards
108
+ VALUE = {{ $value }}
109
+ LABELS = {{ $labels }}
110
+ - alert: ElasticsearchRelocatingShardsTooLong
111
+ expr: elasticsearch_cluster_health_relocating_shards > 0
112
+ for: 15m
113
+ labels:
114
+ severity: warning
115
+ annotations:
116
+ summary: Elasticsearch relocating shards too long (instance {{ $labels.instance }})
117
+ description: |-
118
+ Elasticsearch has been relocating shards for 15min
119
+ VALUE = {{ $value }}
120
+ LABELS = {{ $labels }}
121
+ - alert: ElasticsearchInitializingShards
122
+ expr: elasticsearch_cluster_health_initializing_shards > 0
123
+ for: 0m
124
+ labels:
125
+ severity: info
126
+ annotations:
127
+ summary: Elasticsearch initializing shards (instance {{ $labels.instance }})
128
+ description: |-
129
+ Elasticsearch is initializing shards
130
+ VALUE = {{ $value }}
131
+ LABELS = {{ $labels }}
132
+ - alert: ElasticsearchInitializingShardsTooLong
133
+ expr: elasticsearch_cluster_health_initializing_shards > 0
134
+ for: 15m
135
+ labels:
136
+ severity: warning
137
+ annotations:
138
+ summary: Elasticsearch initializing shards too long (instance {{ $labels.instance }})
139
+ description: |-
140
+ Elasticsearch has been initializing shards for 15 min
141
+ VALUE = {{ $value }}
142
+ LABELS = {{ $labels }}
143
+ - alert: ElasticsearchUnassignedShards
144
+ expr: elasticsearch_cluster_health_unassigned_shards > 0
145
+ for: 0m
146
+ labels:
147
+ severity: critical
148
+ annotations:
149
+ summary: Elasticsearch unassigned shards (instance {{ $labels.instance }})
150
+ description: |-
151
+ Elasticsearch has unassigned shards
152
+ VALUE = {{ $value }}
153
+ LABELS = {{ $labels }}
154
+ - alert: ElasticsearchPendingTasks
155
+ expr: elasticsearch_cluster_health_number_of_pending_tasks > 0
156
+ for: 15m
157
+ labels:
158
+ severity: warning
159
+ annotations:
160
+ summary: Elasticsearch pending tasks (instance {{ $labels.instance }})
161
+ description: |-
162
+ Elasticsearch has pending tasks. Cluster works slowly.
163
+ VALUE = {{ $value }}
164
+ LABELS = {{ $labels }}
165
+ - alert: ElasticsearchNoNewDocuments
166
+ expr: increase(elasticsearch_indices_indexing_index_total{es_data_node="true"}[10m]) < 1
167
+ for: 0m
168
+ labels:
169
+ severity: warning
170
+ annotations:
171
+ summary: Elasticsearch no new documents (instance {{ $labels.instance }})
172
+ description: |-
173
+ No new documents for 10 min!
174
+ VALUE = {{ $value }}
175
+ LABELS = {{ $labels }}
176
+ - alert: ElasticsearchHighIndexingLatency
177
+ expr: elasticsearch_indices_indexing_index_time_seconds_total / elasticsearch_indices_indexing_index_total > 0.0005
178
+ for: 10m
179
+ labels:
180
+ severity: warning
181
+ annotations:
182
+ summary: Elasticsearch High Indexing Latency (instance {{ $labels.instance }})
183
+ description: |-
184
+ The indexing latency on Elasticsearch cluster is higher than the threshold.
185
+ VALUE = {{ $value }}
186
+ LABELS = {{ $labels }}
187
+ - alert: ElasticsearchHighIndexingRate
188
+ expr: sum(rate(elasticsearch_indices_indexing_index_total[1m]))> 10000
189
+ for: 5m
190
+ labels:
191
+ severity: warning
192
+ annotations:
193
+ summary: Elasticsearch High Indexing Rate (instance {{ $labels.instance }})
194
+ description: |-
195
+ The indexing rate on Elasticsearch cluster is higher than the threshold.
196
+ VALUE = {{ $value }}
197
+ LABELS = {{ $labels }}
198
+ - alert: ElasticsearchHighQueryRate
199
+ expr: sum(rate(elasticsearch_indices_search_query_total[1m])) > 100
200
+ for: 5m
201
+ labels:
202
+ severity: warning
203
+ annotations:
204
+ summary: Elasticsearch High Query Rate (instance {{ $labels.instance }})
205
+ description: |-
206
+ The query rate on Elasticsearch cluster is higher than the threshold.
207
+ VALUE = {{ $value }}
208
+ LABELS = {{ $labels }}
209
+ - alert: ElasticsearchHighQueryLatency
210
+ expr: elasticsearch_indices_search_fetch_time_seconds / elasticsearch_indices_search_fetch_total > 1
211
+ for: 5m
212
+ labels:
213
+ severity: warning
214
+ annotations:
215
+ summary: Elasticsearch High Query Latency (instance {{ $labels.instance }})
216
+ description: |-
217
+ The query latency on Elasticsearch cluster is higher than the threshold.
218
+ VALUE = {{ $value }}
219
+ LABELS = {{ $labels }}
@@ -0,0 +1,153 @@
1
+ # https://samber.github.io/awesome-prometheus-alerts/rules#etcd
2
+ apiVersion: monitoring.coreos.com/v1
3
+ kind: PrometheusRule
4
+ metadata:
5
+ name: etcd-exporter # embedded-exporter
6
+ namespace: prometheus
7
+ spec:
8
+ groups:
9
+ - name: Etcd (awesome) # EmbeddedExporter-rules
10
+ rules:
11
+ - alert: EtcdInsufficientMembers
12
+ expr: count(etcd_server_id) % 2 == 0
13
+ for: 0m
14
+ labels:
15
+ severity: critical
16
+ annotations:
17
+ summary: Etcd insufficient Members (instance {{ $labels.instance }})
18
+ description: |-
19
+ Etcd cluster should have an odd number of members
20
+ VALUE = {{ $value }}
21
+ LABELS = {{ $labels }}
22
+ - alert: EtcdNoLeader
23
+ expr: etcd_server_has_leader == 0
24
+ for: 0m
25
+ labels:
26
+ severity: critical
27
+ annotations:
28
+ summary: Etcd no Leader (instance {{ $labels.instance }})
29
+ description: |-
30
+ Etcd cluster have no leader
31
+ VALUE = {{ $value }}
32
+ LABELS = {{ $labels }}
33
+ - alert: EtcdHighNumberOfLeaderChanges
34
+ expr: increase(etcd_server_leader_changes_seen_total[10m]) > 2
35
+ for: 0m
36
+ labels:
37
+ severity: warning
38
+ annotations:
39
+ summary: Etcd high number of leader changes (instance {{ $labels.instance }})
40
+ description: |-
41
+ Etcd leader changed more than 2 times during 10 minutes
42
+ VALUE = {{ $value }}
43
+ LABELS = {{ $labels }}
44
+ - alert: EtcdHighNumberOfFailedGrpcRequests
45
+ expr: sum(rate(grpc_server_handled_total{grpc_code!="OK"}[1m])) BY (grpc_service, grpc_method) / sum(rate(grpc_server_handled_total[1m])) BY (grpc_service, grpc_method) > 0.01
46
+ for: 2m
47
+ labels:
48
+ severity: warning
49
+ annotations:
50
+ summary: Etcd high number of failed GRPC requests (instance {{ $labels.instance }})
51
+ description: |-
52
+ More than 1% GRPC request failure detected in Etcd
53
+ VALUE = {{ $value }}
54
+ LABELS = {{ $labels }}
55
+ - alert: EtcdHighNumberOfFailedGrpcRequests
56
+ expr: sum(rate(grpc_server_handled_total{grpc_code!="OK"}[1m])) BY (grpc_service, grpc_method) / sum(rate(grpc_server_handled_total[1m])) BY (grpc_service, grpc_method) > 0.05
57
+ for: 2m
58
+ labels:
59
+ severity: critical
60
+ annotations:
61
+ summary: Etcd high number of failed GRPC requests (instance {{ $labels.instance }})
62
+ description: |-
63
+ More than 5% GRPC request failure detected in Etcd
64
+ VALUE = {{ $value }}
65
+ LABELS = {{ $labels }}
66
+ - alert: EtcdGrpcRequestsSlow
67
+ expr: histogram_quantile(0.99, sum(rate(grpc_server_handling_seconds_bucket{grpc_type="unary"}[1m])) by (grpc_service, grpc_method, le)) > 0.15
68
+ for: 2m
69
+ labels:
70
+ severity: warning
71
+ annotations:
72
+ summary: Etcd GRPC requests slow (instance {{ $labels.instance }})
73
+ description: |-
74
+ GRPC requests slowing down, 99th percentile is over 0.15s
75
+ VALUE = {{ $value }}
76
+ LABELS = {{ $labels }}
77
+ - alert: EtcdHighNumberOfFailedHttpRequests
78
+ expr: sum(rate(etcd_http_failed_total[1m])) BY (method) / sum(rate(etcd_http_received_total[1m])) BY (method) > 0.01
79
+ for: 2m
80
+ labels:
81
+ severity: warning
82
+ annotations:
83
+ summary: Etcd high number of failed HTTP requests (instance {{ $labels.instance }})
84
+ description: |-
85
+ More than 1% HTTP failure detected in Etcd
86
+ VALUE = {{ $value }}
87
+ LABELS = {{ $labels }}
88
+ - alert: EtcdHighNumberOfFailedHttpRequests
89
+ expr: sum(rate(etcd_http_failed_total[1m])) BY (method) / sum(rate(etcd_http_received_total[1m])) BY (method) > 0.05
90
+ for: 2m
91
+ labels:
92
+ severity: critical
93
+ annotations:
94
+ summary: Etcd high number of failed HTTP requests (instance {{ $labels.instance }})
95
+ description: |-
96
+ More than 5% HTTP failure detected in Etcd
97
+ VALUE = {{ $value }}
98
+ LABELS = {{ $labels }}
99
+ - alert: EtcdHttpRequestsSlow
100
+ expr: histogram_quantile(0.99, rate(etcd_http_successful_duration_seconds_bucket[1m])) > 0.15
101
+ for: 2m
102
+ labels:
103
+ severity: warning
104
+ annotations:
105
+ summary: Etcd HTTP requests slow (instance {{ $labels.instance }})
106
+ description: |-
107
+ HTTP requests slowing down, 99th percentile is over 0.15s
108
+ VALUE = {{ $value }}
109
+ LABELS = {{ $labels }}
110
+ - alert: EtcdMemberCommunicationSlow
111
+ expr: histogram_quantile(0.99, rate(etcd_network_peer_round_trip_time_seconds_bucket[1m])) > 0.15
112
+ for: 2m
113
+ labels:
114
+ severity: warning
115
+ annotations:
116
+ summary: Etcd member communication slow (instance {{ $labels.instance }})
117
+ description: |-
118
+ Etcd member communication slowing down, 99th percentile is over 0.15s
119
+ VALUE = {{ $value }}
120
+ LABELS = {{ $labels }}
121
+ - alert: EtcdHighNumberOfFailedProposals
122
+ expr: increase(etcd_server_proposals_failed_total[1h]) > 5
123
+ for: 2m
124
+ labels:
125
+ severity: warning
126
+ annotations:
127
+ summary: Etcd high number of failed proposals (instance {{ $labels.instance }})
128
+ description: |-
129
+ Etcd server got more than 5 failed proposals past hour
130
+ VALUE = {{ $value }}
131
+ LABELS = {{ $labels }}
132
+ - alert: EtcdHighFsyncDurations
133
+ expr: histogram_quantile(0.99, rate(etcd_disk_wal_fsync_duration_seconds_bucket[1m])) > 0.5
134
+ for: 2m
135
+ labels:
136
+ severity: warning
137
+ annotations:
138
+ summary: Etcd high fsync durations (instance {{ $labels.instance }})
139
+ description: |-
140
+ Etcd WAL fsync duration increasing, 99th percentile is over 0.5s
141
+ VALUE = {{ $value }}
142
+ LABELS = {{ $labels }}
143
+ - alert: EtcdHighCommitDurations
144
+ expr: histogram_quantile(0.99, rate(etcd_disk_backend_commit_duration_seconds_bucket[1m])) > 0.25
145
+ for: 2m
146
+ labels:
147
+ severity: warning
148
+ annotations:
149
+ summary: Etcd high commit durations (instance {{ $labels.instance }})
150
+ description: |-
151
+ Etcd commit duration increasing, 99th percentile is over 0.25s
152
+ VALUE = {{ $value }}
153
+ LABELS = {{ $labels }}