Compare commits
310 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d2f8152a8b | ||
|
|
415afa4cc0 | ||
|
|
984de5fb3d | ||
|
|
419eaf28ce | ||
|
|
8c712eaa36 | ||
|
|
9d69c4c318 | ||
|
|
63da55bc9f | ||
|
|
cd755f2487 | ||
|
|
dd1b9d00e3 | ||
|
|
e9d5221fb7 | ||
|
|
cf039d2222 | ||
|
|
a3d67f5219 | ||
|
|
31189e3a18 | ||
|
|
4c6a06cf7e | ||
|
|
412061ef51 | ||
|
|
7b69800686 | ||
|
|
417e8b3f66 | ||
|
|
752d1a7fdc | ||
|
|
4839afb546 | ||
|
|
8b39a459fa | ||
|
|
9952e858c7 | ||
|
|
cf6f5f2801 | ||
|
|
b043054974 | ||
|
|
72b742d7e8 | ||
|
|
c96c639ef1 | ||
|
|
92016ef68d | ||
|
|
0cde11d3fb | ||
|
|
3135cdd70d | ||
|
|
07136d1d6e | ||
|
|
8b62749642 | ||
|
|
0cb0c49186 | ||
|
|
28d58a9dbc | ||
|
|
7a3879ba49 | ||
|
|
9b5b9dccf7 | ||
|
|
0306cdc053 | ||
|
|
19801f0709 | ||
|
|
e13f0db3d1 | ||
|
|
1e67c71703 | ||
|
|
ed5a2f94fc | ||
|
|
eaeb0c6acf | ||
|
|
1cefb18e55 | ||
|
|
0c468d534d | ||
|
|
de3673a286 | ||
|
|
874bf089ae | ||
|
|
f81412d05d | ||
|
|
2ba8d8aca2 | ||
|
|
0268128bd1 | ||
|
|
b59b2c23d8 | ||
|
|
cf4d2ad524 | ||
|
|
1c63b6d021 | ||
|
|
f06175bb3b | ||
|
|
069f95148f | ||
|
|
f5f72e1b50 | ||
|
|
7ba0479433 | ||
|
|
dafa0f8edd | ||
|
|
0df93109d4 | ||
|
|
17b11ae344 | ||
|
|
af0719e8d8 | ||
|
|
d1f401a73d | ||
|
|
003daae495 | ||
|
|
c9b52c97f5 | ||
|
|
6497d78f2c | ||
|
|
e3dcbb7fa6 | ||
|
|
8973a90049 | ||
|
|
c960da64bb | ||
|
|
35a22050e0 | ||
|
|
ea12911e4f | ||
|
|
4bc91a8303 | ||
|
|
9966c37573 | ||
|
|
4e5087c665 | ||
|
|
ab554c6ecb | ||
|
|
fe1a446b01 | ||
|
|
5d2156ffbf | ||
|
|
4d200f29f5 | ||
|
|
0bf34a24f8 | ||
|
|
ed884b0399 | ||
|
|
094cdb34e8 | ||
|
|
eacf316f61 | ||
|
|
63e20afe98 | ||
|
|
bea6b1a0c2 | ||
|
|
c2ac2a2838 | ||
|
|
b7d7ba0271 | ||
|
|
478a18a6a7 | ||
|
|
e8abcd3dc9 | ||
|
|
98559a0f42 | ||
|
|
1237843e62 | ||
|
|
2fa7ef162f | ||
|
|
09b30e124f | ||
|
|
4bba284d9b | ||
|
|
b473929b36 | ||
|
|
ecd70d66c8 | ||
|
|
6ece9ca0bc | ||
|
|
24afd652ab | ||
|
|
41b3f9bafd | ||
|
|
8b877c1753 | ||
|
|
70a63d1541 | ||
|
|
558574b086 | ||
|
|
d1a3ebbe90 | ||
|
|
8b30b2b669 | ||
|
|
0d2e0875d9 | ||
|
|
9a6289a045 | ||
|
|
e4b58eaa5c | ||
|
|
30a41d18d8 | ||
|
|
60d5aa25fc | ||
|
|
9268851d8b | ||
|
|
9d327cb328 | ||
|
|
5516b05926 | ||
|
|
db2f6f1acc | ||
|
|
578fa2dede | ||
|
|
7c43411531 | ||
|
|
10f710bb58 | ||
|
|
24d9633998 | ||
|
|
4b13b15f2b | ||
|
|
5f06f0da5e | ||
|
|
148fe71cc5 | ||
|
|
f5ed97771c | ||
|
|
b40fe984b3 | ||
|
|
44008b2682 | ||
|
|
3eab50538a | ||
|
|
9f6c7d7654 | ||
|
|
816c73acc6 | ||
|
|
8834c2d5e0 | ||
|
|
e3db1c174e | ||
|
|
8e5bf00c54 | ||
|
|
5f13d38155 | ||
|
|
bb2971e874 | ||
|
|
e586afb280 | ||
|
|
9785c3bb68 | ||
|
|
16c05d16e2 | ||
|
|
6961da9b90 | ||
|
|
ebd4b28b91 | ||
|
|
654283a048 | ||
|
|
e3346b8fce | ||
|
|
f8c92f0428 | ||
|
|
a9961b8f6e | ||
|
|
e13ec2e448 | ||
|
|
f7f817a79e | ||
|
|
60826aa71d | ||
|
|
9c38152dbb | ||
|
|
d9ac51aed0 | ||
|
|
d753169176 | ||
|
|
23c8d865f5 | ||
|
|
dff8d8c11c | ||
|
|
ebef4e02ef | ||
|
|
aecfa970c9 | ||
|
|
6acc4f6569 | ||
|
|
1d2a0e275a | ||
|
|
c88d18c9d2 | ||
|
|
55b6848b42 | ||
|
|
c229d9d34c | ||
|
|
c0a136a4c7 | ||
|
|
70cb4c10cd | ||
|
|
f691421c91 | ||
|
|
da05d36c31 | ||
|
|
390f2d72db | ||
|
|
7c95f88a2b | ||
|
|
32bfeea94f | ||
|
|
66e4a7ba15 | ||
|
|
bf9a917cfa | ||
|
|
5d06e286ca | ||
|
|
57730b757e | ||
|
|
c80a82b19a | ||
|
|
bc1026ae2b | ||
|
|
f039fc94cf | ||
|
|
d909241c4a | ||
|
|
8daef560ea | ||
|
|
1817baccf1 | ||
|
|
daad0e1fae | ||
|
|
a51f690387 | ||
|
|
bd0cc5675c | ||
|
|
d0c746d64b | ||
|
|
99838deb5d | ||
|
|
0c25559b39 | ||
|
|
0fbf8e03e0 | ||
|
|
cff8fec592 | ||
|
|
2a66bb88b5 | ||
|
|
d283e67059 | ||
|
|
83441715a8 | ||
|
|
e40e42cf72 | ||
|
|
30d3d5950d | ||
|
|
ff3e0e1ee4 | ||
|
|
de2d1b5231 | ||
|
|
fc1a03053d | ||
|
|
4245ded81b | ||
|
|
2ff04a63a3 | ||
|
|
a9dd864c67 | ||
|
|
73db89874e | ||
|
|
18630eaca1 | ||
|
|
f8bae9fd96 | ||
|
|
0b0b967764 | ||
|
|
11aa604d39 | ||
|
|
6dfd6d891c | ||
|
|
90298f8f5c | ||
|
|
1384b847f4 | ||
|
|
f95f0fa875 | ||
|
|
e3cd00e01a | ||
|
|
9c93c7aeee | ||
|
|
ab3dff2016 | ||
|
|
6758acbb30 | ||
|
|
102d4c6513 | ||
|
|
8588e30bd0 | ||
|
|
3670d5bf7d | ||
|
|
40c1c7a190 | ||
|
|
c2155fa206 | ||
|
|
0a79177c19 | ||
|
|
6081b306c2 | ||
|
|
5b6f50ffb2 | ||
|
|
dd8fdd68fe | ||
|
|
07a057f09d | ||
|
|
7afbfa3534 | ||
|
|
ab8132a33d | ||
|
|
4220f4e862 | ||
|
|
d3ad5de993 | ||
|
|
5cefc105f7 | ||
|
|
70cfe27872 | ||
|
|
ff3e611245 | ||
|
|
1bf4381117 | ||
|
|
a89a364ece | ||
|
|
9bba0e2a2a | ||
|
|
6d8e56727c | ||
|
|
e2dbc63764 | ||
|
|
0424835b04 | ||
|
|
4132da532c | ||
|
|
fe81e7de56 | ||
|
|
4f9d464087 | ||
|
|
625ab137fa | ||
|
|
2913c866bb | ||
|
|
66b5416bf6 | ||
|
|
b70eb1c49c | ||
|
|
369730b701 | ||
|
|
828cbbbea4 | ||
|
|
42a3ac0606 | ||
|
|
cbddf907db | ||
|
|
1eedb90c17 | ||
|
|
75f918067d | ||
|
|
092b22d62b | ||
|
|
d4c48539a0 | ||
|
|
f1bd7af657 | ||
|
|
5624c5a9a8 | ||
|
|
86d4571aea | ||
|
|
e556dbfd88 | ||
|
|
ba052559cf | ||
|
|
24496d1fac | ||
|
|
b67686409e | ||
|
|
255cd9a1c5 | ||
|
|
7335ac40d0 | ||
|
|
bed5cc8efb | ||
|
|
e2c50fa40f | ||
|
|
e02cc471f5 | ||
|
|
5dcb5de788 | ||
|
|
9cf2ce9ffc | ||
|
|
6b11d79c4b | ||
|
|
b4fcf8f6cc | ||
|
|
55900d9e1c | ||
|
|
5f9b222c41 | ||
|
|
18e804217a | ||
|
|
6e132e4490 | ||
|
|
4c1ff463db | ||
|
|
d00a923299 | ||
|
|
b5ab602911 | ||
|
|
48579a9679 | ||
|
|
ecbaa85d81 | ||
|
|
e255923c05 | ||
|
|
2ce2c80a48 | ||
|
|
7828570118 | ||
|
|
a76135a9f9 | ||
|
|
2eed12b2b7 | ||
|
|
4b47de57f8 | ||
|
|
1c06faf207 | ||
|
|
09ce4afca8 | ||
|
|
5ca429157f | ||
|
|
f2686477f4 | ||
|
|
d4999048fc | ||
|
|
6248e73890 | ||
|
|
d9b40073d4 | ||
|
|
ea3fee466e | ||
|
|
a36c6042e5 | ||
|
|
3b7d4690ba | ||
|
|
630bc31183 | ||
|
|
da817040c6 | ||
|
|
5b8feb783c | ||
|
|
19376df824 | ||
|
|
808c2f8c3d | ||
|
|
cf916082b8 | ||
|
|
a4306c9c7a | ||
|
|
b1dda44501 | ||
|
|
1928f7083a | ||
|
|
6501366ff8 | ||
|
|
2984ca585c | ||
|
|
06d7df8075 | ||
|
|
b0e2449a8b | ||
|
|
5083ae2e89 | ||
|
|
dcd99f7d68 | ||
|
|
66aca04688 | ||
|
|
eda90b6833 | ||
|
|
97aaa1f534 | ||
|
|
8b4effaba0 | ||
|
|
8d53477ec8 | ||
|
|
c2fb1f4208 | ||
|
|
b39b1bfcfc | ||
|
|
4f306fc3ff | ||
|
|
41e3f7d03f | ||
|
|
f36b68458d | ||
|
|
723ac0fd27 | ||
|
|
09ca49fce0 | ||
|
|
af0465fd79 | ||
|
|
ee553a708d | ||
|
|
3830bc8076 | ||
|
|
7d7d40b4de | ||
|
|
d37a299499 |
26
.github/workflows/ci.yaml
vendored
26
.github/workflows/ci.yaml
vendored
@@ -16,15 +16,35 @@ jobs:
|
||||
name: Generate
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ${{ env.golang-version }}
|
||||
- run: make --always-make generate && git diff --exit-code
|
||||
- run: make --always-make generate validate && git diff --exit-code
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
name: Jsonnet linter
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- run: make --always-make lint
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
name: Jsonnet formatter
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- run: make --always-make fmt && git diff --exit-code
|
||||
unit-tests:
|
||||
runs-on: ubuntu-latest
|
||||
name: Unit tests
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- run: make --always-make test
|
||||
e2e-tests:
|
||||
name: E2E tests
|
||||
@@ -32,10 +52,12 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
kind-image:
|
||||
- 'kindest/node:v1.19.0'
|
||||
- 'kindest/node:v1.20.0'
|
||||
# - 'kindest/node:v1.21.0' #TODO(paulfantom): enable as soon as image is available
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Start KinD
|
||||
uses: engineerd/setup-kind@v0.5.0
|
||||
with:
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -3,3 +3,4 @@ minikube-manifests/
|
||||
vendor/
|
||||
./auth
|
||||
.swp
|
||||
crdschemas/
|
||||
|
||||
26
.gitpod.yml
Normal file
26
.gitpod.yml
Normal file
@@ -0,0 +1,26 @@
|
||||
|
||||
tasks:
|
||||
- init: |
|
||||
make --always-make
|
||||
export PATH="$(pwd)/tmp/bin:${PATH}"
|
||||
cat > ${PWD}/.git/hooks/pre-commit <<EOF
|
||||
#!/bin/bash
|
||||
|
||||
echo "Checking jsonnet fmt"
|
||||
make fmt > /dev/null 2>&1
|
||||
echo "Checking if manifests are correct"
|
||||
make generate > /dev/null 2>&1
|
||||
|
||||
git diff --exit-code
|
||||
if [[ \$? == 1 ]]; then
|
||||
echo "
|
||||
|
||||
This commit is being rejected because the YAML manifests are incorrect or jsonnet needs to be formatted."
|
||||
echo "Please commit your changes again!"
|
||||
exit 1
|
||||
fi
|
||||
EOF
|
||||
chmod +x ${PWD}/.git/hooks/pre-commit
|
||||
vscode:
|
||||
extensions:
|
||||
- heptio.jsonnet@0.1.0:woEDU5N62LRdgdz0g/I6sQ==
|
||||
17
Makefile
17
Makefile
@@ -6,8 +6,10 @@ EMBEDMD_BIN=$(BIN_DIR)/embedmd
|
||||
JB_BIN=$(BIN_DIR)/jb
|
||||
GOJSONTOYAML_BIN=$(BIN_DIR)/gojsontoyaml
|
||||
JSONNET_BIN=$(BIN_DIR)/jsonnet
|
||||
JSONNETLINT_BIN=$(BIN_DIR)/jsonnet-lint
|
||||
JSONNETFMT_BIN=$(BIN_DIR)/jsonnetfmt
|
||||
TOOLING=$(EMBEDMD_BIN) $(JB_BIN) $(GOJSONTOYAML_BIN) $(JSONNET_BIN) $(JSONNETFMT_BIN)
|
||||
KUBECONFORM_BIN=$(BIN_DIR)/kubeconform
|
||||
TOOLING=$(EMBEDMD_BIN) $(JB_BIN) $(GOJSONTOYAML_BIN) $(JSONNET_BIN) $(JSONNETLINT_BIN) $(JSONNETFMT_BIN) $(KUBECONFORM_BIN)
|
||||
|
||||
JSONNETFMT_ARGS=-n 2 --max-blank-lines 2 --string-style s --comment-style s
|
||||
|
||||
@@ -31,11 +33,24 @@ vendor: $(JB_BIN) jsonnetfile.json jsonnetfile.lock.json
|
||||
rm -rf vendor
|
||||
$(JB_BIN) install
|
||||
|
||||
crdschemas: vendor
|
||||
./scripts/generate-schemas.sh
|
||||
|
||||
.PHONY: validate
|
||||
validate: crdschemas manifests $(KUBECONFORM_BIN)
|
||||
# Follow-up on https://github.com/instrumenta/kubernetes-json-schema/issues/26 if validations start failing
|
||||
$(KUBECONFORM_BIN) -schema-location 'https://kubernetesjsonschema.dev' -schema-location 'crdschemas/{{ .ResourceKind }}.json' -skip CustomResourceDefinition manifests/
|
||||
|
||||
.PHONY: fmt
|
||||
fmt: $(JSONNETFMT_BIN)
|
||||
find . -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
|
||||
xargs -n 1 -- $(JSONNETFMT_BIN) $(JSONNETFMT_ARGS) -i
|
||||
|
||||
.PHONY: lint
|
||||
lint: $(JSONNETLINT_BIN) vendor
|
||||
find jsonnet/ -name 'vendor' -prune -o -name '*.libsonnet' -print -o -name '*.jsonnet' -print | \
|
||||
xargs -n 1 -- $(JSONNETLINT_BIN) -J vendor
|
||||
|
||||
.PHONY: test
|
||||
test: $(JB_BIN)
|
||||
$(JB_BIN) install
|
||||
|
||||
15
OWNERS
15
OWNERS
@@ -1,15 +0,0 @@
|
||||
reviewers:
|
||||
- brancz
|
||||
- kakkoyun
|
||||
- metalmatze
|
||||
- mxinden
|
||||
- s-urbaniak
|
||||
- squat
|
||||
- paulfantom
|
||||
approvers:
|
||||
- brancz
|
||||
- metalmatze
|
||||
- mxinden
|
||||
- s-urbaniak
|
||||
- squat
|
||||
- paulfantom
|
||||
351
README.md
351
README.md
@@ -1,5 +1,9 @@
|
||||
# kube-prometheus
|
||||
|
||||
[](https://github.com/prometheus-operator/kube-prometheus/actions)
|
||||
[](http://slack.k8s.io/)
|
||||
[](https://gitpod.io/#https://github.com/prometheus-operator/kube-prometheus)
|
||||
|
||||
> Note that everything is experimental and may change significantly at any time.
|
||||
|
||||
This repository collects Kubernetes manifests, [Grafana](http://grafana.com/) dashboards, and [Prometheus rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) combined with documentation and scripts to provide easy to operate end-to-end Kubernetes cluster monitoring with [Prometheus](https://prometheus.io/) using the Prometheus Operator.
|
||||
@@ -18,9 +22,14 @@ Components included in this package:
|
||||
|
||||
This stack is meant for cluster monitoring, so it is pre-configured to collect metrics from all Kubernetes components. In addition to that it delivers a default set of dashboards and alerting rules. Many of the useful dashboards and alerts come from the [kubernetes-mixin project](https://github.com/kubernetes-monitoring/kubernetes-mixin), similar to this project it provides composable jsonnet as a library for users to customize to their needs.
|
||||
|
||||
## Warning
|
||||
|
||||
If you are migrating from `release-0.7` branch or earlier please read [what changed and how to migrate in our guide](https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/migration-guide.md).
|
||||
|
||||
## Table of contents
|
||||
|
||||
- [kube-prometheus](#kube-prometheus)
|
||||
- [Warning](#warning)
|
||||
- [Table of contents](#table-of-contents)
|
||||
- [Prerequisites](#prerequisites)
|
||||
- [minikube](#minikube)
|
||||
@@ -53,7 +62,9 @@ This stack is meant for cluster monitoring, so it is pre-configured to collect m
|
||||
- [Stripping container resource limits](#stripping-container-resource-limits)
|
||||
- [Customizing Prometheus alerting/recording rules and Grafana dashboards](#customizing-prometheus-alertingrecording-rules-and-grafana-dashboards)
|
||||
- [Exposing Prometheus/Alermanager/Grafana via Ingress](#exposing-prometheusalermanagergrafana-via-ingress)
|
||||
- [Setting up a blackbox exporter](#setting-up-a-blackbox-exporter)
|
||||
- [Minikube Example](#minikube-example)
|
||||
- [Continuous Delivery](#continuous-delivery)
|
||||
- [Troubleshooting](#troubleshooting)
|
||||
- [Error retrieving kubelet metrics](#error-retrieving-kubelet-metrics)
|
||||
- [Authentication problem](#authentication-problem)
|
||||
@@ -94,15 +105,13 @@ $ minikube addons disable metrics-server
|
||||
|
||||
The following versions are supported and work as we test against these versions in their respective branches. But note that other versions might work!
|
||||
|
||||
| kube-prometheus stack | Kubernetes 1.16 | Kubernetes 1.17 | Kubernetes 1.18 | Kubernetes 1.19 | Kubernetes 1.20 |
|
||||
|-----------------------|-----------------|-----------------|-----------------|-----------------|-----------------|
|
||||
| `release-0.4` | ✔ (v1.16.5+) | ✔ | ✗ | ✗ | ✗ |
|
||||
| `release-0.5` | ✗ | ✗ | ✔ | ✗ | ✗ |
|
||||
| `release-0.6` | ✗ | ✗ | ✔ | ✔ | ✗ |
|
||||
| `release-0.7` | ✗ | ✗ | ✗ | ✔ | ✔ |
|
||||
| `HEAD` | ✗ | ✗ | ✗ | ✔ | ✔ |
|
||||
|
||||
Note: Due to [two](https://github.com/kubernetes/kubernetes/issues/83778) [bugs](https://github.com/kubernetes/kubernetes/issues/86359) in Kubernetes v1.16.1, and prior to Kubernetes v1.16.5 the kube-prometheus release-0.4 branch only supports v1.16.5 and higher. The `extension-apiserver-authentication-reader` role in the kube-system namespace can be manually edited to include list and watch permissions in order to workaround the second issue with Kubernetes v1.16.2 through v1.16.4.
|
||||
| kube-prometheus stack | Kubernetes 1.18 | Kubernetes 1.19 | Kubernetes 1.20 | Kubernetes 1.21 |
|
||||
|-----------------------|-----------------|-----------------|-----------------|-----------------|
|
||||
| `release-0.5` | ✔ | ✗ | ✗ | ✗ |
|
||||
| `release-0.6` | ✗ | ✔ | ✗ | ✗ |
|
||||
| `release-0.7` | ✗ | ✔ | ✔ | ✗ |
|
||||
| `release-0.8` | ✗ | ✗ | ✔ | ✔ |
|
||||
| `HEAD` | ✗ | ✗ | ✔ | ✔ |
|
||||
|
||||
## Quickstart
|
||||
|
||||
@@ -114,7 +123,7 @@ Though for a quickstart a compiled version of the Kubernetes [manifests](manifes
|
||||
* Create the monitoring stack using the config in the `manifests` directory:
|
||||
|
||||
```shell
|
||||
# Create the namespace and CRDs, and then wait for them to be availble before creating the remaining resources
|
||||
# Create the namespace and CRDs, and then wait for them to be available before creating the remaining resources
|
||||
kubectl create -f manifests/setup
|
||||
until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done
|
||||
kubectl create -f manifests/
|
||||
@@ -175,12 +184,15 @@ Install this library in your own project with [jsonnet-bundler](https://github.c
|
||||
$ mkdir my-kube-prometheus; cd my-kube-prometheus
|
||||
$ jb init # Creates the initial/empty `jsonnetfile.json`
|
||||
# Install the kube-prometheus dependency
|
||||
$ jb install github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus@release-0.4 # Creates `vendor/` & `jsonnetfile.lock.json`, and fills in `jsonnetfile.json`
|
||||
$ jb install github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus@release-0.7 # Creates `vendor/` & `jsonnetfile.lock.json`, and fills in `jsonnetfile.json`
|
||||
|
||||
$ wget https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/release-0.7/example.jsonnet -O example.jsonnet
|
||||
$ wget https://raw.githubusercontent.com/prometheus-operator/kube-prometheus/release-0.7/build.sh -O build.sh
|
||||
```
|
||||
|
||||
> `jb` can be installed with `go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb`
|
||||
|
||||
> An e.g. of how to install a given version of this library: `jb install github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus@release-0.4`
|
||||
> An e.g. of how to install a given version of this library: `jb install github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus@release-0.7`
|
||||
|
||||
In order to update the kube-prometheus dependency, simply use the jsonnet-bundler update functionality:
|
||||
```shell
|
||||
@@ -191,7 +203,7 @@ $ jb update
|
||||
|
||||
e.g. of how to compile the manifests: `./build.sh example.jsonnet`
|
||||
|
||||
> before compiling, install `gojsontoyaml` tool with `go get github.com/brancz/gojsontoyaml`
|
||||
> before compiling, install `gojsontoyaml` tool with `go get github.com/brancz/gojsontoyaml` and `jsonnet` with `go get github.com/google/go-jsonnet/cmd/jsonnet`
|
||||
|
||||
Here's [example.jsonnet](example.jsonnet):
|
||||
|
||||
@@ -200,34 +212,39 @@ Here's [example.jsonnet](example.jsonnet):
|
||||
[embedmd]:# (example.jsonnet)
|
||||
```jsonnet
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
// Uncomment the following imports to enable its patches
|
||||
// (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-external-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/external-metrics.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
|
||||
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor is separated so that it can be created after the CRDs are ready
|
||||
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
|
||||
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
|
||||
```
|
||||
|
||||
And here's the [build.sh](build.sh) script (which uses `vendor/` to render all manifests in a json structure of `{filename: manifest-content}`):
|
||||
@@ -268,7 +285,7 @@ The previous steps (compilation) has created a bunch of manifest files in the ma
|
||||
Now simply use `kubectl` to install Prometheus and Grafana as per your configuration:
|
||||
|
||||
```shell
|
||||
# Update the namespace and CRDs, and then wait for them to be availble before creating the remaining resources
|
||||
# Update the namespace and CRDs, and then wait for them to be available before creating the remaining resources
|
||||
$ kubectl apply -f manifests/setup
|
||||
$ kubectl apply -f manifests/
|
||||
```
|
||||
@@ -310,74 +327,22 @@ Once updated, just follow the instructions under "Compiling" and "Apply the kube
|
||||
|
||||
Jsonnet has the concept of hidden fields. These are fields, that are not going to be rendered in a result. This is used to configure the kube-prometheus components in jsonnet. In the example jsonnet code of the above [Customizing Kube-Prometheus section](#customizing-kube-prometheus), you can see an example of this, where the `namespace` is being configured to be `monitoring`. In order to not override the whole object, use the `+::` construct of jsonnet, to merge objects, this way you can override individual settings, but retain all other settings and defaults.
|
||||
|
||||
These are the available fields with their respective default values:
|
||||
The available fields and their default values can be seen in [main.libsonnet](jsonnet/kube-prometheus/main.libsonnet). Note that many of the fields get their default values from variables, and for example the version numbers are imported from [versions.json](jsonnet/kube-prometheus/versions.json).
|
||||
|
||||
Configuration is mainly done in the `values` map. You can see this being used in the `example.jsonnet` to set the namespace to `monitoring`. This is done in the `common` field, which all other components take their default value from. See for example how Alertmanager is configured in `main.libsonnet`:
|
||||
|
||||
```
|
||||
{
|
||||
_config+:: {
|
||||
namespace: "default",
|
||||
|
||||
versions+:: {
|
||||
alertmanager: "v0.17.0",
|
||||
nodeExporter: "v0.18.1",
|
||||
kubeStateMetrics: "v1.5.0",
|
||||
kubeRbacProxy: "v0.4.1",
|
||||
prometheusOperator: "v0.30.0",
|
||||
prometheus: "v2.10.0",
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
prometheus: "quay.io/prometheus/prometheus",
|
||||
alertmanager: "quay.io/prometheus/alertmanager",
|
||||
kubeStateMetrics: "quay.io/coreos/kube-state-metrics",
|
||||
kubeRbacProxy: "quay.io/brancz/kube-rbac-proxy",
|
||||
nodeExporter: "quay.io/prometheus/node-exporter",
|
||||
prometheusOperator: "quay.io/prometheus-operator/prometheus-operator",
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
names: 'k8s',
|
||||
replicas: 2,
|
||||
rules: {},
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
alertmanager: {
|
||||
name: 'main',
|
||||
config: |||
|
||||
global:
|
||||
resolve_timeout: 5m
|
||||
route:
|
||||
group_by: ['job']
|
||||
group_wait: 30s
|
||||
group_interval: 5m
|
||||
repeat_interval: 12h
|
||||
receiver: 'null'
|
||||
routes:
|
||||
- match:
|
||||
alertname: Watchdog
|
||||
receiver: 'null'
|
||||
receivers:
|
||||
- name: 'null'
|
||||
|||,
|
||||
replicas: 3,
|
||||
// Use the namespace specified under values.common by default.
|
||||
namespace: $.values.common.namespace,
|
||||
version: $.values.common.versions.alertmanager,
|
||||
image: $.values.common.images.alertmanager,
|
||||
mixin+: { ruleLabels: $.values.common.ruleLabels },
|
||||
},
|
||||
|
||||
kubeStateMetrics+:: {
|
||||
collectors: '', // empty string gets a default set
|
||||
scrapeInterval: '30s',
|
||||
scrapeTimeout: '30s',
|
||||
|
||||
baseCPU: '100m',
|
||||
baseMemory: '150Mi',
|
||||
},
|
||||
|
||||
nodeExporter+:: {
|
||||
port: 9100,
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The grafana definition is located in a different project (https://github.com/brancz/kubernetes-grafana), but needed configuration can be customized from the same top level `_config` field. For example to allow anonymous access to grafana, add the following `_config` section:
|
||||
The grafana definition is located in a different project (https://github.com/brancz/kubernetes-grafana), but needed configuration can be customized from the same top level `values` field. For example to allow anonymous access to grafana, add the following `values` section:
|
||||
```
|
||||
grafana+:: {
|
||||
config: { // http://docs.grafana.org/installation/configuration/
|
||||
@@ -394,57 +359,28 @@ Jsonnet is a turing complete language, any logic can be reflected in it. It also
|
||||
|
||||
### Cluster Creation Tools
|
||||
|
||||
A common example is that not all Kubernetes clusters are created exactly the same way, meaning the configuration to monitor them may be slightly different. For [kubeadm](examples/jsonnet-snippets/kubeadm.jsonnet), [bootkube](examples/jsonnet-snippets/bootkube.jsonnet), [kops](examples/jsonnet-snippets/kops.jsonnet) and [kubespray](examples/jsonnet-snippets/kubespray.jsonnet) clusters there are mixins available to easily configure these:
|
||||
A common example is that not all Kubernetes clusters are created exactly the same way, meaning the configuration to monitor them may be slightly different. For the following clusters there are mixins available to easily configure them:
|
||||
|
||||
kubeadm:
|
||||
* aws
|
||||
* bootkube
|
||||
* eks
|
||||
* gke
|
||||
* kops-coredns
|
||||
* kubeadm
|
||||
* kubespray
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/kubeadm.jsonnet)
|
||||
These mixins are selectable via the `platform` field of kubePrometheus:
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/platform.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet')
|
||||
```
|
||||
|
||||
bootkube:
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/bootkube.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-bootkube.libsonnet')
|
||||
```
|
||||
|
||||
kops:
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/kops.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kops.libsonnet')
|
||||
```
|
||||
|
||||
kops with CoreDNS:
|
||||
|
||||
If your kops cluster is using CoreDNS, there is an additional mixin to import.
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/kops-coredns.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kops.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kops-coredns.libsonnet')
|
||||
```
|
||||
|
||||
kubespray:
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/kubespray.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kubespray.libsonnet')
|
||||
```
|
||||
|
||||
kube-aws:
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/kube-aws.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kube-aws.libsonnet')
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
{
|
||||
values+:: {
|
||||
kubePrometheus+: {
|
||||
platform: 'example-platform',
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Internal Registry
|
||||
@@ -470,10 +406,12 @@ Then to generate manifests with `internal-registry.com/organization`, use the `w
|
||||
|
||||
[embedmd]:# (examples/internal-registry.jsonnet)
|
||||
```jsonnet
|
||||
local mixin = import 'kube-prometheus/kube-prometheus-config-mixins.libsonnet';
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local mixin = import 'kube-prometheus/addons/config-mixins.libsonnet';
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
} + mixin.withImageRepository('internal-registry.com/organization');
|
||||
|
||||
@@ -492,8 +430,8 @@ Another mixin that may be useful for exploring the stack is to expose the UIs of
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/node-ports.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet')
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/node-ports.libsonnet')
|
||||
```
|
||||
|
||||
### Prometheus Object Name
|
||||
@@ -502,7 +440,7 @@ To give another customization example, the name of the `Prometheus` object provi
|
||||
|
||||
[embedmd]:# (examples/prometheus-name-override.jsonnet)
|
||||
```jsonnet
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
prometheus+: {
|
||||
prometheus+: {
|
||||
metadata+: {
|
||||
@@ -519,7 +457,7 @@ Standard Kubernetes manifests are all written using [ksonnet-lib](https://github
|
||||
|
||||
[embedmd]:# (examples/ksonnet-example.jsonnet)
|
||||
```jsonnet
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
nodeExporter+: {
|
||||
daemonset+: {
|
||||
metadata+: {
|
||||
@@ -532,12 +470,12 @@ Standard Kubernetes manifests are all written using [ksonnet-lib](https://github
|
||||
|
||||
### Alertmanager configuration
|
||||
|
||||
The Alertmanager configuration is located in the `_config.alertmanager.config` configuration field. In order to set a custom Alertmanager configuration simply set this field.
|
||||
The Alertmanager configuration is located in the `values.alertmanager.config` configuration field. In order to set a custom Alertmanager configuration simply set this field.
|
||||
|
||||
[embedmd]:# (examples/alertmanager-config.jsonnet)
|
||||
```jsonnet
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
alertmanager+: {
|
||||
config: |||
|
||||
global:
|
||||
@@ -564,8 +502,8 @@ In the above example the configuration has been inlined, but can just as well be
|
||||
|
||||
[embedmd]:# (examples/alertmanager-config-external.jsonnet)
|
||||
```jsonnet
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
alertmanager+: {
|
||||
config: importstr 'alertmanager-config.yaml',
|
||||
},
|
||||
@@ -575,15 +513,17 @@ In the above example the configuration has been inlined, but can just as well be
|
||||
|
||||
### Adding additional namespaces to monitor
|
||||
|
||||
In order to monitor additional namespaces, the Prometheus server requires the appropriate `Role` and `RoleBinding` to be able to discover targets from that namespace. By default the Prometheus server is limited to the three namespaces it requires: default, kube-system and the namespace you configure the stack to run in via `$._config.namespace`. This is specified in `$._config.prometheus.namespaces`, to add new namespaces to monitor, simply append the additional namespaces:
|
||||
In order to monitor additional namespaces, the Prometheus server requires the appropriate `Role` and `RoleBinding` to be able to discover targets from that namespace. By default the Prometheus server is limited to the three namespaces it requires: default, kube-system and the namespace you configure the stack to run in via `$.values.namespace`. This is specified in `$.values.prometheus.namespaces`, to add new namespaces to monitor, simply append the additional namespaces:
|
||||
|
||||
[embedmd]:# (examples/additional-namespaces.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
prometheus+: {
|
||||
namespaces+: ['my-namespace', 'my-second-namespace'],
|
||||
},
|
||||
},
|
||||
@@ -608,14 +548,16 @@ You can define ServiceMonitor resources in your `jsonnet` spec. See the snippet
|
||||
|
||||
[embedmd]:# (examples/additional-namespaces-servicemonitor.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
prometheus+:: {
|
||||
namespaces+: ['my-namespace', 'my-second-namespace'],
|
||||
},
|
||||
},
|
||||
prometheus+:: {
|
||||
exampleApplication: {
|
||||
serviceMonitorMyNamespace: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
@@ -647,7 +589,8 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
```
|
||||
|
||||
> NOTE: make sure your service resources have the right labels (eg. `'app': 'myapp'`) applied. Prometheus uses kubernetes labels to discover resources inside the namespaces.
|
||||
@@ -658,12 +601,13 @@ In case you want to monitor all namespaces in a cluster, you can add the followi
|
||||
|
||||
[embedmd]:# (examples/all-namespaces.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-all-namespaces.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
|
||||
prometheus+:: {
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/all-namespaces.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
prometheus+: {
|
||||
namespaces: [],
|
||||
},
|
||||
},
|
||||
@@ -691,11 +635,26 @@ In order to configure a static etcd cluster to scrape there is a simple [kube-pr
|
||||
### Pod Anti-Affinity
|
||||
|
||||
To prevent `Prometheus` and `Alertmanager` instances from being deployed onto the same node when
|
||||
possible, one can include the [kube-prometheus-anti-affinity.libsonnet](jsonnet/kube-prometheus/kube-prometheus-anti-affinity.libsonnet) mixin:
|
||||
possible, one can include the [kube-prometheus-anti-affinity.libsonnet](jsonnet/kube-prometheus/addons/anti-affinity.libsonnet) mixin:
|
||||
|
||||
[embedmd]:# (examples/anti-affinity.jsonnet)
|
||||
```jsonnet
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet')
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/anti-affinity.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['00namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{ ['0prometheus-operator-' + name]: kp.prometheusOperator[name] for name in std.objectFields(kp.prometheusOperator) } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
```
|
||||
|
||||
### Stripping container resource limits
|
||||
@@ -705,10 +664,12 @@ To do that, one can import the following mixin
|
||||
|
||||
[embedmd]:# (examples/strip-limits.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-strip-limits.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/strip-limits.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -729,6 +690,36 @@ See [developing Prometheus rules and Grafana dashboards](docs/developing-prometh
|
||||
|
||||
See [exposing Prometheus/Alertmanager/Grafana](docs/exposing-prometheus-alertmanager-grafana-ingress.md) guide.
|
||||
|
||||
### Setting up a blackbox exporter
|
||||
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
// ... all necessary mixins ...
|
||||
{
|
||||
values+:: {
|
||||
// ... configuration for other features ...
|
||||
blackboxExporter+:: {
|
||||
modules+:: {
|
||||
tls_connect: {
|
||||
prober: 'tcp',
|
||||
tcp: {
|
||||
tls: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
// ... other rendering blocks ...
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) }
|
||||
```
|
||||
|
||||
Then describe the actual blackbox checks you want to run using `Probe` resources. Specify `blackbox-exporter.<namespace>.svc.cluster.local:9115` as the `spec.prober.url` field of the `Probe` resource.
|
||||
|
||||
See the [blackbox exporter guide](docs/blackbox-exporter.md) for the list of configurable options and a complete example.
|
||||
|
||||
## Minikube Example
|
||||
|
||||
To use an easy to reproduce example, see [minikube.jsonnet](examples/minikube.jsonnet), which uses the minikube setup as demonstrated in [Prerequisites](#prerequisites). Because we would like easy access to our Prometheus, Alertmanager and Grafana UIs, `minikube.jsonnet` exposes the services as NodePort type services.
|
||||
@@ -766,7 +757,7 @@ resources. One driver for more resource needs, is a high number of
|
||||
namespaces. There may be others.
|
||||
|
||||
kube-state-metrics resource allocation is managed by
|
||||
[addon-resizer](https://github.com/kubernetes/autoscaler/tree/master/addon-resizer/nanny)
|
||||
[addon-resizer](https://github.com/kubernetes/autoscaler/tree/main/addon-resizer/nanny)
|
||||
You can control it's parameters by setting variables in the
|
||||
config. They default to:
|
||||
|
||||
@@ -794,4 +785,4 @@ the following process:
|
||||
|
||||
## License
|
||||
|
||||
Apache License 2.0, see [LICENSE](https://github.com/prometheus-operator/kube-prometheus/blob/master/LICENSE).
|
||||
Apache License 2.0, see [LICENSE](https://github.com/prometheus-operator/kube-prometheus/blob/main/LICENSE).
|
||||
|
||||
@@ -7,23 +7,31 @@ One fatal issue that can occur is that you run out of IP addresses in your eks c
|
||||
You can monitor the `awscni` using kube-promethus with :
|
||||
[embedmd]:# (../examples/eks-cni-example.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-eks.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
kubePrometheus+: {
|
||||
platform: 'eks',
|
||||
},
|
||||
},
|
||||
prometheusRules+:: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
kubernetesControlPlane+: {
|
||||
prometheusRuleEksCNI+: {
|
||||
spec+: {
|
||||
groups+: [
|
||||
{
|
||||
record: 'aws_eks_available_ip',
|
||||
expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
{
|
||||
record: 'aws_eks_available_ip',
|
||||
expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
97
docs/blackbox-exporter.md
Normal file
97
docs/blackbox-exporter.md
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "Blackbox Exporter"
|
||||
description: "Generated API docs for the Prometheus Operator"
|
||||
lead: "This Document documents the types introduced by the Prometheus Operator to be consumed by users."
|
||||
date: 2021-03-08T08:49:31+00:00
|
||||
lastmod: 2021-03-08T08:49:31+00:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 630
|
||||
toc: true
|
||||
---
|
||||
|
||||
# Setting up a blackbox exporter
|
||||
|
||||
The `prometheus-operator` defines a `Probe` resource type that can be used to describe blackbox checks. To execute these, a separate component called [`blackbox_exporter`](https://github.com/prometheus/blackbox_exporter) has to be deployed, which can be scraped to retrieve the results of these checks. You can use `kube-prometheus` to set up such a blackbox exporter within your Kubernetes cluster.
|
||||
|
||||
## Adding blackbox exporter manifests to an existing `kube-prometheus` configuration
|
||||
|
||||
1. Override blackbox-related configuration parameters as needed.
|
||||
2. Add the following to the list of renderers to render the blackbox exporter manifests:
|
||||
```
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) }
|
||||
```
|
||||
|
||||
## Configuration parameters influencing the blackbox exporter
|
||||
|
||||
* `_config.namespace`: the namespace where the various generated resources (`ConfigMap`, `Deployment`, `Service`, `ServiceAccount` and `ServiceMonitor`) will reside. This does not affect where you can place `Probe` objects; that is determined by the configuration of the `Prometheus` resource. This option is shared with other `kube-prometheus` components; defaults to `default`.
|
||||
* `_config.imageRepos.blackboxExporter`: the name of the blackbox exporter image to deploy. Defaults to `quay.io/prometheus/blackbox-exporter`.
|
||||
* `_config.versions.blackboxExporter`: the tag of the blackbox exporter image to deploy. Defaults to the version `kube-prometheus` was tested with.
|
||||
* `_config.imageRepos.configmapReloader`: the name of the ConfigMap reloader image to deploy. Defaults to `jimmidyson/configmap-reload`.
|
||||
* `_config.versions.configmapReloader`: the tag of the ConfigMap reloader image to deploy. Defaults to the version `kube-prometheus` was tested with.
|
||||
* `_config.resources.blackbox-exporter.requests`: the requested resources; this is used for each container. Defaults to `10m` CPU and `20Mi` RAM. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ for details.
|
||||
* `_config.resources.blackbox-exporter.limits`: the resource limits; this is used for each container. Defaults to `20m` CPU and `40Mi` RAM. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ for details.
|
||||
* `_config.blackboxExporter.port`: the exposed HTTPS port of the exporter. This is what Prometheus can scrape for metrics related to the blackbox exporter itself. Defaults to `9115`.
|
||||
* `_config.blackboxExporter.internalPort`: the internal plaintext port of the exporter. Prometheus scrapes configured via `Probe` objects cannot access the HTTPS port right now, so you have to specify this port in the `url` field. Defaults to `19115`.
|
||||
* `_config.blackboxExporter.replicas`: the number of exporter replicas to be deployed. Defaults to `1`.
|
||||
* `_config.blackboxExporter.matchLabels`: map of the labels to be used to select resources belonging to the instance deployed. Defaults to `{ 'app.kubernetes.io/name': 'blackbox-exporter' }`
|
||||
* `_config.blackboxExporter.assignLabels`: map of the labels applied to components of the instance deployed. Defaults to all the labels included in the `matchLabels` option, and additionally `app.kubernetes.io/version` is set to the version of the blackbox exporter.
|
||||
* `_config.blackboxExporter.modules`: the modules available in the blackbox exporter installation, i.e. the types of checks it can perform. The default value includes most of the modules defined in the default blackbox exporter configuration: `http_2xx`, `http_post_2xx`, `tcp_connect`, `pop3s_banner`, `ssh_banner`, and `irc_banner`. `icmp` is omitted so the exporter can be run with minimum privileges, but you can add it back if needed - see the example below. See https://github.com/prometheus/blackbox_exporter/blob/master/CONFIGURATION.md for the configuration format, except you have to use JSON instead of YAML here.
|
||||
* `_config.blackboxExporter.privileged`: whether the `blackbox-exporter` container should be running as non-root (`false`) or root with heavily-restricted capability set (`true`). Defaults to `true` if you have any ICMP modules defined (which need the extra permissions) and `false` otherwise.
|
||||
|
||||
## Complete example
|
||||
|
||||
```jsonnet
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
blackboxExporter+:: {
|
||||
modules+:: {
|
||||
icmp: {
|
||||
prober: 'icmp',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor is separated so that it can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
```
|
||||
|
||||
After installing the generated manifests, you can create `Probe` resources, for example:
|
||||
|
||||
```yaml
|
||||
kind: Probe
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
metadata:
|
||||
name: example-com-website
|
||||
namespace: monitoring
|
||||
spec:
|
||||
interval: 60s
|
||||
module: http_2xx
|
||||
prober:
|
||||
url: blackbox-exporter.monitoring.svc.cluster.local:19115
|
||||
targets:
|
||||
staticConfig:
|
||||
static:
|
||||
- http://example.com
|
||||
- https://example.com
|
||||
```
|
||||
19
docs/deploy-kind.md
Normal file
19
docs/deploy-kind.md
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
title: "Deploy to kind"
|
||||
description: "Deploy kube-prometheus to Kubernets kind."
|
||||
lead: "Deploy kube-prometheus to Kubernets kind."
|
||||
date: 2021-03-08T23:04:32+01:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 500
|
||||
toc: true
|
||||
---
|
||||
|
||||
---
|
||||
|
||||
Time to explain how!
|
||||
|
||||
Your chance of [**contributing**](https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/deploy-kind.md)!
|
||||
@@ -1,4 +1,16 @@
|
||||
# Developing Prometheus Rules and Grafana Dashboards
|
||||
---
|
||||
title: "Prometheus Rules and Grafana Dashboards"
|
||||
description: "Create Prometheus Rules and Grafana Dashboards on top of kube-prometheus"
|
||||
lead: "Create Prometheus Rules and Grafana Dashboards on top of kube-prometheus"
|
||||
date: 2021-03-08T23:04:32+01:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 650
|
||||
toc: true
|
||||
---
|
||||
|
||||
`kube-prometheus` ships with a set of default [Prometheus rules](https://prometheus.io/docs/prometheus/latest/configuration/recording_rules/) and [Grafana](http://grafana.com/) dashboards. At some point one might like to extend them, the purpose of this document is to explain how to do this.
|
||||
|
||||
@@ -11,34 +23,39 @@ As a basis, all examples in this guide are based on the base example of the kube
|
||||
[embedmd]:# (../example.jsonnet)
|
||||
```jsonnet
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
// Uncomment the following imports to enable its patches
|
||||
// (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-external-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/external-metrics.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
|
||||
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor is separated so that it can be created after the CRDs are ready
|
||||
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
|
||||
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
|
||||
```
|
||||
|
||||
## Prometheus rules
|
||||
@@ -53,28 +70,40 @@ The format is exactly the Prometheus format, so there should be no changes neces
|
||||
|
||||
[embedmd]:# (../examples/prometheus-additional-alert-rule-example.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusAlerts+:: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
exampleApplication: {
|
||||
prometheusRuleExample: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
name: 'my-prometheus-rule',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: [
|
||||
{
|
||||
alert: 'Watchdog',
|
||||
expr: 'vector(1)',
|
||||
labels: {
|
||||
severity: 'none',
|
||||
},
|
||||
annotations: {
|
||||
description: 'This is a Watchdog meant to ensure that the entire alerting pipeline is functional.',
|
||||
},
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
{
|
||||
alert: 'ExampleAlert',
|
||||
expr: 'vector(1)',
|
||||
labels: {
|
||||
severity: 'warning',
|
||||
},
|
||||
annotations: {
|
||||
description: 'This is an example alert.',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -85,7 +114,8 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
```
|
||||
|
||||
### Recording rules
|
||||
@@ -96,22 +126,34 @@ In order to add a recording rule, simply do the same with the `prometheusRules`
|
||||
|
||||
[embedmd]:# (../examples/prometheus-additional-recording-rule-example.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusRules+:: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
exampleApplication: {
|
||||
prometheusRuleExample: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
name: 'my-prometheus-rule',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: [
|
||||
{
|
||||
record: 'some_recording_rule_name',
|
||||
expr: 'vector(1)',
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
{
|
||||
record: 'some_recording_rule_name',
|
||||
expr: 'vector(1)',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -122,7 +164,8 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
```
|
||||
|
||||
### Pre-rendered rules
|
||||
@@ -143,12 +186,24 @@ Then import it in jsonnet:
|
||||
|
||||
[embedmd]:# (../examples/prometheus-additional-rendered-rule-example.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusAlerts+:: {
|
||||
groups+: (import 'existingrule.json').groups,
|
||||
exampleApplication: {
|
||||
prometheusRuleExample: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
name: 'my-prometheus-rule',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: (import 'existingrule.json').groups,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -159,7 +214,8 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
```
|
||||
### Changing default rules
|
||||
|
||||
@@ -249,35 +305,37 @@ local prometheus = grafana.prometheus;
|
||||
local template = grafana.template;
|
||||
local graphPanel = grafana.graphPanel;
|
||||
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+:: {
|
||||
dashboards+:: {
|
||||
'my-dashboard.json':
|
||||
dashboard.new('My Dashboard')
|
||||
.addTemplate(
|
||||
{
|
||||
current: {
|
||||
text: 'Prometheus',
|
||||
value: 'Prometheus',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+: {
|
||||
dashboards+:: {
|
||||
'my-dashboard.json':
|
||||
dashboard.new('My Dashboard')
|
||||
.addTemplate(
|
||||
{
|
||||
current: {
|
||||
text: 'Prometheus',
|
||||
value: 'Prometheus',
|
||||
},
|
||||
hide: 0,
|
||||
label: null,
|
||||
name: 'datasource',
|
||||
options: [],
|
||||
query: 'prometheus',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'datasource',
|
||||
},
|
||||
hide: 0,
|
||||
label: null,
|
||||
name: 'datasource',
|
||||
options: [],
|
||||
query: 'prometheus',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'datasource',
|
||||
},
|
||||
)
|
||||
.addRow(
|
||||
row.new()
|
||||
.addPanel(graphPanel.new('My Panel', span=6, datasource='$datasource')
|
||||
.addTarget(prometheus.target('vector(1)')))
|
||||
),
|
||||
)
|
||||
.addRow(
|
||||
row.new()
|
||||
.addPanel(graphPanel.new('My Panel', span=6, datasource='$datasource')
|
||||
.addTarget(prometheus.target('vector(1)')))
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -297,16 +355,15 @@ As jsonnet is a superset of json, the jsonnet `import` function can be used to i
|
||||
|
||||
[embedmd]:# (../examples/grafana-additional-rendered-dashboard-example.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafanaDashboards+:: { // monitoring-mixin compatibility
|
||||
'my-dashboard.json': (import 'example-grafana-dashboard.json'),
|
||||
},
|
||||
grafana+:: {
|
||||
dashboards+:: { // use this method to import your dashboards to Grafana
|
||||
'my-dashboard.json': (import 'example-grafana-dashboard.json'),
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+: {
|
||||
dashboards+:: { // use this method to import your dashboards to Grafana
|
||||
'my-dashboard.json': (import 'example-grafana-dashboard.json'),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -323,13 +380,15 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
In case you have lots of json dashboard exported out from grafana UI the above approach is going to take lots of time to improve performance we can use `rawDashboards` field and provide it's value as json string by using `importstr`
|
||||
[embedmd]:# (../examples/grafana-additional-rendered-dashboard-example-2.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+:: {
|
||||
rawDashboards+:: {
|
||||
'my-dashboard.json': (importstr 'example-grafana-dashboard.json'),
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+: {
|
||||
rawDashboards+:: {
|
||||
'my-dashboard.json': (importstr 'example-grafana-dashboard.json'),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -342,3 +401,81 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
```
|
||||
|
||||
### Mixins
|
||||
|
||||
Kube-prometheus comes with a couple of default mixins as the Kubernetes-mixin and the Node-exporter mixin, however there [are many more mixins](https://monitoring.mixins.dev/). To use other mixins Kube-prometheus has a jsonnet library for creating a Kubernetes PrometheusRule CRD and Grafana dashboards from a mixin. Below is an example of creating a mixin object that has Prometheus rules and Grafana dashboards:
|
||||
|
||||
```jsonnet
|
||||
// Import the library function for adding mixins
|
||||
local addMixin = (import 'kube-prometheus/lib/mixin.libsonnet');
|
||||
|
||||
// Create your mixin
|
||||
local myMixin = addMixin({
|
||||
name: 'myMixin',
|
||||
mixin: import 'my-mixin/mixin.libsonnet',
|
||||
});
|
||||
```
|
||||
|
||||
The myMixin object will have two objects - `prometheusRules` and `grafanaDashboards`. The `grafanaDashboards` object will be needed to be added to the `dashboards` field as in the example below:
|
||||
|
||||
```jsonnet
|
||||
values+:: {
|
||||
grafana+:: {
|
||||
dashboards+:: myMixin.grafanaDashboards
|
||||
```
|
||||
|
||||
The `prometheusRules` object is a PrometheusRule Kubernetes CRD and it should be defined as its own jsonnet object. If you define multiple mixins in a single jsonnet object there is a possibility that they will overwrite each others' configuration and there will be unintended effects. Therefore, use the `prometheusRules` object as its own jsonnet object:
|
||||
|
||||
```jsonnet
|
||||
...
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ 'external-mixins/my-mixin-prometheus-rules': myMixin.prometheusRules } // one object for each mixin
|
||||
```
|
||||
|
||||
As mentioned above each mixin is configurable and you would configure the mixin as in the example below:
|
||||
|
||||
```jsonnet
|
||||
local myMixin = addMixin({
|
||||
name: 'myMixin',
|
||||
mixin: (import 'my-mixin/mixin.libsonnet') + {
|
||||
_config+:: {
|
||||
myMixinSelector: 'my-selector',
|
||||
interval: '30d', // example
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The library has also two optional parameters - the namespace for the `PrometheusRule` CRD and the dashboard folder for the Grafana dashboards. The below example shows how to use both:
|
||||
|
||||
```jsonnet
|
||||
local myMixin = addMixin({
|
||||
name: 'myMixin',
|
||||
namespace: 'prometheus', // default is monitoring
|
||||
dashboardFolder: 'Observability',
|
||||
mixin: (import 'my-mixin/mixin.libsonnet') + {
|
||||
_config+:: {
|
||||
myMixinSelector: 'my-selector',
|
||||
interval: '30d', // example
|
||||
},
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
The created `prometheusRules` object will have the metadata field `namespace` added and the usage will remain the same. However, the `grafanaDasboards` will be added to the `folderDashboards` field instead of the `dashboards` field as shown in the example below:
|
||||
|
||||
```jsonnet
|
||||
values+:: {
|
||||
grafana+:: {
|
||||
folderDashboards+:: {
|
||||
Kubernetes: {
|
||||
...
|
||||
},
|
||||
Misc: {
|
||||
'grafana-home.json': import 'dashboards/misc/grafana-home.json',
|
||||
},
|
||||
} + myMixin.grafanaDashboards
|
||||
```
|
||||
|
||||
@@ -1,12 +1,24 @@
|
||||
# Exposing Prometheus, Alertmanager and Grafana UIs via Ingress
|
||||
---
|
||||
title: "Expose via Ingress"
|
||||
description: "How to setup a Kubernetes Ingress to expose the Prometheus, Alertmanager and Grafana."
|
||||
lead: "How to setup a Kubernetes Ingress to expose the Prometheus, Alertmanager and Grafana."
|
||||
date: 2021-03-08T23:04:32+01:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 500
|
||||
toc: true
|
||||
---
|
||||
|
||||
In order to access the web interfaces via the Internet [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) is a popular option. This guide explains, how Kubernetes Ingress can be setup, in order to expose the Prometheus, Alertmanager and Grafana UIs, that are included in the [kube-prometheus](https://github.com/coreos/kube-prometheus) project.
|
||||
In order to access the web interfaces via the Internet [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/) is a popular option. This guide explains, how Kubernetes Ingress can be setup, in order to expose the Prometheus, Alertmanager and Grafana UIs, that are included in the [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) project.
|
||||
|
||||
Note: before continuing, it is recommended to first get familiar with the [kube-prometheus](https://github.com/coreos/kube-prometheus) stack by itself.
|
||||
Note: before continuing, it is recommended to first get familiar with the [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) stack by itself.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Apart from a running Kubernetes cluster with a running [kube-prometheus](https://github.com/coreos/kube-prometheus) stack, a Kubernetes Ingress controller must be installed and functional. This guide was tested with the [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx). If you wish to reproduce the exact result in as depicted in this guide we recommend using the nginx-ingress-controller.
|
||||
Apart from a running Kubernetes cluster with a running [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus) stack, a Kubernetes Ingress controller must be installed and functional. This guide was tested with the [nginx-ingress-controller](https://github.com/kubernetes/ingress-nginx). If you wish to reproduce the exact result in as depicted in this guide we recommend using the nginx-ingress-controller.
|
||||
|
||||
## Setting up Ingress
|
||||
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
<br>
|
||||
<div class="alert alert-info" role="alert">
|
||||
<i class="fa fa-exclamation-triangle"></i><b> Note:</b> Starting with v0.12.0, Prometheus Operator requires use of Kubernetes v1.7.x and up.
|
||||
</div>
|
||||
---
|
||||
title: "Deploy to kubeadm"
|
||||
description: "Deploy kube-prometheus to Kubernets kubeadm."
|
||||
lead: "Deploy kube-prometheus to Kubernets kubeadm."
|
||||
date: 2021-03-08T23:04:32+01:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 500
|
||||
toc: true
|
||||
---
|
||||
|
||||
# Kube Prometheus on Kubeadm
|
||||
|
||||
The [kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/) tool is linked by Kubernetes as the offical way to deploy and manage self-hosted clusters. Kubeadm does a lot of heavy lifting by automatically configuring your Kubernetes cluster with some common options. This guide is intended to show you how to deploy Prometheus, Prometheus Operator and Kube Prometheus to get you started monitoring your cluster that was deployed with Kubeadm.
|
||||
The [kubeadm](https://kubernetes.io/docs/setup/independent/create-cluster-kubeadm/) tool is linked by Kubernetes as the offical way to deploy and manage self-hosted clusters. kubeadm does a lot of heavy lifting by automatically configuring your Kubernetes cluster with some common options. This guide is intended to show you how to deploy Prometheus, Prometheus Operator and Kube Prometheus to get you started monitoring your cluster that was deployed with kubeadm.
|
||||
|
||||
This guide assumes you have a basic understanding of how to use the functionality the Prometheus Operator implements. If you haven't yet, we recommend reading through the [getting started guide](https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/getting-started.md) as well as the [alerting guide](https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/alerting.md).
|
||||
|
||||
## Kubeadm Pre-requisites
|
||||
## kubeadm Pre-requisites
|
||||
|
||||
This guide assumes you have some familiarity with `kubeadm` or at least have deployed a cluster using `kubeadm`. By default, `kubeadm` does not expose two of the services that we will be monitoring. Therefore, in order to get the most out of the `kube-prometheus` package, we need to make some quick tweaks to the Kubernetes cluster. Since we will be monitoring the `kube-controller-manager` and `kube-scheduler`, we must expose them to the cluster.
|
||||
|
||||
|
||||
83
docs/migration-guide.md
Normal file
83
docs/migration-guide.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Migration guide from release-0.7 and earlier
|
||||
|
||||
## Why?
|
||||
|
||||
Thanks to our community we identified a lot of short-commings of previous design, varying from issues with global state to UX problems. Hoping to fix at least part of those issues we decided to do a complete refactor of the codebase.
|
||||
|
||||
## Overview
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
- global `_config` object is removed and the new `values` object is a partial replacement
|
||||
- `imageRepos` field was removed and the project no longer tries to compose image strings. Use `$.values.common.images` to override default images.
|
||||
- prometheus alerting and recording rules are split into multiple `PrometheusRule` objects
|
||||
- kubernetes control plane ServiceMonitors and Services are now part of the new `kubernetesControlPlane` top-level object instead of `prometheus` object
|
||||
- `jsonnet/kube-prometheus/kube-prometheus.libsonnet` file was renamed to `jsonnet/kube-prometheus/main.libsonnet` and slimmed down to bare minimum
|
||||
- `jsonnet/kube-prometheus/kube-prometheus*-.libsonnet` files were move either to `jsonnet/kube-prometheus/addons/` or `jsonnet/kube-prometheus/platforms/` depending on the feature they provided
|
||||
- all component libraries are now function- and not object-based
|
||||
- monitoring-mixins are included inside each component and not globally. `prometheusRules`, `prometheusAlerts`, and `grafanaDashboards` are accessible only per component via `mixin` object (ex. `$.alertmanager.mixin.prometheusAlerts`)
|
||||
- default repository branch changed from `master` to `main`
|
||||
- labels on resources have changes, `kubectl apply` will not work correctly due to those field being immutable. Deleting the resource first before applying is a workaround if you are using the kubectl CLI. (This only applies to `Deployments` and `DaemonSets`.)
|
||||
|
||||
### New Features
|
||||
|
||||
- concept of `addons`, `components`, and `platforms` was introduced
|
||||
- all main `components` are now represented internally by a function with default values and required parameters (see #Component-configuration for more information)
|
||||
- `$.values` holds main configuration parameters and should be used to set basic stack configuration.
|
||||
- common parameters across all `components` are stored now in `$.values.common`
|
||||
- removed dependency on deprecated ksonnet library
|
||||
|
||||
## Details
|
||||
|
||||
### Components, Addons, Platforms
|
||||
|
||||
Those concepts were already present in the repository but it wasn't clear which file is holding what. After refactoring we categorized jsonnet code into 3 buckets and put them into separate directories:
|
||||
- `components` - main building blocks for kube-prometheus, written as functions responsible for creating multiple objects representing kubernetes manifests. For example all objects for node_exporter deployment are bundled in `components/node_exporter.libsonnet` library
|
||||
- `addons` - everything that can enhance kube-prometheus deployment. Those are small snippets of code adding a small feature, for example adding anti-affinity to pods via [`addons/anti-affinity.libsonnet`][antiaffinity]. Addons are meant to be used in object-oriented way like `local kp = (import 'kube-prometheus/main.libsonnet') + (import 'kube-prometheus/addons/all-namespaces.libsonnet')`
|
||||
- `platforms` - currently those are `addons` specialized to allow deploying kube-prometheus project on a specific platform.
|
||||
|
||||
### Component configuration
|
||||
|
||||
Refactoring main components to use functions allowed us to define APIs for said components. Each function has a default set of parameters that can be overridden or that are required to be set by a user. Those default parameters are represented in each component by `defaults` map at the top of each library file, for example in [`node_exporter.libsonnet`][node_exporter_defaults_example].
|
||||
|
||||
This API is meant to ease the use of kube-prometheus as parameters can be passed from a JSON file and don't need to be in jsonnet format. However, if you need to modify particular parts of the stack, jsonnet allows you to do this and we are also not restricting such access in any way. An example of such modifications can be seen in any of our `addons`, like the [`addons/anti-affinity.libsonnet`][antiaffinity] one.
|
||||
|
||||
### Mixin integration
|
||||
|
||||
Previously kube-prometheus project joined all mixins on a global level. However with a wider adoption of monitoring mixins this turned out to be a problem, especially apparent when two mixins started to use the same configuration field for different purposes. To fix this we moved all mixins into their own respective components:
|
||||
- alertmanager mixin -> `alertmanager.libsonnet`
|
||||
- kubernetes mixin -> `k8s-control-plane.libsonnet`
|
||||
- kube-state-metrics mixin -> `kube-state-metrics.libsonnet`
|
||||
- node_exporter mixin -> `node_exporter.libsonnet`
|
||||
- prometheus and thanos sidecar mixins -> `prometheus.libsonnet`
|
||||
- prometheus-operator mixin -> `prometheus-operator.libsonnet`
|
||||
- kube-prometheus alerts and rules -> `components/mixin/custom.libsonnet`
|
||||
|
||||
> etcd mixin is a special case as we add it inside an `addon` in `addons/static-etcd.libsonnet`
|
||||
|
||||
This results in creating multiple `PrometheusRule` objects instead of having one giant object as before. It also means each mixin is configured separately and accessing mixin objects is done via `$.<component>.mixin`.
|
||||
|
||||
## Examples
|
||||
|
||||
All examples from `examples/` directory were adapted to the new codebase. [Please take a look at them for guideance](https://github.com/prometheus-operator/kube-prometheus/tree/main/examples)
|
||||
|
||||
## Advanced usage examples
|
||||
|
||||
For more advanced usage examples you can take a look at those two, open to public, implementations:
|
||||
- [thaum-xyz/ankhmorpork][thaum] - extending kube-prometheus to adapt to a required environment
|
||||
- [openshift/cluster-monitoring-operator][openshift] - using kube-prometheus components as standalone libraries to build a custom solution
|
||||
|
||||
## Final note
|
||||
|
||||
Refactoring was a huge undertaking and possibly this document didn't describe in enough detail how to help you with migration to the new stack. If that is the case, please reach out to us by using [GitHub discussions][discussions] feature or directly on [#prometheus-operator kubernetes slack channel][slack].
|
||||
|
||||
|
||||
[antiaffinity]: https://github.com/prometheus-operator/kube-prometheus/blob/main/jsonnet/kube-prometheus/addons/anti-affinity.libsonnet
|
||||
|
||||
[node_exporter_defaults_example]: https://github.com/prometheus-operator/kube-prometheus/blob/1d2a0e275af97948667777739a18b24464480dc8/jsonnet/kube-prometheus/components/node-exporter.libsonnet#L3-L34
|
||||
|
||||
[openshift]: https://github.com/openshift/cluster-monitoring-operator/pull/1044
|
||||
[thaum]: https://github.com/thaum-xyz/ankhmorpork/blob/master/apps/monitoring/jsonnet
|
||||
|
||||
[discussions]: https://github.com/prometheus-operator/kube-prometheus/discussions
|
||||
[slack]: http://slack.k8s.io/
|
||||
@@ -1,5 +1,18 @@
|
||||
# Monitoring external etcd
|
||||
This guide will help you monitor an external etcd cluster. When the etcd cluster is not hosted inside Kubernetes.
|
||||
---
|
||||
title: "Monitoring external etcd"
|
||||
description: "This guide will help you monitor an external etcd cluster."
|
||||
lead: "This guide will help you monitor an external etcd cluster."
|
||||
date: 2021-03-08T23:04:32+01:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 640
|
||||
toc: true
|
||||
---
|
||||
|
||||
When the etcd cluster is not hosted inside Kubernetes.
|
||||
This is often the case with Kubernetes setups. This approach has been tested with kube-aws but the same principals apply to other tools.
|
||||
|
||||
Note that [etcd.jsonnet](../examples/etcd.jsonnet) & [kube-prometheus-static-etcd.libsonnet](../jsonnet/kube-prometheus/kube-prometheus-static-etcd.libsonnet) (which are described by a section of the [Readme](../README.md#static-etcd-configuration)) do the following:
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
# Monitoring other Kubernetes Namespaces
|
||||
---
|
||||
title: "Monitoring other Namespaces"
|
||||
description: "This guide will help you monitor applications in other Namespaces."
|
||||
lead: "This guide will help you monitor applications in other Namespaces."
|
||||
date: 2021-03-08T23:04:32+01:00
|
||||
draft: false
|
||||
images: []
|
||||
menu:
|
||||
docs:
|
||||
parent: "kube"
|
||||
weight: 640
|
||||
toc: true
|
||||
---
|
||||
|
||||
This guide will help you monitor applications in other Namespaces. By default the RBAC rules are only enabled for the `Default` and `kube-system` Namespace during Install.
|
||||
|
||||
# Setup
|
||||
|
||||
@@ -17,36 +17,42 @@ Using kube-prometheus and kubectl you will be able install the following for mon
|
||||
|
||||
[embedmd]:# (../examples/weave-net-example.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-weave-net.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/weave-net/weave-net.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusAlerts+:: {
|
||||
groups: std.map(
|
||||
function(group)
|
||||
if group.name == 'weave-net' then
|
||||
group {
|
||||
rules: std.map(
|
||||
function(rule)
|
||||
if rule.alert == 'WeaveNetFastDPFlowsLow' then
|
||||
rule {
|
||||
expr: 'sum(weave_flows) < 20000',
|
||||
}
|
||||
else if rule.alert == 'WeaveNetIPAMUnreachable' then
|
||||
rule {
|
||||
expr: 'weave_ipam_unreachable_percentage > 25',
|
||||
}
|
||||
else
|
||||
rule
|
||||
,
|
||||
group.rules
|
||||
),
|
||||
}
|
||||
else
|
||||
group,
|
||||
super.groups
|
||||
),
|
||||
kubernetesControlPlane+: {
|
||||
prometheusRuleWeaveNet+: {
|
||||
spec+: {
|
||||
groups: std.map(
|
||||
function(group)
|
||||
if group.name == 'weave-net' then
|
||||
group {
|
||||
rules: std.map(
|
||||
function(rule)
|
||||
if rule.alert == 'WeaveNetFastDPFlowsLow' then
|
||||
rule {
|
||||
expr: 'sum(weave_flows) < 20000',
|
||||
}
|
||||
else if rule.alert == 'WeaveNetIPAMUnreachable' then
|
||||
rule {
|
||||
expr: 'weave_ipam_unreachable_percentage > 25',
|
||||
}
|
||||
else
|
||||
rule
|
||||
,
|
||||
group.rules
|
||||
),
|
||||
}
|
||||
else
|
||||
group,
|
||||
super.groups
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
22
docs/windows.md
Normal file
22
docs/windows.md
Normal file
@@ -0,0 +1,22 @@
|
||||
# Windows
|
||||
|
||||
The [Windows addon](../examples/windows.jsonnet) adds the dashboards and rules from [kubernetes-monitoring/kubernetes-mixin](https://github.com/kubernetes-monitoring/kubernetes-mixin#dashboards-for-windows-nodes).
|
||||
|
||||
Currently, Windows does not support running with [windows_exporter](https://github.com/prometheus-community/windows_exporter) in a pod so this add on uses [additional scrape configuration](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/additional-scrape-config.md) to set up a static config to scrape the node ports where windows_exporter is configured.
|
||||
|
||||
|
||||
The addon requires you to specify the node ips and ports where it can find the windows_exporter. See the [full example](../examples/windows.jsonnet) for setup.
|
||||
|
||||
```
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/windows.libsonnet') +
|
||||
{
|
||||
values+:: {
|
||||
windowsScrapeConfig+:: {
|
||||
static_configs: {
|
||||
targets: ["10.240.0.65:5000", "10.240.0.63:5000"],
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
```
|
||||
@@ -1,29 +1,34 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
// Uncomment the following imports to enable its patches
|
||||
// (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-custom-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-external-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/custom-metrics.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/external-metrics.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
|
||||
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor is separated so that it can be created after the CRDs are ready
|
||||
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
|
||||
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
prometheus+:: {
|
||||
namespaces+: ['my-namespace', 'my-second-namespace'],
|
||||
},
|
||||
},
|
||||
prometheus+:: {
|
||||
exampleApplication: {
|
||||
serviceMonitorMyNamespace: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
@@ -37,4 +39,5 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
prometheus+: {
|
||||
namespaces+: ['my-namespace', 'my-second-namespace'],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
alertmanager+: {
|
||||
config: importstr 'alertmanager-config.yaml',
|
||||
},
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
alertmanager+: {
|
||||
config: |||
|
||||
global:
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-all-namespaces.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
|
||||
prometheus+:: {
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/all-namespaces.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
prometheus+: {
|
||||
namespaces: [],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
local kp = (import './kube-prometheus/kube-prometheus.libsonnet');
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/anti-affinity.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['00namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{ ['0prometheus-operator-' + name]: kp.prometheusOperator[name] for name in std.objectFields(kp.prometheusOperator) } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
@@ -1,7 +1,8 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,20 +1,28 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-eks.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
kubePrometheus+: {
|
||||
platform: 'eks',
|
||||
},
|
||||
},
|
||||
prometheusRules+:: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
kubernetesControlPlane+: {
|
||||
prometheusRuleEksCNI+: {
|
||||
spec+: {
|
||||
groups+: [
|
||||
{
|
||||
record: 'aws_eks_available_ip',
|
||||
expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
{
|
||||
record: 'aws_eks_available_ip',
|
||||
expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < 10',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/static-etcd.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
etcd+:: {
|
||||
ips: ['127.0.0.1'],
|
||||
clientCA: importstr 'etcd-client-ca.crt',
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/static-etcd.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
|
||||
// Reference info: https://github.com/coreos/kube-prometheus/blob/master/README.md#static-etcd-configuration
|
||||
etcd+:: {
|
||||
etcd+: {
|
||||
// Configure this to be the IP(s) to scrape - i.e. your etcd node(s) (use commas to separate multiple values).
|
||||
ips: ['127.0.0.1'],
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"groups":[{"name":"example-group","rules":[{"alert":"Watchdog","annotations":{"description":"This is a Watchdog meant to ensure that the entire alerting pipeline is functional."},"expr":"vector(1)","labels":{"severity":"none"}}]}]}
|
||||
{"groups":[{"name":"example-group","rules":[{"alert":"ExampleAlert","annotations":{"description":"This is an example alert."},"expr":"vector(1)","labels":{"severity":"warning"}}]}]}
|
||||
@@ -1,9 +1,9 @@
|
||||
groups:
|
||||
- name: example-group
|
||||
rules:
|
||||
- alert: Watchdog
|
||||
- alert: ExampleAlert
|
||||
expr: vector(1)
|
||||
labels:
|
||||
severity: "none"
|
||||
severity: "warning"
|
||||
annotations:
|
||||
description: This is a Watchdog meant to ensure that the entire alerting pipeline is functional.
|
||||
description: This is an example alert.
|
||||
|
||||
@@ -5,35 +5,37 @@ local prometheus = grafana.prometheus;
|
||||
local template = grafana.template;
|
||||
local graphPanel = grafana.graphPanel;
|
||||
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+:: {
|
||||
dashboards+:: {
|
||||
'my-dashboard.json':
|
||||
dashboard.new('My Dashboard')
|
||||
.addTemplate(
|
||||
{
|
||||
current: {
|
||||
text: 'Prometheus',
|
||||
value: 'Prometheus',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+: {
|
||||
dashboards+:: {
|
||||
'my-dashboard.json':
|
||||
dashboard.new('My Dashboard')
|
||||
.addTemplate(
|
||||
{
|
||||
current: {
|
||||
text: 'Prometheus',
|
||||
value: 'Prometheus',
|
||||
},
|
||||
hide: 0,
|
||||
label: null,
|
||||
name: 'datasource',
|
||||
options: [],
|
||||
query: 'prometheus',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'datasource',
|
||||
},
|
||||
hide: 0,
|
||||
label: null,
|
||||
name: 'datasource',
|
||||
options: [],
|
||||
query: 'prometheus',
|
||||
refresh: 1,
|
||||
regex: '',
|
||||
type: 'datasource',
|
||||
},
|
||||
)
|
||||
.addRow(
|
||||
row.new()
|
||||
.addPanel(graphPanel.new('My Panel', span=6, datasource='$datasource')
|
||||
.addTarget(prometheus.target('vector(1)')))
|
||||
),
|
||||
)
|
||||
.addRow(
|
||||
row.new()
|
||||
.addPanel(graphPanel.new('My Panel', span=6, datasource='$datasource')
|
||||
.addTarget(prometheus.target('vector(1)')))
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+:: {
|
||||
rawDashboards+:: {
|
||||
'my-dashboard.json': (importstr 'example-grafana-dashboard.json'),
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+: {
|
||||
rawDashboards+:: {
|
||||
'my-dashboard.json': (importstr 'example-grafana-dashboard.json'),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafanaDashboards+:: { // monitoring-mixin compatibility
|
||||
'my-dashboard.json': (import 'example-grafana-dashboard.json'),
|
||||
},
|
||||
grafana+:: {
|
||||
dashboards+:: { // use this method to import your dashboards to Grafana
|
||||
'my-dashboard.json': (import 'example-grafana-dashboard.json'),
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+:: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+: {
|
||||
dashboards+:: { // use this method to import your dashboards to Grafana
|
||||
'my-dashboard.json': (import 'example-grafana-dashboard.json'),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,10 +14,12 @@ local ingress(name, namespace, rules) = {
|
||||
};
|
||||
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
grafana+:: {
|
||||
config+: {
|
||||
sections+: {
|
||||
@@ -47,7 +49,7 @@ local kp =
|
||||
ingress+:: {
|
||||
'alertmanager-main': ingress(
|
||||
'alertmanager-main',
|
||||
$._config.namespace,
|
||||
$.values.common.namespace,
|
||||
[{
|
||||
host: 'alertmanager.example.com',
|
||||
http: {
|
||||
@@ -64,7 +66,7 @@ local kp =
|
||||
),
|
||||
grafana: ingress(
|
||||
'grafana',
|
||||
$._config.namespace,
|
||||
$.values.common.namespace,
|
||||
[{
|
||||
host: 'grafana.example.com',
|
||||
http: {
|
||||
@@ -81,7 +83,7 @@ local kp =
|
||||
),
|
||||
'prometheus-k8s': ingress(
|
||||
'prometheus-k8s',
|
||||
$._config.namespace,
|
||||
$.values.common.namespace,
|
||||
[{
|
||||
host: 'prometheus.example.com',
|
||||
http: {
|
||||
@@ -105,7 +107,7 @@ local kp =
|
||||
kind: 'Secret',
|
||||
metadata: {
|
||||
name: 'basic-auth',
|
||||
namespace: $._config.namespace,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
data: { auth: std.base64(importstr 'auth') },
|
||||
type: 'Opaque',
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
local mixin = import 'kube-prometheus/kube-prometheus-config-mixins.libsonnet';
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local mixin = import 'kube-prometheus/addons/config-mixins.libsonnet';
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
} + mixin.withImageRepository('internal-registry.com/organization');
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-bootkube.libsonnet')
|
||||
@@ -1,3 +0,0 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kops.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kops-coredns.libsonnet')
|
||||
@@ -1,2 +0,0 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kops.libsonnet')
|
||||
@@ -1,2 +0,0 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kube-aws.libsonnet')
|
||||
@@ -1,2 +0,0 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet')
|
||||
@@ -1,2 +0,0 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kubespray.libsonnet')
|
||||
@@ -1,2 +1,2 @@
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet')
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/node-ports.libsonnet')
|
||||
|
||||
8
examples/jsonnet-snippets/platform.jsonnet
Normal file
8
examples/jsonnet-snippets/platform.jsonnet
Normal file
@@ -0,0 +1,8 @@
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
{
|
||||
values+:: {
|
||||
kubePrometheus+: {
|
||||
platform: 'example-platform',
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
nodeExporter+: {
|
||||
daemonset+: {
|
||||
metadata+: {
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
(import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
local manifests =
|
||||
// Uncomment line below to enable vertical auto scaling of kube-state-metrics
|
||||
//{ ['ksm-autoscaler-' + name]: kp.ksmAutoscaler[name] for name in std.objectFields(kp.ksmAutoscaler) } +
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
|
||||
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor is separated so that it can be created after the CRDs are ready
|
||||
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
|
||||
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) };
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) };
|
||||
|
||||
local kustomizationResourceFile(name) = './manifests/' + name + '.yaml';
|
||||
local kustomization = {
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') +
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
// Note that NodePort type services is likely not a good idea for your production use case, it is only used for demonstration purposes here.
|
||||
(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
|
||||
(import 'kube-prometheus/addons/node-ports.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
alertmanager+:: {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
alertmanager+: {
|
||||
config: importstr 'alertmanager-config.yaml',
|
||||
},
|
||||
grafana+:: {
|
||||
grafana+: {
|
||||
config: { // http://docs.grafana.org/installation/configuration/
|
||||
sections: {
|
||||
// Do not require grafana users to login/authenticate
|
||||
@@ -17,12 +18,15 @@ local kp =
|
||||
},
|
||||
},
|
||||
},
|
||||
kubePrometheus+: {
|
||||
platform: 'kubeadm',
|
||||
},
|
||||
},
|
||||
|
||||
// For simplicity, each of the following values for 'externalUrl':
|
||||
// * assume that `minikube ip` prints "192.168.99.100"
|
||||
// * hard-code the NodePort for each app
|
||||
prometheus+:: {
|
||||
prometheus+: {
|
||||
prometheus+: {
|
||||
// Reference info: https://coreos.com/operators/prometheus/docs/latest/api.html#prometheusspec
|
||||
spec+: {
|
||||
@@ -38,7 +42,7 @@ local kp =
|
||||
},
|
||||
},
|
||||
},
|
||||
alertmanager+:: {
|
||||
alertmanager+: {
|
||||
alertmanager+: {
|
||||
// Reference info: https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#alertmanagerspec
|
||||
spec+: {
|
||||
|
||||
23
examples/pod-security-policies.jsonnet
Normal file
23
examples/pod-security-policies.jsonnet
Normal file
@@ -0,0 +1,23 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/podsecuritypolicies.libsonnet');
|
||||
|
||||
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
|
||||
// Add the restricted psp to setup
|
||||
{ 'setup/0podsecuritypolicy-restricted': kp.restrictedPodSecurityPolicy } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
|
||||
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
|
||||
@@ -1,25 +1,37 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusAlerts+:: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
exampleApplication: {
|
||||
prometheusRuleExample: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
name: 'my-prometheus-rule',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: [
|
||||
{
|
||||
alert: 'Watchdog',
|
||||
expr: 'vector(1)',
|
||||
labels: {
|
||||
severity: 'none',
|
||||
},
|
||||
annotations: {
|
||||
description: 'This is a Watchdog meant to ensure that the entire alerting pipeline is functional.',
|
||||
},
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
{
|
||||
alert: 'ExampleAlert',
|
||||
expr: 'vector(1)',
|
||||
labels: {
|
||||
severity: 'warning',
|
||||
},
|
||||
annotations: {
|
||||
description: 'This is an example alert.',
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -30,4 +42,5 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
|
||||
@@ -1,19 +1,31 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusRules+:: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
exampleApplication: {
|
||||
prometheusRuleExample: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
name: 'my-prometheus-rule',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: [
|
||||
{
|
||||
record: 'some_recording_rule_name',
|
||||
expr: 'vector(1)',
|
||||
name: 'example-group',
|
||||
rules: [
|
||||
{
|
||||
record: 'some_recording_rule_name',
|
||||
expr: 'vector(1)',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -24,4 +36,5 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusAlerts+:: {
|
||||
groups+: (import 'existingrule.json').groups,
|
||||
exampleApplication: {
|
||||
prometheusRuleExample: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
name: 'my-prometheus-rule',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: (import 'existingrule.json').groups,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -14,4 +26,5 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['example-application-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
((import 'kube-prometheus/main.libsonnet') + {
|
||||
prometheus+: {
|
||||
prometheus+: {
|
||||
metadata+: {
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
// Uncomment the following imports to enable its patches
|
||||
// (import 'kube-prometheus/kube-prometheus-anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
|
||||
// (import 'kube-prometheus/kube-prometheus-thanos-sidecar.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/anti-affinity.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/managed-cluster.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/node-ports.libsonnet') +
|
||||
// (import 'kube-prometheus/addons/static-etcd.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-strip-limits.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/strip-limits.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
33
examples/thanos-sidecar.jsonnet
Normal file
33
examples/thanos-sidecar.jsonnet
Normal file
@@ -0,0 +1,33 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
{
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
prometheus+: {
|
||||
thanos: {
|
||||
version: '0.19.0',
|
||||
image: 'quay.io/thanos/thanos:v0.19.0',
|
||||
objectStorageConfig: {
|
||||
key: 'thanos.yaml', // How the file inside the secret is called
|
||||
name: 'thanos-objectstorage', // This is the name of your Kubernetes secret with the config
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['setup/0namespace-' + name]: kp.kubePrometheus[name] for name in std.objectFields(kp.kubePrometheus) } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor is separated so that it can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
@@ -1,23 +1,19 @@
|
||||
{
|
||||
_config+:: {
|
||||
tolerations+:: [
|
||||
{
|
||||
key: 'key1',
|
||||
operator: 'Equal',
|
||||
value: 'value1',
|
||||
effect: 'NoSchedule',
|
||||
},
|
||||
{
|
||||
key: 'key2',
|
||||
operator: 'Exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
prometheus+: {
|
||||
prometheus+: {
|
||||
spec+: {
|
||||
tolerations: [t for t in $._config.tolerations],
|
||||
tolerations: [
|
||||
{
|
||||
key: 'key1',
|
||||
operator: 'Equal',
|
||||
value: 'value1',
|
||||
effect: 'NoSchedule',
|
||||
},
|
||||
{
|
||||
key: 'key2',
|
||||
operator: 'Exists',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,33 +1,39 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-weave-net.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
local kp = (import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/weave-net/weave-net.libsonnet') + {
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
},
|
||||
prometheusAlerts+:: {
|
||||
groups: std.map(
|
||||
function(group)
|
||||
if group.name == 'weave-net' then
|
||||
group {
|
||||
rules: std.map(
|
||||
function(rule)
|
||||
if rule.alert == 'WeaveNetFastDPFlowsLow' then
|
||||
rule {
|
||||
expr: 'sum(weave_flows) < 20000',
|
||||
}
|
||||
else if rule.alert == 'WeaveNetIPAMUnreachable' then
|
||||
rule {
|
||||
expr: 'weave_ipam_unreachable_percentage > 25',
|
||||
}
|
||||
else
|
||||
rule
|
||||
,
|
||||
group.rules
|
||||
),
|
||||
}
|
||||
else
|
||||
group,
|
||||
super.groups
|
||||
),
|
||||
kubernetesControlPlane+: {
|
||||
prometheusRuleWeaveNet+: {
|
||||
spec+: {
|
||||
groups: std.map(
|
||||
function(group)
|
||||
if group.name == 'weave-net' then
|
||||
group {
|
||||
rules: std.map(
|
||||
function(rule)
|
||||
if rule.alert == 'WeaveNetFastDPFlowsLow' then
|
||||
rule {
|
||||
expr: 'sum(weave_flows) < 20000',
|
||||
}
|
||||
else if rule.alert == 'WeaveNetIPAMUnreachable' then
|
||||
rule {
|
||||
expr: 'weave_ipam_unreachable_percentage > 25',
|
||||
}
|
||||
else
|
||||
rule
|
||||
,
|
||||
group.rules
|
||||
),
|
||||
}
|
||||
else
|
||||
group,
|
||||
super.groups
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
33
examples/windows.jsonnet
Normal file
33
examples/windows.jsonnet
Normal file
@@ -0,0 +1,33 @@
|
||||
local kp =
|
||||
(import 'kube-prometheus/main.libsonnet') +
|
||||
(import 'kube-prometheus/addons/windows.libsonnet') +
|
||||
{
|
||||
values+:: {
|
||||
common+: {
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
windowsScrapeConfig+:: {
|
||||
static_configs: [{
|
||||
targets: ['10.240.0.65:5000', '10.240.0.63:5000'],
|
||||
}],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ 'setup/0namespace-namespace': kp.kubePrometheus.namespace } +
|
||||
{
|
||||
['setup/prometheus-operator-' + name]: kp.prometheusOperator[name]
|
||||
for name in std.filter((function(name) name != 'serviceMonitor' && name != 'prometheusRule'), std.objectFields(kp.prometheusOperator))
|
||||
} +
|
||||
// serviceMonitor and prometheusRule are separated so that they can be created after the CRDs are ready
|
||||
{ 'prometheus-operator-serviceMonitor': kp.prometheusOperator.serviceMonitor } +
|
||||
{ 'prometheus-operator-prometheusRule': kp.prometheusOperator.prometheusRule } +
|
||||
{ 'kube-prometheus-prometheusRule': kp.kubePrometheus.prometheusRule } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['blackbox-exporter-' + name]: kp.blackboxExporter[name] for name in std.objectFields(kp.blackboxExporter) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['prometheus-adapter-' + name]: kp.prometheusAdapter[name] for name in std.objectFields(kp.prometheusAdapter) }
|
||||
99
jsonnet/kube-prometheus/addons/anti-affinity.libsonnet
Normal file
99
jsonnet/kube-prometheus/addons/anti-affinity.libsonnet
Normal file
@@ -0,0 +1,99 @@
|
||||
{
|
||||
values+:: {
|
||||
alertmanager+: {
|
||||
podAntiAffinity: 'soft',
|
||||
podAntiAffinityTopologyKey: 'kubernetes.io/hostname',
|
||||
},
|
||||
prometheus+: {
|
||||
podAntiAffinity: 'soft',
|
||||
podAntiAffinityTopologyKey: 'kubernetes.io/hostname',
|
||||
},
|
||||
blackboxExporter+: {
|
||||
podAntiAffinity: 'soft',
|
||||
podAntiAffinityTopologyKey: 'kubernetes.io/hostname',
|
||||
},
|
||||
prometheusAdapter+: {
|
||||
podAntiAffinity: 'soft',
|
||||
podAntiAffinityTopologyKey: 'kubernetes.io/hostname',
|
||||
},
|
||||
},
|
||||
|
||||
local antiaffinity(labelSelector, namespace, type, topologyKey) = {
|
||||
local podAffinityTerm = {
|
||||
namespaces: [namespace],
|
||||
topologyKey: topologyKey,
|
||||
labelSelector: {
|
||||
matchLabels: labelSelector,
|
||||
},
|
||||
},
|
||||
|
||||
affinity: {
|
||||
podAntiAffinity: if type == 'soft' then {
|
||||
preferredDuringSchedulingIgnoredDuringExecution: [{
|
||||
weight: 100,
|
||||
podAffinityTerm: podAffinityTerm,
|
||||
}],
|
||||
} else if type == 'hard' then {
|
||||
requiredDuringSchedulingIgnoredDuringExecution: [
|
||||
podAffinityTerm,
|
||||
],
|
||||
} else error 'podAntiAffinity must be either "soft" or "hard"',
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager+: {
|
||||
alertmanager+: {
|
||||
spec+:
|
||||
antiaffinity(
|
||||
$.alertmanager._config.selectorLabels,
|
||||
$.values.common.namespace,
|
||||
$.values.alertmanager.podAntiAffinity,
|
||||
$.values.alertmanager.podAntiAffinityTopologyKey,
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
prometheus+: {
|
||||
prometheus+: {
|
||||
spec+:
|
||||
antiaffinity(
|
||||
$.prometheus._config.selectorLabels,
|
||||
$.values.common.namespace,
|
||||
$.values.prometheus.podAntiAffinity,
|
||||
$.values.prometheus.podAntiAffinityTopologyKey,
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
blackboxExporter+: {
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+:
|
||||
antiaffinity(
|
||||
$.blackboxExporter._config.selectorLabels,
|
||||
$.values.common.namespace,
|
||||
$.values.blackboxExporter.podAntiAffinity,
|
||||
$.values.blackboxExporter.podAntiAffinityTopologyKey,
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
prometheusAdapter+: {
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+:
|
||||
antiaffinity(
|
||||
$.prometheusAdapter._config.selectorLabels,
|
||||
$.values.common.namespace,
|
||||
$.values.prometheusAdapter.podAntiAffinity,
|
||||
$.values.prometheusAdapter.podAntiAffinityTopologyKey,
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,4 +1,18 @@
|
||||
local l = import 'lib/lib.libsonnet';
|
||||
local imageName(image) =
|
||||
local parts = std.split(image, '/');
|
||||
local len = std.length(parts);
|
||||
if len == 3 then
|
||||
// registry.com/org/image
|
||||
parts[2]
|
||||
else if len == 2 then
|
||||
// org/image
|
||||
parts[1]
|
||||
else if len == 1 then
|
||||
// image, ie. busybox
|
||||
parts[0]
|
||||
else
|
||||
error 'unknown image format: ' + image;
|
||||
|
||||
|
||||
// withImageRepository is a mixin that replaces all images prefixes by repository. eg.
|
||||
// quay.io/coreos/addon-resizer -> $repository/addon-resizer
|
||||
@@ -6,8 +20,8 @@ local l = import 'lib/lib.libsonnet';
|
||||
local withImageRepository(repository) = {
|
||||
local oldRepos = super._config.imageRepos,
|
||||
local substituteRepository(image, repository) =
|
||||
if repository == null then image else repository + '/' + l.imageName(image),
|
||||
_config+:: {
|
||||
if repository == null then image else repository + '/' + imageName(image),
|
||||
values+:: {
|
||||
imageRepos:: {
|
||||
[field]: substituteRepository(oldRepos[field], repository)
|
||||
for field in std.objectFields(oldRepos)
|
||||
@@ -2,9 +2,9 @@
|
||||
// For more details on usage visit https://github.com/DirectXMan12/k8s-prometheus-adapter#quick-links
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
prometheusAdapter+:: {
|
||||
namespace: $._config.namespace,
|
||||
values+:: {
|
||||
prometheusAdapter+: {
|
||||
namespace: $.values.common.namespace,
|
||||
// Rules for custom-metrics
|
||||
config+:: {
|
||||
rules+: [
|
||||
@@ -78,7 +78,7 @@
|
||||
},
|
||||
},
|
||||
|
||||
prometheusAdapter+:: {
|
||||
prometheusAdapter+: {
|
||||
customMetricsApiService: {
|
||||
apiVersion: 'apiregistration.k8s.io/v1',
|
||||
kind: 'APIService',
|
||||
@@ -88,7 +88,7 @@
|
||||
spec: {
|
||||
service: {
|
||||
name: $.prometheusAdapter.service.metadata.name,
|
||||
namespace: $._config.prometheusAdapter.namespace,
|
||||
namespace: $.values.prometheusAdapter.namespace,
|
||||
},
|
||||
group: 'custom.metrics.k8s.io',
|
||||
version: 'v1beta1',
|
||||
@@ -106,7 +106,7 @@
|
||||
spec: {
|
||||
service: {
|
||||
name: $.prometheusAdapter.service.metadata.name,
|
||||
namespace: $._config.prometheusAdapter.namespace,
|
||||
namespace: $.values.prometheusAdapter.namespace,
|
||||
},
|
||||
group: 'custom.metrics.k8s.io',
|
||||
version: 'v1beta2',
|
||||
@@ -141,7 +141,7 @@
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: $.prometheusAdapter.serviceAccount.metadata.name,
|
||||
namespace: $._config.prometheusAdapter.namespace,
|
||||
namespace: $.values.prometheusAdapter.namespace,
|
||||
}],
|
||||
},
|
||||
customMetricsClusterRoleBindingHPA: {
|
||||
@@ -2,9 +2,9 @@
|
||||
// For more details on usage visit https://github.com/DirectXMan12/k8s-prometheus-adapter#quick-links
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
prometheusAdapter+:: {
|
||||
namespace: $._config.namespace,
|
||||
values+:: {
|
||||
prometheusAdapter+: {
|
||||
namespace: $.values.common.namespace,
|
||||
// Rules for external-metrics
|
||||
config+:: {
|
||||
externalRules+: [
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
},
|
||||
|
||||
prometheusAdapter+:: {
|
||||
prometheusAdapter+: {
|
||||
externalMetricsApiService: {
|
||||
apiVersion: 'apiregistration.k8s.io/v1',
|
||||
kind: 'APIService',
|
||||
@@ -34,7 +34,7 @@
|
||||
spec: {
|
||||
service: {
|
||||
name: $.prometheusAdapter.service.metadata.name,
|
||||
namespace: $._config.prometheusAdapter.namespace,
|
||||
namespace: $.values.prometheusAdapter.namespace,
|
||||
},
|
||||
group: 'external.metrics.k8s.io',
|
||||
version: 'v1beta1',
|
||||
@@ -70,7 +70,7 @@
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: $.prometheusAdapter.serviceAccount.metadata.name,
|
||||
namespace: $._config.prometheusAdapter.namespace,
|
||||
namespace: $.values.prometheusAdapter.namespace,
|
||||
}],
|
||||
},
|
||||
externalMetricsClusterRoleBindingHPA: {
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
prometheus+:: {
|
||||
prometheus+: {
|
||||
serviceMonitorKubelet+:
|
||||
{
|
||||
spec+: {
|
||||
@@ -1,14 +1,15 @@
|
||||
{
|
||||
_config+:: {
|
||||
versions+:: { clusterVerticalAutoscaler: '0.8.1' },
|
||||
imageRepos+:: { clusterVerticalAutoscaler: 'gcr.io/google_containers/cpvpa-amd64' },
|
||||
|
||||
kubeStateMetrics+:: {
|
||||
values+:: {
|
||||
clusterVerticalAutoscaler: {
|
||||
version: '0.8.1',
|
||||
image: 'gcr.io/google_containers/cpvpa-amd64:v0.8.1',
|
||||
baseCPU: '1m',
|
||||
stepCPU: '1m',
|
||||
baseMemory: '1Mi',
|
||||
stepMemory: '2Mi',
|
||||
},
|
||||
},
|
||||
ksmAutoscaler+:: {
|
||||
ksmAutoscaler+: {
|
||||
clusterRole: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
@@ -29,7 +30,7 @@
|
||||
kind: 'ClusterRole',
|
||||
name: 'ksm-autoscaler',
|
||||
},
|
||||
subjects: [{ kind: 'ServiceAccount', name: 'ksm-autoscaler', namespace: $._config.namespace }],
|
||||
subjects: [{ kind: 'ServiceAccount', name: 'ksm-autoscaler', namespace: $.values.common.namespace }],
|
||||
},
|
||||
|
||||
roleBinding: {
|
||||
@@ -37,7 +38,7 @@
|
||||
kind: 'RoleBinding',
|
||||
metadata: {
|
||||
name: 'ksm-autoscaler',
|
||||
namespace: $._config.namespace,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
@@ -52,7 +53,7 @@
|
||||
kind: 'Role',
|
||||
metadata: {
|
||||
name: 'ksm-autoscaler',
|
||||
namespace: $._config.namespace,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
@@ -75,7 +76,7 @@
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: 'ksm-autoscaler',
|
||||
namespace: $._config.namespace,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
},
|
||||
|
||||
@@ -83,14 +84,21 @@
|
||||
local podLabels = { app: 'ksm-autoscaler' };
|
||||
local c = {
|
||||
name: 'ksm-autoscaler',
|
||||
image: $._config.imageRepos.clusterVerticalAutoscaler + ':v' + $._config.versions.clusterVerticalAutoscaler,
|
||||
image: $.values.clusterVerticalAutoscaler.image,
|
||||
args: [
|
||||
'/cpvpa',
|
||||
'--target=deployment/kube-state-metrics',
|
||||
'--namespace=' + $._config.namespace,
|
||||
'--namespace=' + $.values.common.namespace,
|
||||
'--logtostderr=true',
|
||||
'--poll-period-seconds=10',
|
||||
'--default-config={"kube-state-metrics":{"requests":{"cpu":{"base":"' + $._config.kubeStateMetrics.baseCPU + '","step":"' + $._config.kubeStateMetrics.stepCPU + '","nodesPerStep":1},"memory":{"base":"' + $._config.kubeStateMetrics.baseMemory + '","step":"' + $._config.kubeStateMetrics.stepMemory + '","nodesPerStep":1}},"limits":{"cpu":{"base":"' + $._config.kubeStateMetrics.baseCPU + '","step":"' + $._config.kubeStateMetrics.stepCPU + '","nodesPerStep":1},"memory":{"base":"' + $._config.kubeStateMetrics.baseMemory + '","step":"' + $._config.kubeStateMetrics.stepMemory + '","nodesPerStep":1}}}}',
|
||||
'--default-config={"kube-state-metrics":{"requests":{"cpu":{"base":"' + $.values.clusterVerticalAutoscaler.baseCPU +
|
||||
'","step":"' + $.values.clusterVerticalAutoscaler.stepCPU +
|
||||
'","nodesPerStep":1},"memory":{"base":"' + $.values.clusterVerticalAutoscaler.baseMemory +
|
||||
'","step":"' + $.values.clusterVerticalAutoscaler.stepMemory +
|
||||
'","nodesPerStep":1}},"limits":{"cpu":{"base":"' + $.values.clusterVerticalAutoscaler.baseCPU +
|
||||
'","step":"' + $.values.clusterVerticalAutoscaler.stepCPU +
|
||||
'","nodesPerStep":1},"memory":{"base":"' + $.values.clusterVerticalAutoscaler.baseMemory +
|
||||
'","step":"' + $.values.clusterVerticalAutoscaler.stepMemory + '","nodesPerStep":1}}}}',
|
||||
],
|
||||
resources: {
|
||||
requests: { cpu: '20m', memory: '10Mi' },
|
||||
@@ -102,7 +110,7 @@
|
||||
kind: 'Deployment',
|
||||
metadata: {
|
||||
name: 'ksm-autoscaler',
|
||||
namespace: $._config.namespace,
|
||||
namespace: $.values.common.namespace,
|
||||
labels: podLabels,
|
||||
},
|
||||
spec: {
|
||||
39
jsonnet/kube-prometheus/addons/ksm-lite.libsonnet
Normal file
39
jsonnet/kube-prometheus/addons/ksm-lite.libsonnet
Normal file
@@ -0,0 +1,39 @@
|
||||
local addArgs(args, name, containers) = std.map(
|
||||
function(c) if c.name == name then
|
||||
c {
|
||||
args+: args,
|
||||
}
|
||||
else c,
|
||||
containers,
|
||||
);
|
||||
|
||||
{
|
||||
kubeStateMetrics+: {
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
containers: addArgs(
|
||||
[|||
|
||||
--metric-denylist=
|
||||
kube_*_created,
|
||||
kube_*_metadata_resource_version,
|
||||
kube_replicaset_metadata_generation,
|
||||
kube_replicaset_status_observed_generation,
|
||||
kube_pod_restart_policy,
|
||||
kube_pod_init_container_status_terminated,
|
||||
kube_pod_init_container_status_running,
|
||||
kube_pod_container_status_terminated,
|
||||
kube_pod_container_status_running,
|
||||
kube_pod_completion_time,
|
||||
kube_pod_status_scheduled
|
||||
|||],
|
||||
'kube-state-metrics',
|
||||
super.containers
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
20
jsonnet/kube-prometheus/addons/managed-cluster.libsonnet
Normal file
20
jsonnet/kube-prometheus/addons/managed-cluster.libsonnet
Normal file
@@ -0,0 +1,20 @@
|
||||
// On managed Kubernetes clusters some of the control plane components are not exposed to customers.
|
||||
// Disable scrape jobs, service monitors, and alert groups for these components by overwriting 'main.libsonnet' defaults
|
||||
|
||||
{
|
||||
kubernetesControlPlane+: {
|
||||
serviceMonitorKubeControllerManager:: null,
|
||||
serviceMonitorKubeScheduler:: null,
|
||||
} + {
|
||||
prometheusRule+: {
|
||||
spec+: {
|
||||
local g = super.groups,
|
||||
groups: [
|
||||
h
|
||||
for h in g
|
||||
if !std.setMember(h.name, ['kubernetes-system-controller-manager', 'kubernetes-system-scheduler'])
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
260
jsonnet/kube-prometheus/addons/podsecuritypolicies.libsonnet
Normal file
260
jsonnet/kube-prometheus/addons/podsecuritypolicies.libsonnet
Normal file
@@ -0,0 +1,260 @@
|
||||
local restrictedPodSecurityPolicy = {
|
||||
apiVersion: 'policy/v1beta1',
|
||||
kind: 'PodSecurityPolicy',
|
||||
metadata: {
|
||||
name: 'kube-prometheus-restricted',
|
||||
},
|
||||
spec: {
|
||||
privileged: false,
|
||||
// Required to prevent escalations to root.
|
||||
allowPrivilegeEscalation: false,
|
||||
// This is redundant with non-root + disallow privilege escalation,
|
||||
// but we can provide it for defense in depth.
|
||||
requiredDropCapabilities: ['ALL'],
|
||||
// Allow core volume types.
|
||||
volumes: [
|
||||
'configMap',
|
||||
'emptyDir',
|
||||
'secret',
|
||||
// Assume that persistentVolumes set up by the cluster admin are safe to use.
|
||||
'persistentVolumeClaim',
|
||||
],
|
||||
hostNetwork: false,
|
||||
hostIPC: false,
|
||||
hostPID: false,
|
||||
runAsUser: {
|
||||
// Require the container to run without root privileges.
|
||||
rule: 'MustRunAsNonRoot',
|
||||
},
|
||||
seLinux: {
|
||||
// This policy assumes the nodes are using AppArmor rather than SELinux.
|
||||
rule: 'RunAsAny',
|
||||
},
|
||||
supplementalGroups: {
|
||||
rule: 'MustRunAs',
|
||||
ranges: [{
|
||||
// Forbid adding the root group.
|
||||
min: 1,
|
||||
max: 65535,
|
||||
}],
|
||||
},
|
||||
fsGroup: {
|
||||
rule: 'MustRunAs',
|
||||
ranges: [{
|
||||
// Forbid adding the root group.
|
||||
min: 1,
|
||||
max: 65535,
|
||||
}],
|
||||
},
|
||||
readOnlyRootFilesystem: false,
|
||||
},
|
||||
};
|
||||
|
||||
{
|
||||
restrictedPodSecurityPolicy: restrictedPodSecurityPolicy,
|
||||
|
||||
alertmanager+: {
|
||||
role: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'Role',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + $.values.alertmanager.name,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
rules: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: [restrictedPodSecurityPolicy.metadata.name],
|
||||
}],
|
||||
},
|
||||
|
||||
roleBinding: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleBinding',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + $.values.alertmanager.name,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'Role',
|
||||
name: 'alertmanager-' + $.values.alertmanager.name,
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: 'alertmanager-' + $.values.alertmanager.name,
|
||||
namespace: $.values.alertmanager.namespace,
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
blackboxExporter+: {
|
||||
clusterRole+: {
|
||||
rules+: [
|
||||
{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: ['blackbox-exporter-psp'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
podSecurityPolicy:
|
||||
local blackboxExporterPspPrivileged =
|
||||
if $.blackboxExporter._config.privileged then
|
||||
{
|
||||
metadata+: {
|
||||
name: 'blackbox-exporter-psp',
|
||||
},
|
||||
spec+: {
|
||||
privileged: true,
|
||||
allowedCapabilities: ['NET_RAW'],
|
||||
runAsUser: {
|
||||
rule: 'RunAsAny',
|
||||
},
|
||||
},
|
||||
}
|
||||
else
|
||||
{};
|
||||
|
||||
restrictedPodSecurityPolicy + blackboxExporterPspPrivileged,
|
||||
},
|
||||
|
||||
grafana+: {
|
||||
role: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'Role',
|
||||
metadata: {
|
||||
name: 'grafana',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
rules: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: [restrictedPodSecurityPolicy.metadata.name],
|
||||
}],
|
||||
},
|
||||
|
||||
roleBinding: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleBinding',
|
||||
metadata: {
|
||||
name: 'grafana',
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'Role',
|
||||
name: 'grafana',
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: $.grafana.serviceAccount.metadata.name,
|
||||
namespace: $.grafana.serviceAccount.metadata.namespace,
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
kubeStateMetrics+: {
|
||||
clusterRole+: {
|
||||
rules+: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: ['kube-state-metrics-psp'],
|
||||
}],
|
||||
},
|
||||
|
||||
podSecurityPolicy: restrictedPodSecurityPolicy {
|
||||
metadata+: {
|
||||
name: 'kube-state-metrics-psp',
|
||||
},
|
||||
spec+: {
|
||||
runAsUser: {
|
||||
rule: 'RunAsAny',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
nodeExporter+: {
|
||||
clusterRole+: {
|
||||
rules+: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: ['node-exporter-psp'],
|
||||
}],
|
||||
},
|
||||
|
||||
podSecurityPolicy: restrictedPodSecurityPolicy {
|
||||
metadata+: {
|
||||
name: 'node-exporter-psp',
|
||||
},
|
||||
spec+: {
|
||||
allowedHostPaths+: [
|
||||
{
|
||||
pathPrefix: '/proc',
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
pathPrefix: '/sys',
|
||||
readOnly: true,
|
||||
},
|
||||
{
|
||||
pathPrefix: '/',
|
||||
readOnly: true,
|
||||
},
|
||||
],
|
||||
hostNetwork: true,
|
||||
hostPID: true,
|
||||
hostPorts: [
|
||||
{
|
||||
max: $.nodeExporter._config.port,
|
||||
min: $.nodeExporter._config.port,
|
||||
},
|
||||
],
|
||||
readOnlyRootFilesystem: true,
|
||||
volumes+: [
|
||||
'hostPath',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
prometheusAdapter+: {
|
||||
clusterRole+: {
|
||||
rules+: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: [restrictedPodSecurityPolicy.metadata.name],
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
prometheusOperator+: {
|
||||
clusterRole+: {
|
||||
rules+: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: [restrictedPodSecurityPolicy.metadata.name],
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
prometheus+: {
|
||||
clusterRole+: {
|
||||
rules+: [{
|
||||
apiGroups: ['policy'],
|
||||
resources: ['podsecuritypolicies'],
|
||||
verbs: ['use'],
|
||||
resourceNames: [restrictedPodSecurityPolicy.metadata.name],
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
(import 'github.com/etcd-io/etcd/Documentation/etcd-mixin/mixin.libsonnet') + {
|
||||
_config+:: {
|
||||
(import 'github.com/etcd-io/etcd/contrib/mixin/mixin.libsonnet') + {
|
||||
values+:: {
|
||||
etcd: {
|
||||
ips: [],
|
||||
clientCA: null,
|
||||
@@ -9,14 +9,14 @@
|
||||
insecureSkipVerify: null,
|
||||
},
|
||||
},
|
||||
prometheus+:: {
|
||||
prometheus+: {
|
||||
serviceEtcd: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'etcd',
|
||||
namespace: 'kube-system',
|
||||
labels: { 'k8s-app': 'etcd' },
|
||||
labels: { 'app.kubernetes.io/name': 'etcd' },
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
@@ -31,12 +31,12 @@
|
||||
metadata: {
|
||||
name: 'etcd',
|
||||
namespace: 'kube-system',
|
||||
labels: { 'k8s-app': 'etcd' },
|
||||
labels: { 'app.kubernetes.io/name': 'etcd' },
|
||||
},
|
||||
subsets: [{
|
||||
addresses: [
|
||||
{ ip: etcdIP }
|
||||
for etcdIP in $._config.etcd.ips
|
||||
for etcdIP in $.values.etcd.ips
|
||||
],
|
||||
ports: [
|
||||
{ name: 'metrics', port: 2379, protocol: 'TCP' },
|
||||
@@ -50,11 +50,11 @@
|
||||
name: 'etcd',
|
||||
namespace: 'kube-system',
|
||||
labels: {
|
||||
'k8s-app': 'etcd',
|
||||
'app.kubernetes.io/name': 'etcd',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
endpoints: [
|
||||
{
|
||||
port: 'metrics',
|
||||
@@ -65,14 +65,14 @@
|
||||
caFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client-ca.crt',
|
||||
keyFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client.key',
|
||||
certFile: '/etc/prometheus/secrets/kube-etcd-client-certs/etcd-client.crt',
|
||||
[if $._config.etcd.serverName != null then 'serverName']: $._config.etcd.serverName,
|
||||
[if $._config.etcd.insecureSkipVerify != null then 'insecureSkipVerify']: $._config.etcd.insecureSkipVerify,
|
||||
[if $.values.etcd.serverName != null then 'serverName']: $.values.etcd.serverName,
|
||||
[if $.values.etcd.insecureSkipVerify != null then 'insecureSkipVerify']: $.values.etcd.insecureSkipVerify,
|
||||
},
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'etcd',
|
||||
'app.kubernetes.io/name': 'etcd',
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -84,12 +84,12 @@
|
||||
type: 'Opaque',
|
||||
metadata: {
|
||||
name: 'kube-etcd-client-certs',
|
||||
namespace: $._config.namespace,
|
||||
namespace: $.values.common.namespace,
|
||||
},
|
||||
data: {
|
||||
'etcd-client-ca.crt': std.base64($._config.etcd.clientCA),
|
||||
'etcd-client.key': std.base64($._config.etcd.clientKey),
|
||||
'etcd-client.crt': std.base64($._config.etcd.clientCert),
|
||||
'etcd-client-ca.crt': std.base64($.values.etcd.clientCA),
|
||||
'etcd-client.key': std.base64($.values.etcd.clientKey),
|
||||
'etcd-client.crt': std.base64($.values.etcd.clientCert),
|
||||
},
|
||||
},
|
||||
prometheus+: {
|
||||
48
jsonnet/kube-prometheus/addons/strip-limits.libsonnet
Normal file
48
jsonnet/kube-prometheus/addons/strip-limits.libsonnet
Normal file
@@ -0,0 +1,48 @@
|
||||
// Strips spec.containers[].limits for certain containers
|
||||
// https://github.com/prometheus-operator/kube-prometheus/issues/72
|
||||
|
||||
{
|
||||
local noLimit(c) =
|
||||
//if std.objectHas(c, 'resources') && c.name != 'kube-state-metrics'
|
||||
if c.name != 'kube-state-metrics'
|
||||
then c { resources+: { limits: {} } }
|
||||
else c,
|
||||
|
||||
nodeExporter+: {
|
||||
daemonset+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
containers: std.map(noLimit, super.containers),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
kubeStateMetrics+: {
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
containers: std.map(noLimit, super.containers),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
prometheusOperator+: {
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
local addArgs(c) =
|
||||
if c.name == 'prometheus-operator'
|
||||
then c { args+: ['--config-reloader-cpu=0'] }
|
||||
else c,
|
||||
containers: std.map(addArgs, super.containers),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
134
jsonnet/kube-prometheus/addons/weave-net/alerts.libsonnet
Normal file
134
jsonnet/kube-prometheus/addons/weave-net/alerts.libsonnet
Normal file
@@ -0,0 +1,134 @@
|
||||
[
|
||||
{
|
||||
alert: 'WeaveNetIPAMSplitBrain',
|
||||
expr: 'max(weave_ipam_unreachable_percentage) - min(weave_ipam_unreachable_percentage) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'Percentage of all IP addresses owned by unreachable peers is not same for every node.',
|
||||
description: 'actionable: Weave Net network has a split brain problem. Please find the problem and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetIPAMUnreachable',
|
||||
expr: 'weave_ipam_unreachable_percentage > 25',
|
||||
'for': '10m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'Percentage of all IP addresses owned by unreachable peers is above threshold.',
|
||||
description: 'actionable: Please find the problem and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetIPAMPendingAllocates',
|
||||
expr: 'sum(weave_ipam_pending_allocates) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'Number of pending allocates is above the threshold.',
|
||||
description: 'actionable: Please find the problem and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetIPAMPendingClaims',
|
||||
expr: 'sum(weave_ipam_pending_claims) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'Number of pending claims is above the threshold.',
|
||||
description: 'actionable: Please find the problem and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetFastDPFlowsLow',
|
||||
expr: 'sum(weave_flows) < 15000',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'Number of FastDP flows is below the threshold.',
|
||||
description: 'actionable: Please find the reason for FastDP flows to go below the threshold and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetFastDPFlowsOff',
|
||||
expr: 'sum(weave_flows == bool 0) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'FastDP flows is zero.',
|
||||
description: 'actionable: Please find the reason for FastDP flows to be off and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetHighConnectionTerminationRate',
|
||||
expr: 'rate(weave_connection_terminations_total[5m]) > 0.1',
|
||||
'for': '5m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'A lot of connections are getting terminated.',
|
||||
description: 'actionable: Please find the reason for the high connection termination rate and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetConnectionsConnecting',
|
||||
expr: 'sum(weave_connections{state="connecting"}) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'A lot of connections are in connecting state.',
|
||||
description: 'actionable: Please find the reason for this and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetConnectionsRetying',
|
||||
expr: 'sum(weave_connections{state="retrying"}) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'A lot of connections are in retrying state.',
|
||||
description: 'actionable: Please find the reason for this and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetConnectionsPending',
|
||||
expr: 'sum(weave_connections{state="pending"}) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'A lot of connections are in pending state.',
|
||||
description: 'actionable: Please find the reason for this and fix it.',
|
||||
},
|
||||
},
|
||||
{
|
||||
alert: 'WeaveNetConnectionsFailed',
|
||||
expr: 'sum(weave_connections{state="failed"}) > 0',
|
||||
'for': '3m',
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
summary: 'A lot of connections are in failed state.',
|
||||
description: 'actionable: Please find the reason and fix it.',
|
||||
},
|
||||
},
|
||||
]
|
||||
73
jsonnet/kube-prometheus/addons/weave-net/weave-net.libsonnet
Normal file
73
jsonnet/kube-prometheus/addons/weave-net/weave-net.libsonnet
Normal file
@@ -0,0 +1,73 @@
|
||||
{
|
||||
prometheus+: {
|
||||
local p = self,
|
||||
serviceWeaveNet: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'weave-net',
|
||||
namespace: 'kube-system',
|
||||
labels: { 'app.kubernetes.io/name': 'weave-net' },
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'weave-net-metrics', targetPort: 6782, port: 6782 },
|
||||
],
|
||||
selector: { name: 'weave-net' },
|
||||
clusterIP: 'None',
|
||||
},
|
||||
},
|
||||
serviceMonitorWeaveNet: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'weave-net',
|
||||
labels: {
|
||||
'app.kubernetes.io/name': 'weave-net',
|
||||
},
|
||||
namespace: 'monitoring',
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
endpoints: [
|
||||
{
|
||||
port: 'weave-net-metrics',
|
||||
path: '/metrics',
|
||||
interval: '15s',
|
||||
},
|
||||
],
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'kube-system',
|
||||
],
|
||||
},
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'app.kubernetes.io/name': 'weave-net',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
prometheusRuleWeaveNet: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: p._config.mixin.ruleLabels,
|
||||
name: 'weave-net-rules',
|
||||
namespace: p._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
groups: [{
|
||||
name: 'weave-net',
|
||||
rules: (import './alerts.libsonnet'),
|
||||
}],
|
||||
},
|
||||
},
|
||||
mixin+:: {
|
||||
grafanaDashboards+:: {
|
||||
'weave-net.json': (import './grafana-weave-net.json'),
|
||||
'weave-net-cluster.json': (import './grafana-weave-net-cluster.json'),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
70
jsonnet/kube-prometheus/addons/windows.libsonnet
Normal file
70
jsonnet/kube-prometheus/addons/windows.libsonnet
Normal file
@@ -0,0 +1,70 @@
|
||||
local windowsdashboards = import 'kubernetes-mixin/dashboards/windows.libsonnet';
|
||||
local windowsrules = import 'kubernetes-mixin/rules/windows.libsonnet';
|
||||
|
||||
{
|
||||
values+:: {
|
||||
// This needs to follow prometheus naming convention and not prometheus-operator one
|
||||
windowsScrapeConfig+:: {
|
||||
job_name: 'windows-exporter',
|
||||
static_configs: [
|
||||
{
|
||||
targets: [error 'must provide targets array'],
|
||||
},
|
||||
],
|
||||
relabel_configs: [
|
||||
{
|
||||
action: 'replace',
|
||||
regex: '(.*)',
|
||||
replacement: '$1',
|
||||
source_labels: [
|
||||
'__meta_kubernetes_endpoint_address_target_name',
|
||||
],
|
||||
target_label: 'instance',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
grafana+:: {
|
||||
dashboards+:: windowsdashboards {
|
||||
_config: $.kubernetesControlPlane.mixin._config {
|
||||
wmiExporterSelector: 'job="' + $.values.windowsScrapeConfig.job_name + '"',
|
||||
},
|
||||
}.grafanaDashboards,
|
||||
},
|
||||
},
|
||||
kubernetesControlPlane+: {
|
||||
mixin+:: {
|
||||
prometheusRules+:: {
|
||||
groups+: windowsrules {
|
||||
_config: $.kubernetesControlPlane.mixin._config {
|
||||
wmiExporterSelector: 'job="' + $.values.windowsScrapeConfig.job_name + '"',
|
||||
},
|
||||
}.prometheusRules.groups,
|
||||
},
|
||||
},
|
||||
},
|
||||
prometheus+: {
|
||||
local p = self,
|
||||
local sc = [$.values.windowsScrapeConfig],
|
||||
prometheus+: {
|
||||
spec+: {
|
||||
additionalScrapeConfigs: {
|
||||
name: 'prometheus-' + p._config.name + '-additional-scrape-config',
|
||||
key: 'prometheus-additional.yaml',
|
||||
},
|
||||
},
|
||||
|
||||
},
|
||||
windowsConfig: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Secret',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name + '-additional-scrape-config',
|
||||
namespace: p._config.namespace,
|
||||
},
|
||||
stringData: {
|
||||
'prometheus-additional.yaml': std.manifestYamlDoc(sc),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,147 +0,0 @@
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'default',
|
||||
|
||||
versions+:: {
|
||||
alertmanager: 'v0.21.0',
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
alertmanager: 'quay.io/prometheus/alertmanager',
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
name: 'main',
|
||||
config: {
|
||||
global: {
|
||||
resolve_timeout: '5m',
|
||||
},
|
||||
inhibit_rules: [{
|
||||
source_match: {
|
||||
severity: 'critical',
|
||||
},
|
||||
target_match_re: {
|
||||
severity: 'warning|info',
|
||||
},
|
||||
equal: ['namespace', 'alertname'],
|
||||
}, {
|
||||
source_match: {
|
||||
severity: 'warning',
|
||||
},
|
||||
target_match_re: {
|
||||
severity: 'info',
|
||||
},
|
||||
equal: ['namespace', 'alertname'],
|
||||
}],
|
||||
route: {
|
||||
group_by: ['namespace'],
|
||||
group_wait: '30s',
|
||||
group_interval: '5m',
|
||||
repeat_interval: '12h',
|
||||
receiver: 'Default',
|
||||
routes: [
|
||||
{ receiver: 'Watchdog', match: { alertname: 'Watchdog' } },
|
||||
{ receiver: 'Critical', match: { severity: 'critical' } },
|
||||
],
|
||||
},
|
||||
receivers: [
|
||||
{ name: 'Default' },
|
||||
{ name: 'Watchdog' },
|
||||
{ name: 'Critical' },
|
||||
],
|
||||
},
|
||||
replicas: 3,
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
secret: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Secret',
|
||||
type: 'Opaque',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + $._config.alertmanager.name,
|
||||
namespace: $._config.namespace,
|
||||
},
|
||||
stringData: {
|
||||
'alertmanager.yaml': if std.type($._config.alertmanager.config) == 'object'
|
||||
then
|
||||
std.manifestYamlDoc($._config.alertmanager.config)
|
||||
else
|
||||
$._config.alertmanager.config,
|
||||
},
|
||||
},
|
||||
|
||||
serviceAccount: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + $._config.alertmanager.name,
|
||||
namespace: $._config.namespace,
|
||||
},
|
||||
},
|
||||
|
||||
service: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + $._config.alertmanager.name,
|
||||
namespace: $._config.namespace,
|
||||
labels: { alertmanager: $._config.alertmanager.name },
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'web', targetPort: 'web', port: 9093 },
|
||||
],
|
||||
selector: { app: 'alertmanager', alertmanager: $._config.alertmanager.name },
|
||||
sessionAffinity: 'ClientIP',
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitor: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'alertmanager',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'alertmanager',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: {
|
||||
alertmanager: $._config.alertmanager.name,
|
||||
},
|
||||
},
|
||||
endpoints: [
|
||||
{ port: 'web', interval: '30s' },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'Alertmanager',
|
||||
metadata: {
|
||||
name: $._config.alertmanager.name,
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
alertmanager: $._config.alertmanager.name,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
replicas: $._config.alertmanager.replicas,
|
||||
version: $._config.versions.alertmanager,
|
||||
image: $._config.imageRepos.alertmanager + ':' + $._config.versions.alertmanager,
|
||||
nodeSelector: { 'kubernetes.io/os': 'linux' },
|
||||
serviceAccountName: 'alertmanager-' + $._config.alertmanager.name,
|
||||
securityContext: {
|
||||
runAsUser: 1000,
|
||||
runAsNonRoot: true,
|
||||
fsGroup: 2000,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
213
jsonnet/kube-prometheus/components/alertmanager.libsonnet
Normal file
213
jsonnet/kube-prometheus/components/alertmanager.libsonnet
Normal file
@@ -0,0 +1,213 @@
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
namespace: error 'must provide namespace',
|
||||
image: error 'must provide image',
|
||||
version: error 'must provide version',
|
||||
resources: {
|
||||
limits: { cpu: '100m', memory: '100Mi' },
|
||||
requests: { cpu: '4m', memory: '100Mi' },
|
||||
},
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': 'alertmanager',
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'alert-router',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
name: error 'must provide name',
|
||||
config: {
|
||||
global: {
|
||||
resolve_timeout: '5m',
|
||||
},
|
||||
inhibit_rules: [{
|
||||
source_match: {
|
||||
severity: 'critical',
|
||||
},
|
||||
target_match_re: {
|
||||
severity: 'warning|info',
|
||||
},
|
||||
equal: ['namespace', 'alertname'],
|
||||
}, {
|
||||
source_match: {
|
||||
severity: 'warning',
|
||||
},
|
||||
target_match_re: {
|
||||
severity: 'info',
|
||||
},
|
||||
equal: ['namespace', 'alertname'],
|
||||
}],
|
||||
route: {
|
||||
group_by: ['namespace'],
|
||||
group_wait: '30s',
|
||||
group_interval: '5m',
|
||||
repeat_interval: '12h',
|
||||
receiver: 'Default',
|
||||
routes: [
|
||||
{ receiver: 'Watchdog', match: { alertname: 'Watchdog' } },
|
||||
{ receiver: 'Critical', match: { severity: 'critical' } },
|
||||
],
|
||||
},
|
||||
receivers: [
|
||||
{ name: 'Default' },
|
||||
{ name: 'Watchdog' },
|
||||
{ name: 'Critical' },
|
||||
],
|
||||
},
|
||||
replicas: 3,
|
||||
mixin: {
|
||||
ruleLabels: {},
|
||||
_config: {
|
||||
alertmanagerName: '{{ $labels.namespace }}/{{ $labels.pod}}',
|
||||
alertmanagerClusterLabels: 'namespace,service',
|
||||
alertmanagerSelector: 'job="alertmanager-' + defaults.name + '",namespace="' + defaults.namespace + '"',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function(params) {
|
||||
local am = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(am._config.resources),
|
||||
assert std.isObject(am._config.mixin._config),
|
||||
|
||||
mixin:: (import 'github.com/prometheus/alertmanager/doc/alertmanager-mixin/mixin.libsonnet') +
|
||||
(import 'github.com/kubernetes-monitoring/kubernetes-mixin/alerts/add-runbook-links.libsonnet') {
|
||||
_config+:: am._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: am._config.commonLabels + am._config.mixin.ruleLabels,
|
||||
name: 'alertmanager-' + am._config.name + '-rules',
|
||||
namespace: am._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(am.mixin, 'prometheusRules') then am.mixin.prometheusRules.groups else [],
|
||||
local a = if std.objectHasAll(am.mixin, 'prometheusAlerts') then am.mixin.prometheusAlerts.groups else [],
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
|
||||
secret: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Secret',
|
||||
type: 'Opaque',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + am._config.name,
|
||||
namespace: am._config.namespace,
|
||||
labels: { alertmanager: am._config.name } + am._config.commonLabels,
|
||||
},
|
||||
stringData: {
|
||||
'alertmanager.yaml': if std.type(am._config.config) == 'object'
|
||||
then
|
||||
std.manifestYamlDoc(am._config.config)
|
||||
else
|
||||
am._config.config,
|
||||
},
|
||||
},
|
||||
|
||||
serviceAccount: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + am._config.name,
|
||||
namespace: am._config.namespace,
|
||||
labels: { alertmanager: am._config.name } + am._config.commonLabels,
|
||||
},
|
||||
},
|
||||
|
||||
service: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + am._config.name,
|
||||
namespace: am._config.namespace,
|
||||
labels: { alertmanager: am._config.name } + am._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'web', targetPort: 'web', port: 9093 },
|
||||
],
|
||||
selector: {
|
||||
app: 'alertmanager',
|
||||
alertmanager: am._config.name,
|
||||
} + am._config.selectorLabels,
|
||||
sessionAffinity: 'ClientIP',
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitor: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'alertmanager',
|
||||
namespace: am._config.namespace,
|
||||
labels: am._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: {
|
||||
alertmanager: am._config.name,
|
||||
} + am._config.selectorLabels,
|
||||
},
|
||||
endpoints: [
|
||||
{ port: 'web', interval: '30s' },
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
[if (defaults + params).replicas > 1 then 'podDisruptionBudget']: {
|
||||
apiVersion: 'policy/v1beta1',
|
||||
kind: 'PodDisruptionBudget',
|
||||
metadata: {
|
||||
name: 'alertmanager-' + am._config.name,
|
||||
namespace: am._config.namespace,
|
||||
labels: am._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
maxUnavailable: 1,
|
||||
selector: {
|
||||
matchLabels: {
|
||||
alertmanager: am._config.name,
|
||||
} + am._config.selectorLabels,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'Alertmanager',
|
||||
metadata: {
|
||||
name: am._config.name,
|
||||
namespace: am._config.namespace,
|
||||
labels: {
|
||||
alertmanager: am._config.name,
|
||||
} + am._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
replicas: am._config.replicas,
|
||||
version: am._config.version,
|
||||
image: am._config.image,
|
||||
podMetadata: {
|
||||
labels: am._config.commonLabels,
|
||||
},
|
||||
resources: am._config.resources,
|
||||
nodeSelector: { 'kubernetes.io/os': 'linux' },
|
||||
serviceAccountName: 'alertmanager-' + am._config.name,
|
||||
securityContext: {
|
||||
runAsUser: 1000,
|
||||
runAsNonRoot: true,
|
||||
fsGroup: 2000,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
287
jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet
Normal file
287
jsonnet/kube-prometheus/components/blackbox-exporter.libsonnet
Normal file
@@ -0,0 +1,287 @@
|
||||
local krp = import './kube-rbac-proxy.libsonnet';
|
||||
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
image: error 'must provide version',
|
||||
resources: {
|
||||
requests: { cpu: '10m', memory: '20Mi' },
|
||||
limits: { cpu: '20m', memory: '40Mi' },
|
||||
},
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': 'blackbox-exporter',
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'exporter',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
configmapReloaderImage: 'jimmidyson/configmap-reload:v0.5.0',
|
||||
|
||||
port: 9115,
|
||||
internalPort: 19115,
|
||||
replicas: 1,
|
||||
modules: {
|
||||
http_2xx: {
|
||||
prober: 'http',
|
||||
http: {
|
||||
preferred_ip_protocol: 'ip4',
|
||||
},
|
||||
},
|
||||
http_post_2xx: {
|
||||
prober: 'http',
|
||||
http: {
|
||||
method: 'POST',
|
||||
preferred_ip_protocol: 'ip4',
|
||||
},
|
||||
},
|
||||
tcp_connect: {
|
||||
prober: 'tcp',
|
||||
tcp: {
|
||||
preferred_ip_protocol: 'ip4',
|
||||
},
|
||||
},
|
||||
pop3s_banner: {
|
||||
prober: 'tcp',
|
||||
tcp: {
|
||||
query_response: [
|
||||
{ expect: '^+OK' },
|
||||
],
|
||||
tls: true,
|
||||
tls_config: {
|
||||
insecure_skip_verify: false,
|
||||
},
|
||||
preferred_ip_protocol: 'ip4',
|
||||
},
|
||||
},
|
||||
ssh_banner: {
|
||||
prober: 'tcp',
|
||||
tcp: {
|
||||
query_response: [
|
||||
{ expect: '^SSH-2.0-' },
|
||||
],
|
||||
preferred_ip_protocol: 'ip4',
|
||||
},
|
||||
},
|
||||
irc_banner: {
|
||||
prober: 'tcp',
|
||||
tcp: {
|
||||
query_response: [
|
||||
{ send: 'NICK prober' },
|
||||
{ send: 'USER prober prober prober :prober' },
|
||||
{ expect: 'PING :([^ ]+)', send: 'PONG ${1}' },
|
||||
{ expect: '^:[^ ]+ 001' },
|
||||
],
|
||||
preferred_ip_protocol: 'ip4',
|
||||
},
|
||||
},
|
||||
},
|
||||
privileged:
|
||||
local icmpModules = [self.modules[m] for m in std.objectFields(self.modules) if self.modules[m].prober == 'icmp'];
|
||||
std.length(icmpModules) > 0,
|
||||
};
|
||||
|
||||
|
||||
function(params) {
|
||||
local bb = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(bb._config.resources),
|
||||
|
||||
configuration: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ConfigMap',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter-configuration',
|
||||
namespace: bb._config.namespace,
|
||||
labels: bb._config.commonLabels,
|
||||
},
|
||||
data: {
|
||||
'config.yml': std.manifestYamlDoc({ modules: bb._config.modules }),
|
||||
},
|
||||
},
|
||||
|
||||
serviceAccount: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter',
|
||||
namespace: bb._config.namespace,
|
||||
},
|
||||
},
|
||||
|
||||
clusterRole: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter',
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
apiGroups: ['authentication.k8s.io'],
|
||||
resources: ['tokenreviews'],
|
||||
verbs: ['create'],
|
||||
},
|
||||
{
|
||||
apiGroups: ['authorization.k8s.io'],
|
||||
resources: ['subjectaccessreviews'],
|
||||
verbs: ['create'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
clusterRoleBinding: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRoleBinding',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter',
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'ClusterRole',
|
||||
name: 'blackbox-exporter',
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: 'blackbox-exporter',
|
||||
namespace: bb._config.namespace,
|
||||
}],
|
||||
},
|
||||
|
||||
deployment:
|
||||
local blackboxExporter = {
|
||||
name: 'blackbox-exporter',
|
||||
image: bb._config.image,
|
||||
args: [
|
||||
'--config.file=/etc/blackbox_exporter/config.yml',
|
||||
'--web.listen-address=:%d' % bb._config.internalPort,
|
||||
],
|
||||
ports: [{
|
||||
name: 'http',
|
||||
containerPort: bb._config.internalPort,
|
||||
}],
|
||||
resources: bb._config.resources,
|
||||
securityContext: if bb._config.privileged then {
|
||||
runAsNonRoot: false,
|
||||
capabilities: { drop: ['ALL'], add: ['NET_RAW'] },
|
||||
} else {
|
||||
runAsNonRoot: true,
|
||||
runAsUser: 65534,
|
||||
},
|
||||
volumeMounts: [{
|
||||
mountPath: '/etc/blackbox_exporter/',
|
||||
name: 'config',
|
||||
readOnly: true,
|
||||
}],
|
||||
};
|
||||
|
||||
local reloader = {
|
||||
name: 'module-configmap-reloader',
|
||||
image: bb._config.configmapReloaderImage,
|
||||
args: [
|
||||
'--webhook-url=http://localhost:%d/-/reload' % bb._config.internalPort,
|
||||
'--volume-dir=/etc/blackbox_exporter/',
|
||||
],
|
||||
resources: bb._config.resources,
|
||||
securityContext: { runAsNonRoot: true, runAsUser: 65534 },
|
||||
terminationMessagePath: '/dev/termination-log',
|
||||
terminationMessagePolicy: 'FallbackToLogsOnError',
|
||||
volumeMounts: [{
|
||||
mountPath: '/etc/blackbox_exporter/',
|
||||
name: 'config',
|
||||
readOnly: true,
|
||||
}],
|
||||
};
|
||||
|
||||
local kubeRbacProxy = krp({
|
||||
name: 'kube-rbac-proxy',
|
||||
upstream: 'http://127.0.0.1:' + bb._config.internalPort + '/',
|
||||
secureListenAddress: ':' + bb._config.port,
|
||||
ports: [
|
||||
{ name: 'https', containerPort: bb._config.port },
|
||||
],
|
||||
});
|
||||
|
||||
{
|
||||
apiVersion: 'apps/v1',
|
||||
kind: 'Deployment',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter',
|
||||
namespace: bb._config.namespace,
|
||||
labels: bb._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
replicas: bb._config.replicas,
|
||||
selector: { matchLabels: bb._config.selectorLabels },
|
||||
template: {
|
||||
metadata: {
|
||||
labels: bb._config.commonLabels,
|
||||
annotations: {
|
||||
'kubectl.kubernetes.io/default-container': blackboxExporter.name,
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
containers: [blackboxExporter, reloader, kubeRbacProxy],
|
||||
nodeSelector: { 'kubernetes.io/os': 'linux' },
|
||||
serviceAccountName: 'blackbox-exporter',
|
||||
volumes: [{
|
||||
name: 'config',
|
||||
configMap: { name: 'blackbox-exporter-configuration' },
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
service: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter',
|
||||
namespace: bb._config.namespace,
|
||||
labels: bb._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
ports: [{
|
||||
name: 'https',
|
||||
port: bb._config.port,
|
||||
targetPort: 'https',
|
||||
}, {
|
||||
name: 'probe',
|
||||
port: bb._config.internalPort,
|
||||
targetPort: 'http',
|
||||
}],
|
||||
selector: bb._config.selectorLabels,
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitor:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'blackbox-exporter',
|
||||
namespace: bb._config.namespace,
|
||||
labels: bb._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
endpoints: [{
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
interval: '30s',
|
||||
path: '/metrics',
|
||||
port: 'https',
|
||||
scheme: 'https',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
}],
|
||||
selector: {
|
||||
matchLabels: bb._config.selectorLabels,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
103
jsonnet/kube-prometheus/components/grafana.libsonnet
Normal file
103
jsonnet/kube-prometheus/components/grafana.libsonnet
Normal file
@@ -0,0 +1,103 @@
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
name: 'grafana',
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
// image: error 'must provide image',
|
||||
imageRepos: 'grafana/grafana',
|
||||
resources: {
|
||||
requests: { cpu: '100m', memory: '100Mi' },
|
||||
limits: { cpu: '200m', memory: '200Mi' },
|
||||
},
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': defaults.name,
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'grafana',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
prometheusName: error 'must provide prometheus name',
|
||||
dashboards: {},
|
||||
// TODO(paulfantom): expose those to have a stable API. After kubernetes-grafana refactor those could probably be removed.
|
||||
rawDashboards: {},
|
||||
folderDashboards: {},
|
||||
containers: [],
|
||||
datasources: [],
|
||||
config: {},
|
||||
plugins: [],
|
||||
};
|
||||
|
||||
function(params) {
|
||||
local g = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(g._config.resources),
|
||||
|
||||
local glib = (import 'github.com/brancz/kubernetes-grafana/grafana/grafana.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: g._config.namespace,
|
||||
versions+:: {
|
||||
grafana: g._config.version,
|
||||
},
|
||||
imageRepos+:: {
|
||||
grafana: g._config.imageRepos,
|
||||
},
|
||||
prometheus+:: {
|
||||
name: g._config.prometheusName,
|
||||
},
|
||||
grafana+:: {
|
||||
labels: g._config.commonLabels,
|
||||
dashboards: g._config.dashboards,
|
||||
resources: g._config.resources,
|
||||
rawDashboards: g._config.rawDashboards,
|
||||
folderDashboards: g._config.folderDashboards,
|
||||
containers: g._config.containers,
|
||||
config+: g._config.config,
|
||||
plugins+: g._config.plugins,
|
||||
} + (
|
||||
// Conditionally overwrite default setting.
|
||||
if std.length(g._config.datasources) > 0 then
|
||||
{ datasources: g._config.datasources }
|
||||
else {}
|
||||
),
|
||||
},
|
||||
},
|
||||
|
||||
// Add object only if user passes config and config is not empty
|
||||
[if std.objectHas(params, 'config') && std.length(params.config) > 0 then 'config']: glib.grafana.config,
|
||||
service: glib.grafana.service,
|
||||
serviceAccount: glib.grafana.serviceAccount,
|
||||
deployment: glib.grafana.deployment,
|
||||
dashboardDatasources: glib.grafana.dashboardDatasources,
|
||||
dashboardSources: glib.grafana.dashboardSources,
|
||||
|
||||
dashboardDefinitions: if std.length(g._config.dashboards) > 0 then {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ConfigMapList',
|
||||
items: glib.grafana.dashboardDefinitions,
|
||||
},
|
||||
serviceMonitor: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'grafana',
|
||||
namespace: g._config.namespace,
|
||||
labels: g._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'app.kubernetes.io/name': 'grafana',
|
||||
},
|
||||
},
|
||||
endpoints: [{
|
||||
port: 'http',
|
||||
interval: '15s',
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
262
jsonnet/kube-prometheus/components/k8s-control-plane.libsonnet
Normal file
262
jsonnet/kube-prometheus/components/k8s-control-plane.libsonnet
Normal file
@@ -0,0 +1,262 @@
|
||||
local relabelings = import '../addons/dropping-deprecated-metrics-relabelings.libsonnet';
|
||||
|
||||
local defaults = {
|
||||
namespace: error 'must provide namespace',
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': 'kube-prometheus',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
mixin: {
|
||||
ruleLabels: {},
|
||||
_config: {
|
||||
cadvisorSelector: 'job="kubelet", metrics_path="/metrics/cadvisor"',
|
||||
kubeletSelector: 'job="kubelet", metrics_path="/metrics"',
|
||||
kubeStateMetricsSelector: 'job="kube-state-metrics"',
|
||||
nodeExporterSelector: 'job="node-exporter"',
|
||||
kubeSchedulerSelector: 'job="kube-scheduler"',
|
||||
kubeControllerManagerSelector: 'job="kube-controller-manager"',
|
||||
kubeApiserverSelector: 'job="apiserver"',
|
||||
podLabel: 'pod',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
diskDeviceSelector: 'device=~"mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|dasd.+"',
|
||||
hostNetworkInterfaceSelector: 'device!~"veth.+"',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function(params) {
|
||||
local k8s = self,
|
||||
_config:: defaults + params,
|
||||
|
||||
mixin:: (import 'github.com/kubernetes-monitoring/kubernetes-mixin/mixin.libsonnet') {
|
||||
_config+:: k8s._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: k8s._config.commonLabels + k8s._config.mixin.ruleLabels,
|
||||
name: 'kubernetes-monitoring-rules',
|
||||
namespace: k8s._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(k8s.mixin, 'prometheusRules') then k8s.mixin.prometheusRules.groups else {},
|
||||
local a = if std.objectHasAll(k8s.mixin, 'prometheusAlerts') then k8s.mixin.prometheusAlerts.groups else {},
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitorKubeScheduler: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-scheduler',
|
||||
namespace: k8s._config.namespace,
|
||||
labels: { 'app.kubernetes.io/name': 'kube-scheduler' },
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
endpoints: [{
|
||||
port: 'https-metrics',
|
||||
interval: '30s',
|
||||
scheme: 'https',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: { insecureSkipVerify: true },
|
||||
}],
|
||||
selector: {
|
||||
matchLabels: { 'app.kubernetes.io/name': 'kube-scheduler' },
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: ['kube-system'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitorKubelet: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kubelet',
|
||||
namespace: k8s._config.namespace,
|
||||
labels: { 'app.kubernetes.io/name': 'kubelet' },
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https-metrics',
|
||||
scheme: 'https',
|
||||
interval: '30s',
|
||||
honorLabels: true,
|
||||
tlsConfig: { insecureSkipVerify: true },
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
metricRelabelings: relabelings,
|
||||
relabelings: [{
|
||||
sourceLabels: ['__metrics_path__'],
|
||||
targetLabel: 'metrics_path',
|
||||
}],
|
||||
},
|
||||
{
|
||||
port: 'https-metrics',
|
||||
scheme: 'https',
|
||||
path: '/metrics/cadvisor',
|
||||
interval: '30s',
|
||||
honorLabels: true,
|
||||
honorTimestamps: false,
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
relabelings: [{
|
||||
sourceLabels: ['__metrics_path__'],
|
||||
targetLabel: 'metrics_path',
|
||||
}],
|
||||
metricRelabelings: [
|
||||
// Drop a bunch of metrics which are disabled but still sent, see
|
||||
// https://github.com/google/cadvisor/issues/1925.
|
||||
{
|
||||
sourceLabels: ['__name__'],
|
||||
regex: 'container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)',
|
||||
action: 'drop',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
port: 'https-metrics',
|
||||
scheme: 'https',
|
||||
path: '/metrics/probes',
|
||||
interval: '30s',
|
||||
honorLabels: true,
|
||||
tlsConfig: { insecureSkipVerify: true },
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
relabelings: [{
|
||||
sourceLabels: ['__metrics_path__'],
|
||||
targetLabel: 'metrics_path',
|
||||
}],
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
matchLabels: { 'app.kubernetes.io/name': 'kubelet' },
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: ['kube-system'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitorKubeControllerManager: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-controller-manager',
|
||||
namespace: k8s._config.namespace,
|
||||
labels: { 'app.kubernetes.io/name': 'kube-controller-manager' },
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
endpoints: [{
|
||||
port: 'https-metrics',
|
||||
interval: '30s',
|
||||
scheme: 'https',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
metricRelabelings: relabelings + [
|
||||
{
|
||||
sourceLabels: ['__name__'],
|
||||
regex: 'etcd_(debugging|disk|request|server).*',
|
||||
action: 'drop',
|
||||
},
|
||||
],
|
||||
}],
|
||||
selector: {
|
||||
matchLabels: { 'app.kubernetes.io/name': 'kube-controller-manager' },
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: ['kube-system'],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitorApiserver: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-apiserver',
|
||||
namespace: k8s._config.namespace,
|
||||
labels: { 'app.kubernetes.io/name': 'apiserver' },
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'component',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
component: 'apiserver',
|
||||
provider: 'kubernetes',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: ['default'],
|
||||
},
|
||||
endpoints: [{
|
||||
port: 'https',
|
||||
interval: '30s',
|
||||
scheme: 'https',
|
||||
tlsConfig: {
|
||||
caFile: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt',
|
||||
serverName: 'kubernetes',
|
||||
},
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
metricRelabelings: relabelings + [
|
||||
{
|
||||
sourceLabels: ['__name__'],
|
||||
regex: 'etcd_(debugging|disk|server).*',
|
||||
action: 'drop',
|
||||
},
|
||||
{
|
||||
sourceLabels: ['__name__'],
|
||||
regex: 'apiserver_admission_controller_admission_latencies_seconds_.*',
|
||||
action: 'drop',
|
||||
},
|
||||
{
|
||||
sourceLabels: ['__name__'],
|
||||
regex: 'apiserver_admission_step_admission_latencies_seconds_.*',
|
||||
action: 'drop',
|
||||
},
|
||||
{
|
||||
sourceLabels: ['__name__', 'le'],
|
||||
regex: 'apiserver_request_duration_seconds_bucket;(0.15|0.25|0.3|0.35|0.4|0.45|0.6|0.7|0.8|0.9|1.25|1.5|1.75|2.5|3|3.5|4.5|6|7|8|9|15|25|30|50)',
|
||||
action: 'drop',
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitorCoreDNS: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'coredns',
|
||||
namespace: k8s._config.namespace,
|
||||
labels: { 'app.kubernetes.io/name': 'coredns' },
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
selector: {
|
||||
matchLabels: { 'app.kubernetes.io/name': 'kube-dns' },
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: ['kube-system'],
|
||||
},
|
||||
endpoints: [{
|
||||
port: 'metrics',
|
||||
interval: '15s',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
63
jsonnet/kube-prometheus/components/kube-rbac-proxy.libsonnet
Normal file
63
jsonnet/kube-prometheus/components/kube-rbac-proxy.libsonnet
Normal file
@@ -0,0 +1,63 @@
|
||||
local defaults = {
|
||||
namespace: error 'must provide namespace',
|
||||
image: 'quay.io/brancz/kube-rbac-proxy:v0.8.0',
|
||||
ports: error 'must provide ports',
|
||||
secureListenAddress: error 'must provide secureListenAddress',
|
||||
upstream: error 'must provide upstream',
|
||||
resources: {
|
||||
requests: { cpu: '10m', memory: '20Mi' },
|
||||
limits: { cpu: '20m', memory: '40Mi' },
|
||||
},
|
||||
tlsCipherSuites: [
|
||||
'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256', // required by h2: http://golang.org/cl/30721
|
||||
'TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256', // required by h2: http://golang.org/cl/30721
|
||||
|
||||
// 'TLS_RSA_WITH_RC4_128_SHA', // insecure: https://access.redhat.com/security/cve/cve-2013-2566
|
||||
// 'TLS_RSA_WITH_3DES_EDE_CBC_SHA', // insecure: https://access.redhat.com/articles/2548661
|
||||
// 'TLS_RSA_WITH_AES_128_CBC_SHA', // disabled by h2
|
||||
// 'TLS_RSA_WITH_AES_256_CBC_SHA', // disabled by h2
|
||||
// 'TLS_RSA_WITH_AES_128_CBC_SHA256', // insecure: https://access.redhat.com/security/cve/cve-2013-0169
|
||||
// 'TLS_RSA_WITH_AES_128_GCM_SHA256', // disabled by h2
|
||||
// 'TLS_RSA_WITH_AES_256_GCM_SHA384', // disabled by h2
|
||||
// 'TLS_ECDHE_ECDSA_WITH_RC4_128_SHA', // insecure: https://access.redhat.com/security/cve/cve-2013-2566
|
||||
// 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA', // disabled by h2
|
||||
// 'TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA', // disabled by h2
|
||||
// 'TLS_ECDHE_RSA_WITH_RC4_128_SHA', // insecure: https://access.redhat.com/security/cve/cve-2013-2566
|
||||
// 'TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA', // insecure: https://access.redhat.com/articles/2548661
|
||||
// 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA', // disabled by h2
|
||||
// 'TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA', // disabled by h2
|
||||
// 'TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256', // insecure: https://access.redhat.com/security/cve/cve-2013-0169
|
||||
// 'TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256', // insecure: https://access.redhat.com/security/cve/cve-2013-0169
|
||||
|
||||
// disabled by h2 means: https://github.com/golang/net/blob/e514e69ffb8bc3c76a71ae40de0118d794855992/http2/ciphers.go
|
||||
|
||||
'TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384',
|
||||
'TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384',
|
||||
'TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305',
|
||||
'TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305',
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
function(params) {
|
||||
local krp = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(krp._config.resources),
|
||||
|
||||
name: krp._config.name,
|
||||
image: krp._config.image,
|
||||
args: [
|
||||
'--logtostderr',
|
||||
'--secure-listen-address=' + krp._config.secureListenAddress,
|
||||
'--tls-cipher-suites=' + std.join(',', krp._config.tlsCipherSuites),
|
||||
'--upstream=' + krp._config.upstream,
|
||||
],
|
||||
resources: krp._config.resources,
|
||||
ports: krp._config.ports,
|
||||
securityContext: {
|
||||
runAsUser: 65532,
|
||||
runAsGroup: 65532,
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
}
|
||||
171
jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet
Normal file
171
jsonnet/kube-prometheus/components/kube-state-metrics.libsonnet
Normal file
@@ -0,0 +1,171 @@
|
||||
local krp = import './kube-rbac-proxy.libsonnet';
|
||||
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
name: 'kube-state-metrics',
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
image: error 'must provide version',
|
||||
resources: {
|
||||
requests: { cpu: '10m', memory: '190Mi' },
|
||||
limits: { cpu: '100m', memory: '250Mi' },
|
||||
},
|
||||
|
||||
scrapeInterval: '30s',
|
||||
scrapeTimeout: '30s',
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': defaults.name,
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'exporter',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
mixin: {
|
||||
ruleLabels: {},
|
||||
_config: {
|
||||
kubeStateMetricsSelector: 'job="' + defaults.name + '"',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function(params) (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics/kube-state-metrics.libsonnet') {
|
||||
local ksm = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(ksm._config.resources),
|
||||
assert std.isObject(ksm._config.mixin._config),
|
||||
|
||||
name:: ksm._config.name,
|
||||
namespace:: ksm._config.namespace,
|
||||
version:: ksm._config.version,
|
||||
image:: ksm._config.image,
|
||||
commonLabels:: ksm._config.commonLabels,
|
||||
podLabels:: ksm._config.selectorLabels,
|
||||
|
||||
mixin:: (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics-mixin/mixin.libsonnet') +
|
||||
(import 'github.com/kubernetes-monitoring/kubernetes-mixin/alerts/add-runbook-links.libsonnet') {
|
||||
_config+:: ksm._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: ksm._config.commonLabels + ksm._config.mixin.ruleLabels,
|
||||
name: ksm._config.name + '-rules',
|
||||
namespace: ksm._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(ksm.mixin, 'prometheusRules') then ksm.mixin.prometheusRules.groups else [],
|
||||
local a = if std.objectHasAll(ksm.mixin, 'prometheusAlerts') then ksm.mixin.prometheusAlerts.groups else [],
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
|
||||
service+: {
|
||||
spec+: {
|
||||
ports: [
|
||||
{
|
||||
name: 'https-main',
|
||||
port: 8443,
|
||||
targetPort: 'https-main',
|
||||
},
|
||||
{
|
||||
name: 'https-self',
|
||||
port: 9443,
|
||||
targetPort: 'https-self',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
local kubeRbacProxyMain = krp({
|
||||
name: 'kube-rbac-proxy-main',
|
||||
upstream: 'http://127.0.0.1:8081/',
|
||||
secureListenAddress: ':8443',
|
||||
ports: [
|
||||
{ name: 'https-main', containerPort: 8443 },
|
||||
],
|
||||
resources+: {
|
||||
limits+: { cpu: '40m' },
|
||||
requests+: { cpu: '20m' },
|
||||
},
|
||||
}),
|
||||
|
||||
local kubeRbacProxySelf = krp({
|
||||
name: 'kube-rbac-proxy-self',
|
||||
upstream: 'http://127.0.0.1:8082/',
|
||||
secureListenAddress: ':9443',
|
||||
ports: [
|
||||
{ name: 'https-self', containerPort: 9443 },
|
||||
],
|
||||
}),
|
||||
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
metadata+: {
|
||||
annotations+: {
|
||||
'kubectl.kubernetes.io/default-container': 'kube-state-metrics',
|
||||
},
|
||||
},
|
||||
spec+: {
|
||||
containers: std.map(function(c) c {
|
||||
ports:: null,
|
||||
livenessProbe:: null,
|
||||
readinessProbe:: null,
|
||||
args: ['--host=127.0.0.1', '--port=8081', '--telemetry-host=127.0.0.1', '--telemetry-port=8082'],
|
||||
resources: ksm._config.resources,
|
||||
}, super.containers) + [kubeRbacProxyMain, kubeRbacProxySelf],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceMonitor:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: ksm.name,
|
||||
namespace: ksm._config.namespace,
|
||||
labels: ksm._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
selector: { matchLabels: ksm._config.selectorLabels },
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https-main',
|
||||
scheme: 'https',
|
||||
interval: ksm._config.scrapeInterval,
|
||||
scrapeTimeout: ksm._config.scrapeTimeout,
|
||||
honorLabels: true,
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
relabelings: [
|
||||
{
|
||||
regex: '(pod|service|endpoint|namespace)',
|
||||
action: 'labeldrop',
|
||||
},
|
||||
],
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
port: 'https-self',
|
||||
scheme: 'https',
|
||||
interval: ksm._config.scrapeInterval,
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -7,7 +7,8 @@
|
||||
{
|
||||
alert: 'TargetDown',
|
||||
annotations: {
|
||||
message: '{{ printf "%.4g" $value }}% of the {{ $labels.job }}/{{ $labels.service }} targets in {{ $labels.namespace }} namespace are down.',
|
||||
summary: 'One or more targets are unreachable.',
|
||||
description: '{{ printf "%.4g" $value }}% of the {{ $labels.job }}/{{ $labels.service }} targets in {{ $labels.namespace }} namespace are down.',
|
||||
},
|
||||
expr: '100 * (count(up == 0) BY (job, namespace, service) / count(up) BY (job, namespace, service)) > 10',
|
||||
'for': '10m',
|
||||
@@ -18,7 +19,8 @@
|
||||
{
|
||||
alert: 'Watchdog',
|
||||
annotations: {
|
||||
message: |||
|
||||
summary: 'An alert that should always be firing to certify that Alertmanager is working properly.',
|
||||
description: |||
|
||||
This is an alert meant to ensure that the entire alerting pipeline is functional.
|
||||
This alert is always firing, therefore it should always be firing in Alertmanager
|
||||
and always fire against a receiver. There are integrations with various notification
|
||||
@@ -7,7 +7,7 @@
|
||||
{
|
||||
alert: 'NodeNetworkInterfaceFlapping',
|
||||
annotations: {
|
||||
message: 'Network interface "{{ $labels.device }}" changing it\'s up status often on node-exporter {{ $labels.namespace }}/{{ $labels.pod }}"',
|
||||
message: 'Network interface "{{ $labels.device }}" changing it\'s up status often on node-exporter {{ $labels.namespace }}/{{ $labels.pod }}',
|
||||
},
|
||||
expr: |||
|
||||
changes(node_network_up{%(nodeExporterSelector)s,%(hostNetworkInterfaceSelector)s}[2m]) > 2
|
||||
44
jsonnet/kube-prometheus/components/mixin/custom.libsonnet
Normal file
44
jsonnet/kube-prometheus/components/mixin/custom.libsonnet
Normal file
@@ -0,0 +1,44 @@
|
||||
local defaults = {
|
||||
name: 'kube-prometheus',
|
||||
namespace: error 'must provide namespace',
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': 'kube-prometheus',
|
||||
'app.kubernetes.io/component': 'exporter',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
mixin: {
|
||||
ruleLabels: {},
|
||||
_config: {
|
||||
nodeExporterSelector: 'job="node-exporter"',
|
||||
hostNetworkInterfaceSelector: 'device!~"veth.+"',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function(params) {
|
||||
local m = self,
|
||||
_config:: defaults + params,
|
||||
|
||||
local alertsandrules = (import './alerts/alerts.libsonnet') + (import './rules/rules.libsonnet'),
|
||||
|
||||
mixin:: alertsandrules +
|
||||
(import 'github.com/kubernetes-monitoring/kubernetes-mixin/alerts/add-runbook-links.libsonnet') {
|
||||
_config+:: m._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: m._config.commonLabels + m._config.mixin.ruleLabels,
|
||||
name: m._config.name + '-rules',
|
||||
namespace: m._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(m.mixin, 'prometheusRules') then m.mixin.prometheusRules.groups else [],
|
||||
local a = if std.objectHasAll(m.mixin, 'prometheusAlerts') then m.mixin.prometheusAlerts.groups else [],
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
}
|
||||
248
jsonnet/kube-prometheus/components/node-exporter.libsonnet
Normal file
248
jsonnet/kube-prometheus/components/node-exporter.libsonnet
Normal file
@@ -0,0 +1,248 @@
|
||||
local krp = import './kube-rbac-proxy.libsonnet';
|
||||
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
name: 'node-exporter',
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
image: error 'must provide version',
|
||||
resources: {
|
||||
requests: { cpu: '102m', memory: '180Mi' },
|
||||
limits: { cpu: '250m', memory: '180Mi' },
|
||||
},
|
||||
listenAddress: '127.0.0.1',
|
||||
port: 9100,
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': defaults.name,
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'exporter',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
mixin: {
|
||||
ruleLabels: {},
|
||||
_config: {
|
||||
nodeExporterSelector: 'job="' + defaults.name + '"',
|
||||
fsSpaceFillingUpCriticalThreshold: 15,
|
||||
diskDeviceSelector: 'device=~"mmcblk.p.+|nvme.+|rbd.+|sd.+|vd.+|xvd.+|dm-.+|dasd.+"',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
function(params) {
|
||||
local ne = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(ne._config.resources),
|
||||
assert std.isObject(ne._config.mixin._config),
|
||||
|
||||
mixin:: (import 'github.com/prometheus/node_exporter/docs/node-mixin/mixin.libsonnet') +
|
||||
(import 'github.com/kubernetes-monitoring/kubernetes-mixin/alerts/add-runbook-links.libsonnet') {
|
||||
_config+:: ne._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: ne._config.commonLabels + ne._config.mixin.ruleLabels,
|
||||
name: ne._config.name + '-rules',
|
||||
namespace: ne._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(ne.mixin, 'prometheusRules') then ne.mixin.prometheusRules.groups else [],
|
||||
local a = if std.objectHasAll(ne.mixin, 'prometheusAlerts') then ne.mixin.prometheusAlerts.groups else [],
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
|
||||
clusterRoleBinding: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRoleBinding',
|
||||
metadata: {
|
||||
name: ne._config.name,
|
||||
labels: ne._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'ClusterRole',
|
||||
name: ne._config.name,
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: ne._config.name,
|
||||
namespace: ne._config.namespace,
|
||||
}],
|
||||
},
|
||||
|
||||
clusterRole: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
metadata: {
|
||||
name: ne._config.name,
|
||||
labels: ne._config.commonLabels,
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
apiGroups: ['authentication.k8s.io'],
|
||||
resources: ['tokenreviews'],
|
||||
verbs: ['create'],
|
||||
},
|
||||
{
|
||||
apiGroups: ['authorization.k8s.io'],
|
||||
resources: ['subjectaccessreviews'],
|
||||
verbs: ['create'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
serviceAccount: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: ne._config.name,
|
||||
namespace: ne._config.namespace,
|
||||
labels: ne._config.commonLabels,
|
||||
},
|
||||
},
|
||||
|
||||
service: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: ne._config.name,
|
||||
namespace: ne._config.namespace,
|
||||
labels: ne._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'https', targetPort: 'https', port: ne._config.port },
|
||||
],
|
||||
selector: ne._config.selectorLabels,
|
||||
clusterIP: 'None',
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitor: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: ne._config.name,
|
||||
namespace: ne._config.namespace,
|
||||
labels: ne._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'app.kubernetes.io/name',
|
||||
selector: {
|
||||
matchLabels: ne._config.selectorLabels,
|
||||
},
|
||||
endpoints: [{
|
||||
port: 'https',
|
||||
scheme: 'https',
|
||||
interval: '15s',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
relabelings: [
|
||||
{
|
||||
action: 'replace',
|
||||
regex: '(.*)',
|
||||
replacement: '$1',
|
||||
sourceLabels: ['__meta_kubernetes_pod_node_name'],
|
||||
targetLabel: 'instance',
|
||||
},
|
||||
],
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
daemonset:
|
||||
local nodeExporter = {
|
||||
name: ne._config.name,
|
||||
image: ne._config.image,
|
||||
args: [
|
||||
'--web.listen-address=' + std.join(':', [ne._config.listenAddress, std.toString(ne._config.port)]),
|
||||
'--path.sysfs=/host/sys',
|
||||
'--path.rootfs=/host/root',
|
||||
'--no-collector.wifi',
|
||||
'--no-collector.hwmon',
|
||||
'--collector.filesystem.ignored-mount-points=^/(dev|proc|sys|var/lib/docker/.+|var/lib/kubelet/pods/.+)($|/)',
|
||||
'--collector.netclass.ignored-devices=^(veth.*)$',
|
||||
'--collector.netdev.device-exclude=^(veth.*)$',
|
||||
],
|
||||
volumeMounts: [
|
||||
{ name: 'sys', mountPath: '/host/sys', mountPropagation: 'HostToContainer', readOnly: true },
|
||||
{ name: 'root', mountPath: '/host/root', mountPropagation: 'HostToContainer', readOnly: true },
|
||||
],
|
||||
resources: ne._config.resources,
|
||||
};
|
||||
|
||||
local kubeRbacProxy = krp({
|
||||
name: 'kube-rbac-proxy',
|
||||
//image: krpImage,
|
||||
upstream: 'http://127.0.0.1:' + ne._config.port + '/',
|
||||
secureListenAddress: '[$(IP)]:' + ne._config.port,
|
||||
// Keep `hostPort` here, rather than in the node-exporter container
|
||||
// because Kubernetes mandates that if you define a `hostPort` then
|
||||
// `containerPort` must match. In our case, we are splitting the
|
||||
// host port and container port between the two containers.
|
||||
// We'll keep the port specification here so that the named port
|
||||
// used by the service is tied to the proxy container. We *could*
|
||||
// forgo declaring the host port, however it is important to declare
|
||||
// it so that the scheduler can decide if the pod is schedulable.
|
||||
ports: [
|
||||
{ name: 'https', containerPort: ne._config.port, hostPort: ne._config.port },
|
||||
],
|
||||
}) + {
|
||||
env: [
|
||||
{ name: 'IP', valueFrom: { fieldRef: { fieldPath: 'status.podIP' } } },
|
||||
],
|
||||
};
|
||||
|
||||
{
|
||||
apiVersion: 'apps/v1',
|
||||
kind: 'DaemonSet',
|
||||
metadata: {
|
||||
name: ne._config.name,
|
||||
namespace: ne._config.namespace,
|
||||
labels: ne._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
selector: { matchLabels: ne._config.selectorLabels },
|
||||
updateStrategy: {
|
||||
type: 'RollingUpdate',
|
||||
rollingUpdate: { maxUnavailable: '10%' },
|
||||
},
|
||||
template: {
|
||||
metadata: { labels: ne._config.commonLabels },
|
||||
spec: {
|
||||
nodeSelector: { 'kubernetes.io/os': 'linux' },
|
||||
tolerations: [{
|
||||
operator: 'Exists',
|
||||
}],
|
||||
containers: [nodeExporter, kubeRbacProxy],
|
||||
volumes: [
|
||||
{ name: 'sys', hostPath: { path: '/sys' } },
|
||||
{ name: 'root', hostPath: { path: '/' } },
|
||||
],
|
||||
serviceAccountName: ne._config.name,
|
||||
securityContext: {
|
||||
runAsUser: 65534,
|
||||
runAsNonRoot: true,
|
||||
},
|
||||
hostPID: true,
|
||||
hostNetwork: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
303
jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet
Normal file
303
jsonnet/kube-prometheus/components/prometheus-adapter.libsonnet
Normal file
@@ -0,0 +1,303 @@
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
name: 'prometheus-adapter',
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
image: error 'must provide image',
|
||||
resources: {
|
||||
requests: { cpu: '102m', memory: '180Mi' },
|
||||
limits: { cpu: '250m', memory: '180Mi' },
|
||||
},
|
||||
replicas: 2,
|
||||
listenAddress: '127.0.0.1',
|
||||
port: 9100,
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': 'prometheus-adapter',
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'metrics-adapter',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
|
||||
prometheusURL: error 'must provide prometheusURL',
|
||||
config: {
|
||||
resourceRules: {
|
||||
cpu: {
|
||||
containerQuery: 'sum(irate(container_cpu_usage_seconds_total{<<.LabelMatchers>>,container!="",pod!=""}[5m])) by (<<.GroupBy>>)',
|
||||
nodeQuery: 'sum(1 - irate(node_cpu_seconds_total{mode="idle"}[5m]) * on(namespace, pod) group_left(node) node_namespace_pod:kube_pod_info:{<<.LabelMatchers>>}) by (<<.GroupBy>>) or sum (1- irate(windows_cpu_time_total{mode="idle", job="windows-exporter",<<.LabelMatchers>>}[5m])) by (<<.GroupBy>>)',
|
||||
resources: {
|
||||
overrides: {
|
||||
node: { resource: 'node' },
|
||||
namespace: { resource: 'namespace' },
|
||||
pod: { resource: 'pod' },
|
||||
},
|
||||
},
|
||||
containerLabel: 'container',
|
||||
},
|
||||
memory: {
|
||||
containerQuery: 'sum(container_memory_working_set_bytes{<<.LabelMatchers>>,container!="",pod!=""}) by (<<.GroupBy>>)',
|
||||
nodeQuery: 'sum(node_memory_MemTotal_bytes{job="node-exporter",<<.LabelMatchers>>} - node_memory_MemAvailable_bytes{job="node-exporter",<<.LabelMatchers>>}) by (<<.GroupBy>>) or sum(windows_cs_physical_memory_bytes{job="windows-exporter",<<.LabelMatchers>>} - windows_memory_available_bytes{job="windows-exporter",<<.LabelMatchers>>}) by (<<.GroupBy>>)',
|
||||
resources: {
|
||||
overrides: {
|
||||
instance: { resource: 'node' },
|
||||
namespace: { resource: 'namespace' },
|
||||
pod: { resource: 'pod' },
|
||||
},
|
||||
},
|
||||
containerLabel: 'container',
|
||||
},
|
||||
window: '5m',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function(params) {
|
||||
local pa = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(pa._config.resources),
|
||||
|
||||
apiService: {
|
||||
apiVersion: 'apiregistration.k8s.io/v1',
|
||||
kind: 'APIService',
|
||||
metadata: {
|
||||
name: 'v1beta1.metrics.k8s.io',
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
service: {
|
||||
name: $.service.metadata.name,
|
||||
namespace: pa._config.namespace,
|
||||
},
|
||||
group: 'metrics.k8s.io',
|
||||
version: 'v1beta1',
|
||||
insecureSkipTLSVerify: true,
|
||||
groupPriorityMinimum: 100,
|
||||
versionPriority: 100,
|
||||
},
|
||||
},
|
||||
|
||||
configMap: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ConfigMap',
|
||||
metadata: {
|
||||
name: 'adapter-config',
|
||||
namespace: pa._config.namespace,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
data: { 'config.yaml': std.manifestYamlDoc(pa._config.config) },
|
||||
},
|
||||
|
||||
serviceMonitor: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: pa._config.name,
|
||||
namespace: pa._config.namespace,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: pa._config.selectorLabels,
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https',
|
||||
interval: '30s',
|
||||
scheme: 'https',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
service: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: pa._config.name,
|
||||
namespace: pa._config.namespace,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'https', targetPort: 6443, port: 443 },
|
||||
],
|
||||
selector: pa._config.selectorLabels,
|
||||
},
|
||||
},
|
||||
|
||||
deployment:
|
||||
local c = {
|
||||
name: pa._config.name,
|
||||
image: pa._config.image,
|
||||
args: [
|
||||
'--cert-dir=/var/run/serving-cert',
|
||||
'--config=/etc/adapter/config.yaml',
|
||||
'--logtostderr=true',
|
||||
'--metrics-relist-interval=1m',
|
||||
'--prometheus-url=' + pa._config.prometheusURL,
|
||||
'--secure-port=6443',
|
||||
],
|
||||
ports: [{ containerPort: 6443 }],
|
||||
volumeMounts: [
|
||||
{ name: 'tmpfs', mountPath: '/tmp', readOnly: false },
|
||||
{ name: 'volume-serving-cert', mountPath: '/var/run/serving-cert', readOnly: false },
|
||||
{ name: 'config', mountPath: '/etc/adapter', readOnly: false },
|
||||
],
|
||||
};
|
||||
|
||||
{
|
||||
apiVersion: 'apps/v1',
|
||||
kind: 'Deployment',
|
||||
metadata: {
|
||||
name: pa._config.name,
|
||||
namespace: pa._config.namespace,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
replicas: pa._config.replicas,
|
||||
selector: { matchLabels: pa._config.selectorLabels },
|
||||
strategy: {
|
||||
rollingUpdate: {
|
||||
maxSurge: 1,
|
||||
maxUnavailable: 1,
|
||||
},
|
||||
},
|
||||
template: {
|
||||
metadata: { labels: pa._config.commonLabels },
|
||||
spec: {
|
||||
containers: [c],
|
||||
serviceAccountName: $.serviceAccount.metadata.name,
|
||||
nodeSelector: { 'kubernetes.io/os': 'linux' },
|
||||
volumes: [
|
||||
{ name: 'tmpfs', emptyDir: {} },
|
||||
{ name: 'volume-serving-cert', emptyDir: {} },
|
||||
{ name: 'config', configMap: { name: 'adapter-config' } },
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
serviceAccount: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: pa._config.name,
|
||||
namespace: pa._config.namespace,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
},
|
||||
|
||||
clusterRole: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
metadata: {
|
||||
name: pa._config.name,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
rules: [{
|
||||
apiGroups: [''],
|
||||
resources: ['nodes', 'namespaces', 'pods', 'services'],
|
||||
verbs: ['get', 'list', 'watch'],
|
||||
}],
|
||||
},
|
||||
|
||||
clusterRoleBinding: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRoleBinding',
|
||||
metadata: {
|
||||
name: pa._config.name,
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'ClusterRole',
|
||||
name: $.clusterRole.metadata.name,
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: $.serviceAccount.metadata.name,
|
||||
namespace: pa._config.namespace,
|
||||
}],
|
||||
},
|
||||
|
||||
clusterRoleBindingDelegator: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRoleBinding',
|
||||
metadata: {
|
||||
name: 'resource-metrics:system:auth-delegator',
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'ClusterRole',
|
||||
name: 'system:auth-delegator',
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: $.serviceAccount.metadata.name,
|
||||
namespace: pa._config.namespace,
|
||||
}],
|
||||
},
|
||||
|
||||
clusterRoleServerResources: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
metadata: {
|
||||
name: 'resource-metrics-server-resources',
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
rules: [{
|
||||
apiGroups: ['metrics.k8s.io'],
|
||||
resources: ['*'],
|
||||
verbs: ['*'],
|
||||
}],
|
||||
},
|
||||
|
||||
clusterRoleAggregatedMetricsReader: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
metadata: {
|
||||
name: 'system:aggregated-metrics-reader',
|
||||
labels: {
|
||||
'rbac.authorization.k8s.io/aggregate-to-admin': 'true',
|
||||
'rbac.authorization.k8s.io/aggregate-to-edit': 'true',
|
||||
'rbac.authorization.k8s.io/aggregate-to-view': 'true',
|
||||
} + pa._config.commonLabels,
|
||||
},
|
||||
rules: [{
|
||||
apiGroups: ['metrics.k8s.io'],
|
||||
resources: ['pods', 'nodes'],
|
||||
verbs: ['get', 'list', 'watch'],
|
||||
}],
|
||||
},
|
||||
|
||||
roleBindingAuthReader: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleBinding',
|
||||
metadata: {
|
||||
name: 'resource-metrics-auth-reader',
|
||||
namespace: 'kube-system',
|
||||
labels: pa._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'Role',
|
||||
name: 'extension-apiserver-authentication-reader',
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: $.serviceAccount.metadata.name,
|
||||
namespace: pa._config.namespace,
|
||||
}],
|
||||
},
|
||||
}
|
||||
128
jsonnet/kube-prometheus/components/prometheus-operator.libsonnet
Normal file
128
jsonnet/kube-prometheus/components/prometheus-operator.libsonnet
Normal file
@@ -0,0 +1,128 @@
|
||||
local krp = import './kube-rbac-proxy.libsonnet';
|
||||
local prometheusOperator = import 'github.com/prometheus-operator/prometheus-operator/jsonnet/prometheus-operator/prometheus-operator.libsonnet';
|
||||
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
name: 'prometheus-operator',
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
image: error 'must provide image',
|
||||
configReloaderImage: error 'must provide config reloader image',
|
||||
resources: {
|
||||
limits: { cpu: '200m', memory: '200Mi' },
|
||||
requests: { cpu: '100m', memory: '100Mi' },
|
||||
},
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': defaults.name,
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'controller',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
},
|
||||
mixin: {
|
||||
ruleLabels: {
|
||||
role: 'alert-rules',
|
||||
prometheus: defaults.name,
|
||||
},
|
||||
_config: {
|
||||
prometheusOperatorSelector: 'job="prometheus-operator",namespace="' + defaults.namespace + '"',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
function(params)
|
||||
local config = defaults + params;
|
||||
// Safety check
|
||||
assert std.isObject(config.resources);
|
||||
|
||||
prometheusOperator(config) {
|
||||
local po = self,
|
||||
// declare variable as a field to allow overriding options and to have unified API across all components
|
||||
_config:: config,
|
||||
mixin:: (import 'github.com/prometheus-operator/prometheus-operator/jsonnet/mixin/mixin.libsonnet') +
|
||||
(import 'github.com/kubernetes-monitoring/kubernetes-mixin/alerts/add-runbook-links.libsonnet') {
|
||||
_config+:: po._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: po._config.commonLabels + po._config.mixin.ruleLabels,
|
||||
name: po._config.name + '-rules',
|
||||
namespace: po._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(po.mixin, 'prometheusRules') then po.mixin.prometheusRules.groups else [],
|
||||
local a = if std.objectHasAll(po.mixin, 'prometheusAlerts') then po.mixin.prometheusAlerts.groups else [],
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
|
||||
service+: {
|
||||
spec+: {
|
||||
ports: [
|
||||
{
|
||||
name: 'https',
|
||||
port: 8443,
|
||||
targetPort: 'https',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitor+: {
|
||||
spec+: {
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https',
|
||||
scheme: 'https',
|
||||
honorLabels: true,
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
clusterRole+: {
|
||||
rules+: [
|
||||
{
|
||||
apiGroups: ['authentication.k8s.io'],
|
||||
resources: ['tokenreviews'],
|
||||
verbs: ['create'],
|
||||
},
|
||||
{
|
||||
apiGroups: ['authorization.k8s.io'],
|
||||
resources: ['subjectaccessreviews'],
|
||||
verbs: ['create'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
local kubeRbacProxy = krp({
|
||||
name: 'kube-rbac-proxy',
|
||||
upstream: 'http://127.0.0.1:8080/',
|
||||
secureListenAddress: ':8443',
|
||||
ports: [
|
||||
{ name: 'https', containerPort: 8443 },
|
||||
],
|
||||
}),
|
||||
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
containers+: [kubeRbacProxy],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
376
jsonnet/kube-prometheus/components/prometheus.libsonnet
Normal file
376
jsonnet/kube-prometheus/components/prometheus.libsonnet
Normal file
@@ -0,0 +1,376 @@
|
||||
local defaults = {
|
||||
local defaults = self,
|
||||
namespace: error 'must provide namespace',
|
||||
version: error 'must provide version',
|
||||
image: error 'must provide image',
|
||||
resources: {
|
||||
requests: { memory: '400Mi' },
|
||||
},
|
||||
|
||||
name: error 'must provide name',
|
||||
alertmanagerName: error 'must provide alertmanagerName',
|
||||
namespaces: ['default', 'kube-system', defaults.namespace],
|
||||
replicas: 2,
|
||||
externalLabels: {},
|
||||
commonLabels:: {
|
||||
'app.kubernetes.io/name': 'prometheus',
|
||||
'app.kubernetes.io/version': defaults.version,
|
||||
'app.kubernetes.io/component': 'prometheus',
|
||||
'app.kubernetes.io/part-of': 'kube-prometheus',
|
||||
},
|
||||
selectorLabels:: {
|
||||
[labelName]: defaults.commonLabels[labelName]
|
||||
for labelName in std.objectFields(defaults.commonLabels)
|
||||
if !std.setMember(labelName, ['app.kubernetes.io/version'])
|
||||
} + { prometheus: defaults.name },
|
||||
ruleSelector: {
|
||||
matchLabels: defaults.mixin.ruleLabels,
|
||||
},
|
||||
mixin: {
|
||||
ruleLabels: {
|
||||
role: 'alert-rules',
|
||||
prometheus: defaults.name,
|
||||
},
|
||||
_config: {
|
||||
prometheusSelector: 'job="prometheus-' + defaults.name + '",namespace="' + defaults.namespace + '"',
|
||||
prometheusName: '{{$labels.namespace}}/{{$labels.pod}}',
|
||||
thanosSelector: 'job="thanos-sidecar"',
|
||||
runbookURLPattern: 'https://github.com/prometheus-operator/kube-prometheus/wiki/%s',
|
||||
},
|
||||
},
|
||||
thanos: {},
|
||||
};
|
||||
|
||||
|
||||
function(params) {
|
||||
local p = self,
|
||||
_config:: defaults + params,
|
||||
// Safety check
|
||||
assert std.isObject(p._config.resources),
|
||||
assert std.isObject(p._config.mixin._config),
|
||||
|
||||
mixin:: (import 'github.com/prometheus/prometheus/documentation/prometheus-mixin/mixin.libsonnet') +
|
||||
(import 'github.com/kubernetes-monitoring/kubernetes-mixin/alerts/add-runbook-links.libsonnet') + (
|
||||
if p._config.thanos != {} then
|
||||
(import 'github.com/thanos-io/thanos/mixin/alerts/sidecar.libsonnet') + {
|
||||
sidecar: {
|
||||
selector: p._config.mixin._config.thanosSelector,
|
||||
},
|
||||
}
|
||||
else {}
|
||||
) {
|
||||
_config+:: p._config.mixin._config,
|
||||
},
|
||||
|
||||
prometheusRule: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'PrometheusRule',
|
||||
metadata: {
|
||||
labels: p._config.commonLabels + p._config.mixin.ruleLabels,
|
||||
name: 'prometheus-' + p._config.name + '-prometheus-rules',
|
||||
namespace: p._config.namespace,
|
||||
},
|
||||
spec: {
|
||||
local r = if std.objectHasAll(p.mixin, 'prometheusRules') then p.mixin.prometheusRules.groups else [],
|
||||
local a = if std.objectHasAll(p.mixin, 'prometheusAlerts') then p.mixin.prometheusAlerts.groups else [],
|
||||
groups: a + r,
|
||||
},
|
||||
},
|
||||
|
||||
serviceAccount: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'ServiceAccount',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
},
|
||||
|
||||
service: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
labels: { prometheus: p._config.name } + p._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'web', targetPort: 'web', port: 9090 },
|
||||
] +
|
||||
(
|
||||
if p._config.thanos != {} then
|
||||
[{ name: 'grpc', port: 10901, targetPort: 10901 }]
|
||||
else []
|
||||
),
|
||||
selector: { app: 'prometheus' } + p._config.selectorLabels,
|
||||
sessionAffinity: 'ClientIP',
|
||||
},
|
||||
},
|
||||
|
||||
roleBindingSpecificNamespaces:
|
||||
local newSpecificRoleBinding(namespace) = {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleBinding',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'Role',
|
||||
name: 'prometheus-' + p._config.name,
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
}],
|
||||
};
|
||||
{
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleBindingList',
|
||||
items: [newSpecificRoleBinding(x) for x in p._config.namespaces],
|
||||
},
|
||||
|
||||
clusterRole: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRole',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
apiGroups: [''],
|
||||
resources: ['nodes/metrics'],
|
||||
verbs: ['get'],
|
||||
},
|
||||
{
|
||||
nonResourceURLs: ['/metrics'],
|
||||
verbs: ['get'],
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
roleConfig: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'Role',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name + '-config',
|
||||
namespace: p._config.namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
rules: [{
|
||||
apiGroups: [''],
|
||||
resources: ['configmaps'],
|
||||
verbs: ['get'],
|
||||
}],
|
||||
},
|
||||
|
||||
roleBindingConfig: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleBinding',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name + '-config',
|
||||
namespace: p._config.namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'Role',
|
||||
name: 'prometheus-' + p._config.name + '-config',
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
}],
|
||||
},
|
||||
|
||||
clusterRoleBinding: {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'ClusterRoleBinding',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
roleRef: {
|
||||
apiGroup: 'rbac.authorization.k8s.io',
|
||||
kind: 'ClusterRole',
|
||||
name: 'prometheus-' + p._config.name,
|
||||
},
|
||||
subjects: [{
|
||||
kind: 'ServiceAccount',
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
}],
|
||||
},
|
||||
|
||||
roleSpecificNamespaces:
|
||||
local newSpecificRole(namespace) = {
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'Role',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
rules: [
|
||||
{
|
||||
apiGroups: [''],
|
||||
resources: ['services', 'endpoints', 'pods'],
|
||||
verbs: ['get', 'list', 'watch'],
|
||||
},
|
||||
{
|
||||
apiGroups: ['extensions'],
|
||||
resources: ['ingresses'],
|
||||
verbs: ['get', 'list', 'watch'],
|
||||
},
|
||||
{
|
||||
apiGroups: ['networking.k8s.io'],
|
||||
resources: ['ingresses'],
|
||||
verbs: ['get', 'list', 'watch'],
|
||||
},
|
||||
],
|
||||
};
|
||||
{
|
||||
apiVersion: 'rbac.authorization.k8s.io/v1',
|
||||
kind: 'RoleList',
|
||||
items: [newSpecificRole(x) for x in p._config.namespaces],
|
||||
},
|
||||
|
||||
[if (defaults + params).replicas > 1 then 'podDisruptionBudget']: {
|
||||
apiVersion: 'policy/v1beta1',
|
||||
kind: 'PodDisruptionBudget',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
minAvailable: 1,
|
||||
selector: {
|
||||
matchLabels: {
|
||||
prometheus: p._config.name,
|
||||
} + p._config.selectorLabels,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
prometheus: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'Prometheus',
|
||||
metadata: {
|
||||
name: p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
labels: { prometheus: p._config.name } + p._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
replicas: p._config.replicas,
|
||||
version: p._config.version,
|
||||
image: p._config.image,
|
||||
podMetadata: {
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
externalLabels: p._config.externalLabels,
|
||||
serviceAccountName: 'prometheus-' + p._config.name,
|
||||
serviceMonitorSelector: {},
|
||||
podMonitorSelector: {},
|
||||
probeSelector: {},
|
||||
serviceMonitorNamespaceSelector: {},
|
||||
podMonitorNamespaceSelector: {},
|
||||
probeNamespaceSelector: {},
|
||||
nodeSelector: { 'kubernetes.io/os': 'linux' },
|
||||
ruleSelector: p._config.ruleSelector,
|
||||
resources: p._config.resources,
|
||||
alerting: {
|
||||
alertmanagers: [{
|
||||
namespace: p._config.namespace,
|
||||
name: 'alertmanager-' + p._config.alertmanagerName,
|
||||
port: 'web',
|
||||
apiVersion: 'v2',
|
||||
}],
|
||||
},
|
||||
securityContext: {
|
||||
runAsUser: 1000,
|
||||
runAsNonRoot: true,
|
||||
fsGroup: 2000,
|
||||
},
|
||||
[if std.objectHas(params, 'thanos') then 'thanos']: p._config.thanos,
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitor: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'prometheus-' + p._config.name,
|
||||
namespace: p._config.namespace,
|
||||
labels: p._config.commonLabels,
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: p._config.selectorLabels,
|
||||
},
|
||||
endpoints: [{
|
||||
port: 'web',
|
||||
interval: '30s',
|
||||
}],
|
||||
},
|
||||
},
|
||||
|
||||
// Include thanos sidecar Service only if thanos config was passed by user
|
||||
[if std.objectHas(params, 'thanos') && std.length(params.thanos) > 0 then 'serviceThanosSidecar']: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata+: {
|
||||
name: 'prometheus-' + p._config.name + '-thanos-sidecar',
|
||||
namespace: p._config.namespace,
|
||||
labels+: p._config.commonLabels {
|
||||
prometheus: p._config.name,
|
||||
'app.kubernetes.io/component': 'thanos-sidecar',
|
||||
},
|
||||
},
|
||||
spec+: {
|
||||
ports: [
|
||||
{ name: 'grpc', port: 10901, targetPort: 10901 },
|
||||
{ name: 'http', port: 10902, targetPort: 10902 },
|
||||
],
|
||||
selector: p._config.selectorLabels {
|
||||
prometheus: p._config.name,
|
||||
'app.kubernetes.io/component': 'prometheus',
|
||||
},
|
||||
clusterIP: 'None',
|
||||
},
|
||||
},
|
||||
|
||||
// Include thanos sidecar ServiceMonitor only if thanos config was passed by user
|
||||
[if std.objectHas(params, 'thanos') && std.length(params.thanos) > 0 then 'serviceMonitorThanosSidecar']: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata+: {
|
||||
name: 'thanos-sidecar',
|
||||
namespace: p._config.namespace,
|
||||
labels: p._config.commonLabels {
|
||||
prometheus: p._config.name,
|
||||
'app.kubernetes.io/component': 'thanos-sidecar',
|
||||
},
|
||||
},
|
||||
spec+: {
|
||||
jobLabel: 'app.kubernetes.io/component',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
prometheus: p._config.name,
|
||||
'app.kubernetes.io/component': 'thanos-sidecar',
|
||||
},
|
||||
},
|
||||
endpoints: [{
|
||||
port: 'http',
|
||||
interval: '30s',
|
||||
}],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -8,16 +8,16 @@
|
||||
"subdir": "grafana"
|
||||
}
|
||||
},
|
||||
"version": "release-0.2"
|
||||
"version": "8ea4e7bc04b1bf5e9bd99918ca28c6271b42be0e"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
"git": {
|
||||
"remote": "https://github.com/etcd-io/etcd",
|
||||
"subdir": "Documentation/etcd-mixin"
|
||||
"subdir": "contrib/mixin"
|
||||
}
|
||||
},
|
||||
"version": "master"
|
||||
"version": "562d645ac923388ff5b8d270b0536764d34b0e0f"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -26,7 +26,7 @@
|
||||
"subdir": "jsonnet/prometheus-operator"
|
||||
}
|
||||
},
|
||||
"version": "release-0.44"
|
||||
"version": "release-0.47"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -35,7 +35,8 @@
|
||||
"subdir": "jsonnet/mixin"
|
||||
}
|
||||
},
|
||||
"version": "release-0.44"
|
||||
"version": "release-0.47",
|
||||
"name": "prometheus-operator-mixin"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -44,7 +45,7 @@
|
||||
"subdir": ""
|
||||
}
|
||||
},
|
||||
"version": "release-0.6"
|
||||
"version": "release-0.8"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -53,7 +54,7 @@
|
||||
"subdir": "jsonnet/kube-state-metrics"
|
||||
}
|
||||
},
|
||||
"version": "release-1.9"
|
||||
"version": "release-2.0"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -62,7 +63,7 @@
|
||||
"subdir": "jsonnet/kube-state-metrics-mixin"
|
||||
}
|
||||
},
|
||||
"version": "release-1.9"
|
||||
"version": "release-2.0"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -71,7 +72,7 @@
|
||||
"subdir": "docs/node-mixin"
|
||||
}
|
||||
},
|
||||
"version": "master"
|
||||
"version": "release-1.1"
|
||||
},
|
||||
{
|
||||
"source": {
|
||||
@@ -80,7 +81,7 @@
|
||||
"subdir": "documentation/prometheus-mixin"
|
||||
}
|
||||
},
|
||||
"version": "release-2.23",
|
||||
"version": "release-2.26",
|
||||
"name": "prometheus"
|
||||
},
|
||||
{
|
||||
@@ -90,7 +91,7 @@
|
||||
"subdir": "doc/alertmanager-mixin"
|
||||
}
|
||||
},
|
||||
"version": "master",
|
||||
"version": "release-0.21",
|
||||
"name": "alertmanager"
|
||||
},
|
||||
{
|
||||
@@ -100,7 +101,8 @@
|
||||
"subdir": "mixin"
|
||||
}
|
||||
},
|
||||
"version": "release-0.17"
|
||||
"version": "release-0.19",
|
||||
"name": "thanos-mixin"
|
||||
}
|
||||
],
|
||||
"legacyImports": true
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
{
|
||||
local antiaffinity(key, values, namespace) = {
|
||||
affinity: {
|
||||
podAntiAffinity: {
|
||||
preferredDuringSchedulingIgnoredDuringExecution: [
|
||||
{
|
||||
weight: 100,
|
||||
podAffinityTerm: {
|
||||
namespaces: [namespace],
|
||||
topologyKey: 'kubernetes.io/hostname',
|
||||
labelSelector: {
|
||||
matchExpressions: [{
|
||||
key: key,
|
||||
operator: 'In',
|
||||
values: values,
|
||||
}],
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
alertmanager+: {
|
||||
spec+:
|
||||
antiaffinity('alertmanager', [$._config.alertmanager.name], $._config.namespace),
|
||||
},
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
local p = self,
|
||||
|
||||
prometheus+: {
|
||||
spec+:
|
||||
antiaffinity('prometheus', [$._config.prometheus.name], $._config.namespace),
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
{
|
||||
_config+:: {
|
||||
eks: {
|
||||
minimumAvailableIPs: 10,
|
||||
minimumAvailableIPsTime: '10m',
|
||||
},
|
||||
},
|
||||
prometheus+: {
|
||||
serviceMonitorCoreDNS+: {
|
||||
spec+: {
|
||||
endpoints: [
|
||||
{
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
interval: '15s',
|
||||
targetPort: 9153,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
AwsEksCniMetricService: {
|
||||
apiVersion: 'v1',
|
||||
kind: 'Service',
|
||||
metadata: {
|
||||
name: 'aws-node',
|
||||
namespace: 'kube-system',
|
||||
labels: { 'k8s-app': 'aws-node' },
|
||||
},
|
||||
spec: {
|
||||
ports: [
|
||||
{ name: 'cni-metrics-port', port: 61678, targetPort: 61678 },
|
||||
],
|
||||
selector: { 'k8s-app': 'aws-node' },
|
||||
clusterIP: 'None',
|
||||
},
|
||||
},
|
||||
|
||||
serviceMonitorAwsEksCNI: {
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'awsekscni',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'eks-cni',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'aws-node',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'kube-system',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'cni-metrics-port',
|
||||
interval: '30s',
|
||||
path: '/metrics',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
prometheusRules+: {
|
||||
groups+: [
|
||||
{
|
||||
name: 'kube-prometheus-eks.rules',
|
||||
rules: [
|
||||
{
|
||||
expr: 'sum by(instance) (awscni_ip_max) - sum by(instance) (awscni_assigned_ip_addresses) < %s' % $._config.eks.minimumAvailableIPs,
|
||||
labels: {
|
||||
severity: 'critical',
|
||||
},
|
||||
annotations: {
|
||||
message: 'Instance {{ $labels.instance }} has less than 10 IPs available.',
|
||||
},
|
||||
'for': $._config.eks.minimumAvailableIPsTime,
|
||||
alert: 'EksAvailableIPs',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// On managed Kubernetes clusters some of the control plane components are not exposed to customers.
|
||||
// Disable scrape jobs, service monitors, and alert groups for these components by overwriting 'kube-prometheus.libsonnet' defaults
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
// This snippet walks the original object (super.jobs, set as temp var j) and creates a replacement jobs object
|
||||
// excluding any members of the set specified (eg: controller and scheduler).
|
||||
local j = super.jobs,
|
||||
jobs: {
|
||||
[k]: j[k]
|
||||
for k in std.objectFields(j)
|
||||
if !std.setMember(k, ['KubeControllerManager', 'KubeScheduler'])
|
||||
},
|
||||
|
||||
// Skip alerting rules too
|
||||
prometheus+:: {
|
||||
rules+:: {
|
||||
local g = super.groups,
|
||||
groups: [
|
||||
h
|
||||
for h in g
|
||||
if !std.setMember(h.name, ['kubernetes-system-controller-manager', 'kubernetes-system-scheduler'])
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// Same as above but for ServiceMonitor's
|
||||
local p = super.prometheus,
|
||||
prometheus: {
|
||||
[q]: p[q]
|
||||
for q in std.objectFields(p)
|
||||
if !std.setMember(q, ['serviceMonitorKubeControllerManager', 'serviceMonitorKubeScheduler'])
|
||||
},
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
// Strips spec.containers[].limits for certain containers
|
||||
// https://github.com/prometheus-operator/kube-prometheus/issues/72
|
||||
{
|
||||
_config+:: {
|
||||
resources+:: {
|
||||
'addon-resizer'+: {
|
||||
limits: {},
|
||||
},
|
||||
'kube-rbac-proxy'+: {
|
||||
limits: {},
|
||||
},
|
||||
'kube-state-metrics'+: {
|
||||
limits: {},
|
||||
},
|
||||
'node-exporter'+: {
|
||||
limits: {},
|
||||
},
|
||||
},
|
||||
},
|
||||
prometheusOperator+: {
|
||||
deployment+: {
|
||||
spec+: {
|
||||
template+: {
|
||||
spec+: {
|
||||
local addArgs(c) =
|
||||
if c.name == 'prometheus-operator'
|
||||
then c { args+: ['--config-reloader-cpu=0'] }
|
||||
else c,
|
||||
containers: std.map(addArgs, super.containers),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user