Merge branch 'prometheus-operator:main' into master

This commit is contained in:
Eric 2021-09-19 17:26:07 -04:00 committed by GitHub
commit a519249214
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
249 changed files with 19534 additions and 10942 deletions

37
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -0,0 +1,37 @@
<!--
WARNING: Not using this template will result in a longer review process and your change won't be visible in CHANGELOG.
-->
## Description
_Describe the big picture of your changes here to communicate to the maintainers why we should accept this pull request.
If it fixes a bug or resolves a feature request, be sure to link to that issue._
## Type of change
_What type of changes does your code introduce to the kube-prometheus? Put an `x` in the box that apply._
- [ ] `CHANGE` (fix or feature that would cause existing functionality to not work as expected)
- [ ] `FEATURE` (non-breaking change which adds functionality)
- [ ] `BUGFIX` (non-breaking change which fixes an issue)
- [ ] `ENHANCEMENT` (non-breaking change which improves existing functionality)
- [ ] `NONE` (if none of the other choices apply. Example, tooling, build system, CI, docs, etc.)
## Changelog entry
_Please put a one-line changelog entry below. Later this will be copied to the changelog file._
<!--
Your release note should be written in clear and straightforward sentences. Most often, users aren't familiar with
the technical details of your PR, so consider what they need to know when you write your release note.
Some brief examples of release notes:
- Add metadataConfig field to the Prometheus CRD for configuring how remote-write sends metadata information.
- Generate correct scraping configuration for Probes with empty or unset module parameter.
-->
```release-note
```

View File

@ -3,8 +3,8 @@ on:
- push
- pull_request
env:
golang-version: '1.13'
kind-version: 'v0.9.0'
golang-version: '1.15'
kind-version: 'v0.11.1'
jobs:
generate:
runs-on: ${{ matrix.os }}
@ -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,21 +52,20 @@ jobs:
strategy:
matrix:
kind-image:
- 'kindest/node:v1.19.0'
- 'kindest/node:v1.21.1'
- 'kindest/node:v1.22.0'
steps:
- uses: actions/checkout@v2
with:
persist-credentials: false
- name: Start KinD
uses: engineerd/setup-kind@v0.5.0
with:
version: ${{ env.kind-version }}
image: ${{ matrix.kind-image }}
wait: 300s
- name: Wait for cluster to finish bootstraping
run: |
until [ "$(kubectl get pods --all-namespaces --no-headers | grep -cEv '([0-9]+)/\1')" -eq 0 ]; do
sleep 5s
done
kubectl cluster-info
kubectl get pods -A
run: kubectl wait --for=condition=Ready pods --all --all-namespaces --timeout=300s
- name: Create kube-prometheus stack
run: |
kubectl create -f manifests/setup

68
.github/workflows/versions.yaml vendored Normal file
View File

@ -0,0 +1,68 @@
name: Upgrade to latest versions
on:
workflow_dispatch:
schedule:
- cron: '37 7 * * 1'
jobs:
versions:
runs-on: ubuntu-latest
strategy:
matrix:
branch:
- 'release-0.6'
- 'release-0.7'
- 'release-0.8'
- 'release-0.9'
- 'main'
steps:
- uses: actions/checkout@v2
with:
ref: ${{ matrix.branch }}
- uses: actions/setup-go@v2
with:
go-version: 1.16
- name: Upgrade versions
run: |
export GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}
# Write to temporary file to make update atomic
scripts/generate-versions.sh > /tmp/versions.json
mv /tmp/versions.json jsonnet/kube-prometheus/versions.json
if: matrix.branch == 'main'
- name: Update jsonnet dependencies
run: |
make update
make generate
# Reset jsonnetfile.lock.json if no dependencies were updated
changedFiles=$(git diff --name-only | grep -v 'jsonnetfile.lock.json' | wc -l)
if [[ "$changedFiles" -eq 0 ]]; then
git checkout -- jsonnetfile.lock.json;
fi
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
commit-message: "[bot] [${{ matrix.branch }}] Automated version update"
title: "[bot] [${{ matrix.branch }}] Automated version update"
body: |
## Description
This is an automated version and jsonnet dependencies update performed from CI.
Configuration of the workflow is located in `.github/workflows/versions.yaml`
## Type of change
- [x] `NONE` (if none of the other choices apply. Example, tooling, build system, CI, docs, etc.)
## Changelog entry
```release-note
```
team-reviewers: kube-prometheus-reviewers
branch: automated-updates-${{ matrix.branch }}
delete-branch: true
# GITHUB_TOKEN cannot be used as it won't trigger CI in a created PR
# More in https://github.com/peter-evans/create-pull-request/issues/155
token: ${{ secrets.PROM_OP_BOT_PAT }}

3
.gitignore vendored
View File

@ -3,3 +3,6 @@ minikube-manifests/
vendor/
./auth
.swp
crdschemas/
.gitpod/_output/

47
.gitpod.yml Normal file
View File

@ -0,0 +1,47 @@
image: gitpod/workspace-full
checkoutLocation: gitpod-k3s
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
- name: run kube-prometheus
command: |
.gitpod/prepare-k3s.sh
.gitpod/deploy-kube-prometheus.sh
- name: kernel dev environment
init: |
sudo apt update -y
sudo apt install qemu qemu-system-x86 linux-image-$(uname -r) libguestfs-tools sshpass netcat -y
sudo curl -o /usr/bin/kubectl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo chmod +x /usr/bin/kubectl
.gitpod/prepare-rootfs.sh
command: |
.gitpod/qemu.sh
ports:
- port: 3000
onOpen: open-browser
- port: 9090
onOpen: open-browser
- port: 9093
onOpen: open-browser
vscode:
extensions:
- heptio.jsonnet@0.1.0:woEDU5N62LRdgdz0g/I6sQ==

View File

@ -0,0 +1,16 @@
kubectl apply -f manifests/setup
# Safety wait for CRDs to be working
sleep 30
kubectl apply -f manifests/
kubectl rollout status -n monitoring daemonset node-exporter
kubectl rollout status -n monitoring statefulset alertmanager-main
kubectl rollout status -n monitoring statefulset prometheus-k8s
kubectl rollout status -n monitoring deployment grafana
kubectl rollout status -n monitoring deployment kube-state-metrics
kubectl port-forward -n monitoring svc/grafana 3000 > /dev/null 2>&1 &
kubectl port-forward -n monitoring svc/alertmanager-main 9093 > /dev/null 2>&1 &
kubectl port-forward -n monitoring svc/prometheus-k8s 9090 > /dev/null 2>&1 &

49
.gitpod/prepare-k3s.sh Executable file
View File

@ -0,0 +1,49 @@
#!/bin/bash
script_dirname="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
rootfslock="${script_dirname}/_output/rootfs/rootfs-ready.lock"
k3sreadylock="${script_dirname}/_output/rootfs/k3s-ready.lock"
if test -f "${k3sreadylock}"; then
exit 0
fi
cd $script_dirname
function waitssh() {
while ! nc -z 127.0.0.1 2222; do
sleep 0.1
done
./ssh.sh "whoami" &>/dev/null
if [ $? -ne 0 ]; then
sleep 1
waitssh
fi
}
function waitrootfs() {
while ! test -f "${rootfslock}"; do
sleep 0.1
done
}
echo "🔥 Installing everything, this will be done only one time per workspace."
echo "Waiting for the rootfs to become available, it can take a while, open the terminal #2 for progress"
waitrootfs
echo "✅ rootfs available"
echo "Waiting for the ssh server to become available, it can take a while, after this k3s is getting installed"
waitssh
echo "✅ ssh server available"
./ssh.sh "curl -sfL https://get.k3s.io | sh -"
mkdir -p ~/.kube
./scp.sh root@127.0.0.1:/etc/rancher/k3s/k3s.yaml ~/.kube/config
echo "✅ k3s server is ready"
touch "${k3sreadylock}"
# safety wait for cluster availability
sleep 30s

48
.gitpod/prepare-rootfs.sh Executable file
View File

@ -0,0 +1,48 @@
#!/bin/bash
set -euo pipefail
img_url="https://cloud-images.ubuntu.com/hirsute/current/hirsute-server-cloudimg-amd64.tar.gz"
script_dirname="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
outdir="${script_dirname}/_output/rootfs"
rm -Rf $outdir
mkdir -p $outdir
curl -L -o "${outdir}/rootfs.tar.gz" $img_url
cd $outdir
tar -xvf rootfs.tar.gz
qemu-img resize hirsute-server-cloudimg-amd64.img +20G
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --run-command 'resize2fs /dev/sda'
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --root-password password:root
netconf="
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
dhcp4: yes
"
# networking setup
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --run-command "echo '${netconf}' > /etc/netplan/01-net.yaml"
# copy kernel modules
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --copy-in /lib/modules/$(uname -r):/lib/modules
# ssh
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --run-command 'apt remove openssh-server -y && apt install openssh-server -y'
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --run-command "sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config"
sudo virt-customize -a hirsute-server-cloudimg-amd64.img --run-command "sed -i 's/PasswordAuthentication no/PasswordAuthentication yes/' /etc/ssh/sshd_config"
# mark as ready
touch rootfs-ready.lock
echo "k3s development environment is ready"

14
.gitpod/qemu.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -xeuo pipefail
script_dirname="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
outdir="${script_dirname}/_output"
sudo qemu-system-x86_64 -kernel "/boot/vmlinuz" \
-boot c -m 3073M -hda "${outdir}/rootfs/hirsute-server-cloudimg-amd64.img" \
-net user \
-smp 8 \
-append "root=/dev/sda rw console=ttyS0,115200 acpi=off nokaslr" \
-nic user,hostfwd=tcp::2222-:22,hostfwd=tcp::6443-:6443 \
-serial mon:stdio -display none

3
.gitpod/scp.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
sshpass -p 'root' scp -o StrictHostKeychecking=no -P 2222 $@

3
.gitpod/ssh.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
sshpass -p 'root' ssh -o StrictHostKeychecking=no -p 2222 root@127.0.0.1 "$@"

44
CHANGELOG.md Normal file
View File

@ -0,0 +1,44 @@
## release-0.9 / 2021-08-19
* [CHANGE] Test against Kubernetes 1.21 and 1,22. #1161 #1337
* [CHANGE] Drop cAdvisor metrics without (pod, namespace) label pairs. #1250
* [CHANGE] Excluded deprecated `etcd_object_counts` metric. #1337
* [FEATURE] Add PodDisruptionBudget to prometheus-adapter. #1136
* [FEATURE] Add support for feature flags in Prometheus. #1129
* [FEATURE] Add env parameter for grafana component. #1171
* [FEATURE] Add gitpod deployment of kube-prometheus on k3s. #1211
* [FEATURE] Add resource requests and limits to prometheus-adapter container. #1282
* [FEATURE] Add PodMonitor for kube-proxy. #1230
* [FEATURE] Turn AWS VPC CNI into a control plane add-on. #1307
* [ENHANCEMENT] Export anti-affinity addon. #1114
* [ENHANCEMENT] Allow changing configmap-reloader, grafana, and kube-rbac-proxy images in $.values.common.images. #1123 #1124 #1125
* [ENHANCEMENT] Add automated version upgrader. #1166
* [ENHANCEMENT] Improve all-namespace addon. #1131
* [ENHANCEMENT] Add example of running without grafana deployment. #1201
* [ENHANCEMENT] Import managed-cluster addon for the EKS platform. #1205
* [ENHANCEMENT] Automatically update jsonnet dependencies. #1220
* [ENHANCEMENT] Adapt kube-prometheus to changes to ovn veth interfaces names. #1224
* [ENHANCEMENT] Add example release-0.3 to release-0.8 migration to docs. #1235
* [ENHANCEMENT] Consolidate intervals used in prometheus-adapter CPU queries. #1231
* [ENHANCEMENT] Create dashboardDefinitions if rawDashboards or folderDashboards are specified. #1255
* [ENHANCEMENT] Relabel instance with node name for CNI DaemonSet on EKS. #1259
* [ENHANCEMENT] Update doc on Prometheus rule updates since release 0.8. #1253
* [ENHANCEMENT] Point runbooks to https://runbooks.prometheus-operator.dev. #1267
* [ENHANCEMENT] Allow setting of kubeRbacProxyMainResources in kube-state-metrics. #1257
* [ENHANCEMENT] Automate release branch updates. #1293 #1303
* [ENHANCEMENT] Create Thanos Sidecar rules separately from Prometheus ones. #1308
* [ENHANCEMENT] Allow using newer jsonnet-bundler dependency resolution when using windows addon. #1310
* [ENHANCEMENT] Prometheus ruleSelector defaults to all rules.
* [BUGFIX] Fix kube-state-metrics metric denylist regex pattern. #1146
* [BUGFIX] Fix missing resource config in blackbox exporter. #1148
* [BUGFIX] Fix adding private repository. #1169
* [BUGFIX] Fix kops selectors for scheduler, controllerManager and kube-dns. #1164
* [BUGFIX] Fix scheduler and controller selectors for Kubespray. #1142
* [BUGFIX] Fix label selector for coredns ServiceMonitor. #1200
* [BUGFIX] Fix name for blackbox-exporter PodSecurityPolicy. #1213
* [BUGFIX] Fix ingress path rules for networking.k8s.io/v1. #1212
* [BUGFIX] Disable insecure cypher suites for prometheus-adapter. #1216
* [BUGFIX] Fix CNI metrics relabelings on EKS. #1277
* [BUGFIX] Fix node-exporter ignore list for OVN. #1283
* [BUGFIX] Revert back to awscni_total_ip_addresses-based alert on EKS. #1292
* [BUGFIX] Allow passing `thanos: {}` to prometheus configuration. #1325

View File

@ -1,15 +1,15 @@
SHELL=/bin/bash -o pipefail
export GO111MODULE=on
BIN_DIR?=$(shell pwd)/tmp/bin
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
@ -26,22 +26,47 @@ generate: manifests **.md
**.md: $(EMBEDMD_BIN) $(shell find examples) build.sh example.jsonnet
$(EMBEDMD_BIN) -w `find . -name "*.md" | grep -v vendor`
manifests: examples/kustomize.jsonnet $(GOJSONTOYAML_BIN) vendor build.sh
manifests: examples/kustomize.jsonnet $(GOJSONTOYAML_BIN) vendor
./build.sh $<
vendor: $(JB_BIN) jsonnetfile.json jsonnetfile.lock.json
rm -rf vendor
$(JB_BIN) install
crdschemas: vendor
./scripts/generate-schemas.sh
.PHONY: update
update: $(JB_BIN)
$(JB_BIN) update
.PHONY: validate
validate: validate-1.21 validate-1.22
validate-1.21:
KUBE_VERSION=1.21.1 $(MAKE) kubeconform
validate-1.22:
KUBE_VERSION=1.22.0 $(MAKE) kubeconform
.PHONY: kubeconform
kubeconform: crdschemas manifests $(KUBECONFORM_BIN)
$(KUBECONFORM_BIN) -kubernetes-version $(KUBE_VERSION) -schema-location 'default' -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
./test.sh
./scripts/test.sh
.PHONY: test-e2e
test-e2e:
@ -52,4 +77,4 @@ $(BIN_DIR):
$(TOOLING): $(BIN_DIR)
@echo Installing tools from scripts/tools.go
@cat scripts/tools.go | grep _ | awk -F'"' '{print $$2}' | GOBIN=$(BIN_DIR) xargs -tI % go install %
@cd scripts && cat tools.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go build -modfile=go.mod -o $(BIN_DIR) %

5
NOTICE
View File

@ -1,5 +0,0 @@
CoreOS Project
Copyright 2018 CoreOS, Inc
This product includes software developed at CoreOS, Inc.
(http://www.coreos.com/).

14
OWNERS
View File

@ -1,14 +0,0 @@
reviewers:
- brancz
- metalmatze
- mxinden
- s-urbaniak
- squat
- paulfantom
approvers:
- brancz
- metalmatze
- mxinden
- s-urbaniak
- squat
- paulfantom

367
README.md
View File

@ -1,5 +1,9 @@
# kube-prometheus
[![Build Status](https://github.com/prometheus-operator/kube-prometheus/workflows/ci/badge.svg)](https://github.com/prometheus-operator/kube-prometheus/actions)
[![Slack](https://img.shields.io/badge/join%20slack-%23prometheus--operator-brightgreen.svg)](http://slack.k8s.io/)
[![Gitpod ready-to-code](https://img.shields.io/badge/Gitpod-ready--to--code-blue?logo=gitpod)](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,13 +62,17 @@ 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)
- [Authorization problem](#authorization-problem)
- [kube-state-metrics resource usage](#kube-state-metrics-resource-usage)
- [Error retrieving kube-proxy metrics](#error-retrieving-kube-proxy-metrics)
- [Contributing](#contributing)
- [License](#license)
## Prerequisites
@ -78,7 +91,7 @@ This adapter is an Extension API Server and Kubernetes needs to be have this fea
To try out this stack, start [minikube](https://github.com/kubernetes/minikube) with the following command:
```shell
$ minikube delete && minikube start --kubernetes-version=v1.19.0 --memory=6g --bootstrapper=kubeadm --extra-config=kubelet.authentication-token-webhook=true --extra-config=kubelet.authorization-mode=Webhook --extra-config=scheduler.address=0.0.0.0 --extra-config=controller-manager.address=0.0.0.0
$ minikube delete && minikube start --kubernetes-version=v1.20.0 --memory=6g --bootstrapper=kubeadm --extra-config=kubelet.authentication-token-webhook=true --extra-config=kubelet.authorization-mode=Webhook --extra-config=scheduler.address=0.0.0.0 --extra-config=controller-manager.address=0.0.0.0
```
The kube-prometheus stack includes a resource metrics API server, so the metrics-server addon is not necessary. Ensure the metrics-server addon is disabled on minikube:
@ -93,19 +106,17 @@ $ 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.14 | Kubernetes 1.15 | Kubernetes 1.16 | Kubernetes 1.17 | Kubernetes 1.18 | Kubernetes 1.19 |
|-----------------------|-----------------|-----------------|-----------------|-----------------|-----------------|-----------------|
| `release-0.3` | ✔ | ✔ | ✔ | ✔ | ✗ | ✗ |
| `release-0.4` | ✗ | ✗ | ✔ (v1.16.5+) | ✔ | ✗ | ✗ |
| `release-0.5` | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ |
| `release-0.6` | ✗ | ✗ | ✗ | ✗ | ✔ | ✔ |
| `HEAD` | ✗ | ✗ | ✗ | ✗ | x | ✔ |
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 | Kubernetes 1.22 |
|------------------------------------------------------------------------------------------|-----------------|-----------------|-----------------|-----------------|-----------------|
| [`release-0.6`](https://github.com/prometheus-operator/kube-prometheus/tree/release-0.6) | ✗ | ✔ | ✗ | ✗ | ✗ |
| [`release-0.7`](https://github.com/prometheus-operator/kube-prometheus/tree/release-0.7) | ✗ | ✔ | ✔ | ✗ | ✗ |
| [`release-0.8`](https://github.com/prometheus-operator/kube-prometheus/tree/release-0.8) | ✗ | ✗ | ✔ | ✔ | ✗ |
| [`release-0.9`](https://github.com/prometheus-operator/kube-prometheus/tree/release-0.9) | ✗ | ✗ | ✗ | ✔ | ✔ |
| [`HEAD`](https://github.com/prometheus-operator/kube-prometheus/tree/main) | ✗ | ✗ | ✗ | ✔ | ✔ |
## Quickstart
>Note: For versions before Kubernetes v1.19.z refer to the [Kubernetes compatibility matrix](#kubernetes-compatibility-matrix) in order to choose a compatible branch.
>Note: For versions before Kubernetes v1.21.z refer to the [Kubernetes compatibility matrix](#kubernetes-compatibility-matrix) in order to choose a compatible branch.
This project is intended to be used as a library (i.e. the intent is not for you to create your own modified copy of this repository).
@ -113,7 +124,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/
@ -174,12 +185,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
@ -190,7 +204,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):
@ -199,33 +213,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/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}`):
@ -266,7 +286,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/
```
@ -308,74 +328,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/coreos/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/
@ -392,57 +360,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+:: {
common+: {
platform: 'example-platform',
},
},
}
```
### Internal Registry
@ -468,10 +407,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');
@ -490,8 +431,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
@ -500,7 +441,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+: {
@ -517,7 +458,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+: {
@ -530,12 +471,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:
@ -562,8 +503,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',
},
@ -573,15 +514,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'],
},
},
@ -606,14 +549,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',
@ -645,7 +590,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.
@ -656,12 +602,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: [],
},
},
@ -689,11 +636,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
@ -703,10 +665,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',
},
},
};
@ -727,6 +691,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.
@ -737,6 +731,8 @@ Working examples of use with continuous delivery tools are found in examples/con
## Troubleshooting
See the general [guidelines](docs/community-support.md) for getting support from the community.
### Error retrieving kubelet metrics
Should the Prometheus `/targets` page show kubelet targets, but not able to successfully scrape the metrics, then most likely it is a problem with the authentication and authorization setup of the kubelets.
@ -762,7 +758,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:
@ -775,6 +771,13 @@ config. They default to:
}
```
### Error retrieving kube-proxy metrics
By default, kubeadm will configure kube-proxy to listen on 127.0.0.1 for metrics. Because of this prometheus would not be able to scrape these metrics. This would have to be changed to 0.0.0.0 in one of the following two places:
1. Before cluster initialization, the config file passed to kubeadm init should have KubeProxyConfiguration manifest with the field metricsBindAddress set to 0.0.0.0:10249
2. If the k8s cluster is already up and running, we'll have to modify the configmap kube-proxy in the namespace kube-system and set the metricsBindAddress field. After this kube-proxy daemonset would have to be restarted with
`kubectl -n kube-system rollout restart daemonset kube-proxy`
## Contributing
All `.yaml` files in the `/manifests` folder are generated via
@ -787,3 +790,7 @@ the following process:
3. Update the pinned kube-prometheus dependency in `jsonnetfile.lock.json`: `jb update`
3. Generate dependent `*.yaml` files: `make generate`
4. Commit the generated changes.
## License
Apache License 2.0, see [LICENSE](https://github.com/prometheus-operator/kube-prometheus/blob/main/LICENSE).

View File

@ -1,4 +1,4 @@
## CoreOS Community Code of Conduct
## Community Code of Conduct
### Contributor Code of Conduct
@ -33,29 +33,9 @@ This code of conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community.
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting a project maintainer, Brandon Philips
<brandon.philips@coreos.com>, and/or Rithu John <rithu.john@coreos.com>.
reported by contacting a project maintainer listed in
https://github.com/prometheus-operator/prometheus-operator/blob/master/MAINTAINERS.md.
This Code of Conduct is adapted from the Contributor Covenant
(http://contributor-covenant.org), version 1.2.0, available at
http://contributor-covenant.org/version/1/2/0/
### CoreOS Events Code of Conduct
CoreOS events are working conferences intended for professional networking and
collaboration in the CoreOS community. Attendees are expected to behave
according to professional standards and in accordance with their employers
policies on appropriate workplace behavior.
While at CoreOS events or related social networking opportunities, attendees
should not engage in discriminatory or offensive speech or actions including
but not limited to gender, sexuality, race, age, disability, or religion.
Speakers should be especially aware of these concerns.
CoreOS does not condone any statements by speakers contrary to these standards.
CoreOS reserves the right to deny entrance and/or eject from an event (without
refund) any individual found to be engaging in discriminatory or offensive
speech or actions.
Please bring any concerns to the immediate attention of designated on-site
staff, Brandon Philips <brandon.philips@coreos.com>, and/or Rithu John <rithu.john@coreos.com>.

View File

@ -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
View 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
```

84
docs/community-support.md Normal file
View File

@ -0,0 +1,84 @@
# Community support
For bugs, you can use the GitHub [issue tracker](https://github.com/prometheus-operator/kube-prometheus/issues/new/choose).
For questions, you can use the GitHub [discussions forum](https://github.com/prometheus-operator/kube-prometheus/discussions).
Many of the `kube-prometheus` project's contributors and users can also be found on the #prometheus-operator channel of the [Kubernetes Slack][Kubernetes Slack].
`kube-prometheus` is the aggregation of many projects that all have different
channels to reach out for help and support. This community strives at
supporting all users and you should never be afraid of asking us first. However
if your request relates specifically to one of the projects listed below, it is
often more efficient to reach out to the project directly. If you are unsure,
please feel free to open an issue in this repository and we will redirect you
if applicable.
## prometheus-operator
For documentation, check the project's [documentation directory](https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation).
For questions, use the #prometheus-operator channel on the [Kubernetes Slack][Kubernetes Slack].
For bugs, use the GitHub [issue tracker](https://github.com/prometheus-operator/prometheus-operator/issues/new/choose).
## Prometheus, Alertmanager, node_exporter
For documentation, check the Prometheus [online docs](https://prometheus.io/docs/). There is a
[section](https://prometheus.io/docs/introduction/media/) with links to blog
posts, recorded talks and presentations. This [repository](https://github.com/roaldnefs/awesome-prometheus)
(not affiliated to the Prometheus project) has also a list of curated resources
related to the Prometheus ecosystem.
For questions, see the Prometheus [community page](https://prometheus.io/community/) for the various channels.
There is also a #prometheus channel on the [CNCF Slack][CNCF Slack].
## kube-state-metrics
For documentation, see the project's [docs directory](https://github.com/kubernetes/kube-state-metrics/tree/master/docs).
For questions, use the #kube-state-metrics channel on the [Kubernetes Slack][Kubernetes Slack].
For bugs, use the GitHub [issue tracker](https://github.com/kubernetes/kube-state-metrics/issues/new/choose).
## Kubernetes
For documentation, check the [Kubernetes docs](https://kubernetes.io/docs/home/).
For questions, use the [community forums](https://discuss.kubernetes.io/) and the [Kubernetes Slack][Kubernetes Slack]. Check also the [community page](https://kubernetes.io/community/#discuss).
For bugs, use the GitHub [issue tracker](https://github.com/kubernetes/kubernetes/issues/new/choose).
## Prometheus adapter
For documentation, check the project's [README](https://github.com/DirectXMan12/k8s-prometheus-adapter/blob/master/README.md).
For questions, use the #sig-instrumentation channel on the [Kubernetes Slack][Kubernetes Slack].
For bugs, use the GitHub [issue tracker](https://github.com/DirectXMan12/k8s-prometheus-adapter/issues/new).
## Grafana
For documentation, check the [Grafana docs](https://grafana.com/docs/grafana/latest/).
For questions, use the [community forums](https://community.grafana.com/).
For bugs, use the GitHub [issue tracker](https://github.com/grafana/grafana/issues/new/choose).
## kubernetes-mixin
For documentation, check the project's [README](https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/README.md).
For questions, use #monitoring-mixins channel on the [Kubernetes Slack][Kubernetes Slack].
For bugs, use the GitHub [issue tracker](https://github.com/kubernetes-monitoring/kubernetes-mixin/issues/new).
## Jsonnet
For documentation, check the [Jsonnet](https://jsonnet.org/) website.
For questions, use the [mailing list](https://groups.google.com/forum/#!forum/jsonnet).
[Kubernetes Slack]: https://slack.k8s.io/
[CNCF Slack]: https://slack.cncf.io/

19
docs/deploy-kind.md Normal file
View 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)!

View File

@ -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,33 +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/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
@ -52,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.',
},
},
],
},
],
},
],
},
},
};
@ -84,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
@ -95,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)',
},
],
},
],
},
],
},
},
};
@ -121,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
@ -142,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,
},
},
},
};
@ -158,76 +214,118 @@ 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
Along with adding additional rules, we give the user the option to filter or adjust the existing rules imported by `kube-prometheus/kube-prometheus.libsonnet`. The recording rules can be found in [kube-prometheus/rules](../jsonnet/kube-prometheus/rules) and [kubernetes-mixin/rules](https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/rules) while the alerting rules can be found in [kube-prometheus/alerts](../jsonnet/kube-prometheus/alerts) and [kubernetes-mixin/alerts](https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/alerts).
Along with adding additional rules, we give the user the option to filter or adjust the existing rules imported by `kube-prometheus/main.libsonnet`. The recording rules can be found in [kube-prometheus/components/mixin/rules](../jsonnet/kube-prometheus/components/mixin/rules) and [kubernetes-mixin/rules](https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/rules) while the alerting rules can be found in [kube-prometheus/components/mixin/alerts](../jsonnet/kube-prometheus/components/mixin/alerts) and [kubernetes-mixin/alerts](https://github.com/kubernetes-monitoring/kubernetes-mixin/tree/master/alerts).
Knowing which rules to change, the user can now use functions from the [Jsonnet standard library](https://jsonnet.org/ref/stdlib.html) to make these changes. Below are examples of both a filter and an adjustment being made to the default rules. These changes can be assigned to a local variable and then added to the `local kp` object as seen in the examples above.
#### Filter
Here the alert `KubeStatefulSetReplicasMismatch` is being filtered out of the group `kubernetes-apps`. The default rule can be seen [here](https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/alerts/apps_alerts.libsonnet).
Here the alert `KubeStatefulSetReplicasMismatch` is being filtered out of the group `kubernetes-apps`. The default rule can be seen [here](https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/alerts/apps_alerts.libsonnet). You first need to find out in which component the rule is defined (here it is kuberentesControlPlane).
```jsonnet
local filter = {
prometheusAlerts+:: {
groups: std.map(
function(group)
if group.name == 'kubernetes-apps' then
group {
rules: std.filter(function(rule)
rule.alert != "KubeStatefulSetReplicasMismatch",
group.rules
)
}
else
group,
super.groups
),
kubernetesControlPlane+: {
prometheusRule+: {
spec+: {
groups: std.map(
function(group)
if group.name == 'kubernetes-apps' then
group {
rules: std.filter(
function(rule)
rule.alert != 'KubeStatefulSetReplicasMismatch',
group.rules
),
}
else
group,
super.groups
),
},
},
},
};
```
#### Adjustment
Here the expression for the alert used above is updated from its previous value. The default rule can be seen [here](https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/alerts/apps_alerts.libsonnet).
Here the expression for another alert in the same component is updated from its previous value. The default rule can be seen [here](https://github.com/kubernetes-monitoring/kubernetes-mixin/blob/master/alerts/apps_alerts.libsonnet).
```jsonnet
local update = {
prometheusAlerts+:: {
groups: std.map(
function(group)
if group.name == 'kubernetes-apps' then
group {
rules: std.map(
function(rule)
if rule.alert == "KubeStatefulSetReplicasMismatch" then
rule {
expr: "kube_statefulset_status_replicas_ready{job=\"kube-state-metrics\",statefulset!=\"vault\"} != kube_statefulset_status_replicas{job=\"kube-state-metrics\",statefulset!=\"vault\"}"
}
else
rule,
group.rules
)
}
else
group,
super.groups
),
kubernetesControlPlane+: {
prometheusRule+: {
spec+: {
groups: std.map(
function(group)
if group.name == 'kubernetes-apps' then
group {
rules: std.map(
function(rule)
if rule.alert == 'KubePodCrashLooping' then
rule {
expr: 'rate(kube_pod_container_status_restarts_total{namespace=kube-system,job="kube-state-metrics"}[10m]) * 60 * 5 > 0',
}
else
rule,
group.rules
),
}
else
group,
super.groups
),
},
},
},
};
```
Using the example from above about adding in pre-rendered rules, the new local variables can be added in as follows:
```jsonnet
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + filter + update + {
prometheusAlerts+:: (import 'existingrule.json'),
local add = {
exampleApplication:: {
prometheusRule+: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'PrometheusRule',
metadata: {
name: 'example-application-rules',
namespace: $.values.common.namespace,
},
spec: (import 'existingrule.json'),
},
},
};
{ ['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) } +
local kp = (import 'kube-prometheus/main.libsonnet') + filter + update + add;
local kp = (import 'kube-prometheus/main.libsonnet') +
filter +
update +
add + {
values+:: {
common+: {
namespace: 'monitoring',
},
},
};
{ '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 } +
{ ['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) } +
{ ['exampleApplication-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }
```
## Dashboards
@ -248,35 +346,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)')))
),
},
},
},
};
@ -296,16 +396,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'),
},
},
},
};
@ -322,13 +421,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'),
},
},
},
};
@ -341,3 +442,117 @@ 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
```
Full example of including etcd mixin using method described above:
[embedmd]:# (../examples/mixin-inclusion.jsonnet)
```jsonnet
local addMixin = (import 'kube-prometheus/lib/mixin.libsonnet');
local etcdMixin = addMixin({
name: 'etcd',
mixin: (import 'github.com/etcd-io/etcd/contrib/mixin/mixin.libsonnet') + {
_config+: {}, // mixin configuration object
},
});
local kp = (import 'kube-prometheus/main.libsonnet') +
{
values+:: {
common+: {
namespace: 'monitoring',
},
grafana+: {
// Adding new dashboard to grafana. This will modify grafana configMap with dashboards
dashboards+: etcdMixin.grafanaDashboards,
},
},
};
{ ['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) } +
// Rendering prometheusRules object. This is an object compatible with prometheus-operator CRD definition for prometheusRule
{ 'external-mixins/etcd-mixin-prometheus-rules': etcdMixin.prometheusRules }
```

View File

@ -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

View File

@ -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.

View File

@ -0,0 +1,296 @@
// Has the following customisations
// Custom alert manager config
// Ingresses for the alert manager, prometheus and grafana
// Grafana admin user password
// Custom prometheus rules
// Custom grafana dashboards
// Custom prometheus config - Data retention, memory, etc.
// Node exporter role and role binding so we can use a PSP for the node exporter
// External variables
// See https://jsonnet.org/learning/tutorial.html
local cluster_identifier = std.extVar('cluster_identifier');
local etcd_ip = std.extVar('etcd_ip');
local etcd_tls_ca = std.extVar('etcd_tls_ca');
local etcd_tls_cert = std.extVar('etcd_tls_cert');
local etcd_tls_key = std.extVar('etcd_tls_key');
local grafana_admin_password = std.extVar('grafana_admin_password');
local prometheus_data_retention_period = std.extVar('prometheus_data_retention_period');
local prometheus_request_memory = std.extVar('prometheus_request_memory');
// Derived variables
local alert_manager_host = 'alertmanager.' + cluster_identifier + '.myorg.local';
local grafana_host = 'grafana.' + cluster_identifier + '.myorg.local';
local prometheus_host = 'prometheus.' + cluster_identifier + '.myorg.local';
// Imports
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
local ingress = k.extensions.v1beta1.ingress;
local ingressRule = ingress.mixin.spec.rulesType;
local ingressRuleHttpPath = ingressRule.mixin.http.pathsType;
local ingressTls = ingress.mixin.spec.tlsType;
local role = k.rbac.v1.role;
local roleBinding = k.rbac.v1.roleBinding;
local roleRulesType = k.rbac.v1.role.rulesType;
local kp =
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') +
(import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
{
_config+:: {
// Override namespace
namespace: 'monitoring',
// Override alert manager config
// See https://github.com/coreos/kube-prometheus/tree/master/examples/alertmanager-config-external.jsonnet
alertmanager+: {
config: importstr 'alertmanager.yaml',
},
// Override etcd config
// See https://github.com/coreos/kube-prometheus/blob/master/jsonnet/kube-prometheus/kube-prometheus-static-etcd.libsonnet
// See https://github.com/coreos/kube-prometheus/blob/master/examples/etcd-skip-verify.jsonnet
etcd+:: {
clientCA: etcd_tls_ca,
clientCert: etcd_tls_cert,
clientKey: etcd_tls_key,
ips: [etcd_ip],
},
// Override grafana config
// anonymous access
// See http://docs.grafana.org/installation/configuration/
// See http://docs.grafana.org/auth/overview/#anonymous-authentication
// admin_password
// See http://docs.grafana.org/installation/configuration/#admin-password
grafana+:: {
config: {
sections: {
'auth.anonymous': {
enabled: true,
},
security: {
admin_password: grafana_admin_password,
},
},
},
},
},
// Additional grafana dashboards
grafanaDashboards+:: {
'my-specific.json': (import 'my-grafana-dashboard-definitions.json'),
},
// Alert manager needs an externalUrl
alertmanager+:: {
alertmanager+: {
spec+: {
// See https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md
// See https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/exposing-prometheus-and-alertmanager.md
externalUrl: 'https://' + alert_manager_host,
},
},
},
// Add additional ingresses
// See https://github.com/coreos/kube-prometheus/tree/master/examples/ingress.jsonnet
ingress+:: {
alertmanager:
ingress.new() +
ingress.mixin.metadata.withName('alertmanager') +
ingress.mixin.metadata.withNamespace($._config.namespace) +
ingress.mixin.metadata.withAnnotations({
'kubernetes.io/ingress.class': 'nginx-api',
}) +
ingress.mixin.spec.withRules(
ingressRule.new() +
ingressRule.withHost(alert_manager_host) +
ingressRule.mixin.http.withPaths(
ingressRuleHttpPath.new() +
ingressRuleHttpPath.mixin.backend.withServiceName('alertmanager-operated') +
ingressRuleHttpPath.mixin.backend.withServicePort(9093)
),
) +
// Note we do not need a TLS secretName here as we are going to use the nginx-ingress default secret which is a wildcard
// secretName would need to be in the same namespace at this time, see https://github.com/kubernetes/ingress-nginx/issues/2371
ingress.mixin.spec.withTls(
ingressTls.new() +
ingressTls.withHosts(alert_manager_host)
),
grafana:
ingress.new() +
ingress.mixin.metadata.withName('grafana') +
ingress.mixin.metadata.withNamespace($._config.namespace) +
ingress.mixin.metadata.withAnnotations({
'kubernetes.io/ingress.class': 'nginx-api',
}) +
ingress.mixin.spec.withRules(
ingressRule.new() +
ingressRule.withHost(grafana_host) +
ingressRule.mixin.http.withPaths(
ingressRuleHttpPath.new() +
ingressRuleHttpPath.mixin.backend.withServiceName('grafana') +
ingressRuleHttpPath.mixin.backend.withServicePort(3000)
),
) +
// Note we do not need a TLS secretName here as we are going to use the nginx-ingress default secret which is a wildcard
// secretName would need to be in the same namespace at this time, see https://github.com/kubernetes/ingress-nginx/issues/2371
ingress.mixin.spec.withTls(
ingressTls.new() +
ingressTls.withHosts(grafana_host)
),
prometheus:
ingress.new() +
ingress.mixin.metadata.withName('prometheus') +
ingress.mixin.metadata.withNamespace($._config.namespace) +
ingress.mixin.metadata.withAnnotations({
'kubernetes.io/ingress.class': 'nginx-api',
}) +
ingress.mixin.spec.withRules(
ingressRule.new() +
ingressRule.withHost(prometheus_host) +
ingressRule.mixin.http.withPaths(
ingressRuleHttpPath.new() +
ingressRuleHttpPath.mixin.backend.withServiceName('prometheus-operated') +
ingressRuleHttpPath.mixin.backend.withServicePort(9090)
),
) +
// Note we do not need a TLS secretName here as we are going to use the nginx-ingress default secret which is a wildcard
// secretName would need to be in the same namespace at this time, see https://github.com/kubernetes/ingress-nginx/issues/2371
ingress.mixin.spec.withTls(
ingressTls.new() +
ingressTls.withHosts(prometheus_host)
),
},
// Node exporter PSP role and role binding
// Add a new top level field for this, the "node-exporter" PSP already exists, so not defining here just referencing
// See https://github.com/coreos/prometheus-operator/issues/787
nodeExporterPSP: {
role:
role.new() +
role.mixin.metadata.withName('node-exporter-psp') +
role.mixin.metadata.withNamespace($._config.namespace) +
role.withRules([
roleRulesType.new() +
roleRulesType.withApiGroups(['policy']) +
roleRulesType.withResources(['podsecuritypolicies']) +
roleRulesType.withVerbs(['use']) +
roleRulesType.withResourceNames(['node-exporter']),
]),
roleBinding:
roleBinding.new() +
roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
roleBinding.mixin.metadata.withName('node-exporter-psp') +
roleBinding.mixin.metadata.withNamespace($._config.namespace) +
roleBinding.mixin.roleRef.withName('node-exporter-psp') +
roleBinding.mixin.roleRef.mixinInstance({ kind: 'Role' }) +
roleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'node-exporter' }]),
},
// Prometheus needs some extra custom config
prometheus+:: {
prometheus+: {
spec+: {
// See https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md#prometheusspec
externalLabels: {
cluster: cluster_identifier,
},
// See https://github.com/coreos/prometheus-operator/blob/master/Documentation/api.md
// See https://github.com/coreos/prometheus-operator/blob/master/Documentation/user-guides/exposing-prometheus-and-alertmanager.md
externalUrl: 'https://' + prometheus_host,
// Override reuest memory
resources: {
requests: {
memory: prometheus_request_memory,
},
},
// Override data retention period
retention: prometheus_data_retention_period,
},
},
},
// Additional prometheus rules
// See https://github.com/coreos/kube-prometheus/docs/developing-prometheus-rules-and-grafana-dashboards.md
// cat my-prometheus-rules.yaml | gojsontoyaml -yamltojson | jq . > my-prometheus-rules.json
prometheusRules+:: {
groups+: import 'my-prometheus-rules.json',
},
};
// Render
{ ['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) } +
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
{ ['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) } +
{ [name + '-ingress']: kp.ingress[name] for name in std.objectFields(kp.ingress) } +
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
{ ['node-exporter-psp-' + name]: kp.nodeExporterPSP[name] for name in std.objectFields(kp.nodeExporterPSP) } +
{ ['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) }

View File

@ -0,0 +1,316 @@
// Has the following customisations
// Custom alert manager config
// Ingresses for the alert manager, prometheus and grafana
// Grafana admin user password
// Custom prometheus rules
// Custom grafana dashboards
// Custom prometheus config - Data retention, memory, etc.
// Node exporter role and role binding so we can use a PSP for the node exporter
// for help with expected content, see https://github.com/thaum-xyz/ankhmorpork
// External variables
// See https://jsonnet.org/learning/tutorial.html
local cluster_identifier = std.extVar('cluster_identifier');
local etcd_ip = std.extVar('etcd_ip');
local etcd_tls_ca = std.extVar('etcd_tls_ca');
local etcd_tls_cert = std.extVar('etcd_tls_cert');
local etcd_tls_key = std.extVar('etcd_tls_key');
local grafana_admin_password = std.extVar('grafana_admin_password');
local prometheus_data_retention_period = std.extVar('prometheus_data_retention_period');
local prometheus_request_memory = std.extVar('prometheus_request_memory');
// Derived variables
local alert_manager_host = 'alertmanager.' + cluster_identifier + '.myorg.local';
local grafana_host = 'grafana.' + cluster_identifier + '.myorg.local';
local prometheus_host = 'prometheus.' + cluster_identifier + '.myorg.local';
// ksonnet no longer required
local kp =
(import 'kube-prometheus/main.libsonnet') +
// kubeadm now achieved by setting platform value - see 9 lines below
(import 'kube-prometheus/addons/static-etcd.libsonnet') +
(import 'kube-prometheus/addons/podsecuritypolicies.libsonnet') +
{
values+:: {
common+: {
namespace: 'monitoring',
},
// Add kubeadm platform-specific items,
// including kube-contoller-manager and kube-scheduler discovery
kubePrometheus+: {
platform: 'kubeadm',
},
// Override alert manager config
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/examples/alertmanager-config-external.jsonnet
alertmanager+: {
config: importstr 'alertmanager.yaml',
},
// Override etcd config
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/jsonnet/kube-prometheus/addons/static-etcd.libsonnet
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/examples/etcd-skip-verify.jsonnet
etcd+:: {
clientCA: etcd_tls_ca,
clientCert: etcd_tls_cert,
clientKey: etcd_tls_key,
ips: [etcd_ip],
},
// Override grafana config
// anonymous access
// See http://docs.grafana.org/installation/configuration/
// See http://docs.grafana.org/auth/overview/#anonymous-authentication
// admin_password
// See http://docs.grafana.org/installation/configuration/#admin-password
grafana+:: {
config: {
sections: {
'auth.anonymous': {
enabled: true,
},
security: {
admin_password: grafana_admin_password,
},
},
},
// Additional grafana dashboards
dashboards+:: {
'my-specific.json': (import 'my-grafana-dashboard-definitions.json'),
},
},
},
// Alert manager needs an externalUrl
alertmanager+:: {
alertmanager+: {
spec+: {
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/exposing-prometheus-alertmanager-grafana-ingress.md
externalUrl: 'https://' + alert_manager_host,
},
},
},
// Add additional ingresses
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/examples/ingress.jsonnet
ingress+:: {
alertmanager: {
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: {
name: 'alertmanager',
namespace: $.values.common.namespace,
annotations: {
'kubernetes.io/ingress.class': 'nginx-api',
},
},
spec: {
rules: [{
host: alert_manager_host,
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'alertmanager-operated',
port: {
number: 9093,
},
},
},
}],
},
}],
tls: [{
hosts: [alert_manager_host],
}],
},
},
grafana: {
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: {
name: 'grafana',
namespace: $.values.common.namespace,
annotations: {
'kubernetes.io/ingress.class': 'nginx-api',
},
},
spec: {
rules: [{
host: grafana_host,
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'grafana',
port: {
number: 3000,
},
},
},
}],
},
}],
tls: [{
hosts: [grafana_host],
}],
},
},
prometheus: {
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: {
name: 'prometheus',
namespace: $.values.common.namespace,
annotations: {
'kubernetes.io/ingress.class': 'nginx-api',
},
},
spec: {
rules: [{
host: prometheus_host,
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'prometheus-operated',
port: {
number: 9090,
},
},
},
}],
},
}],
tls: [{
hosts: [prometheus_host],
}],
},
},
},
// Node exporter PSP role and role binding
nodeExporter+: {
'psp-role'+: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'Role',
metadata: {
name: 'node-exporter-psp',
namespace: $.values.common.namespace,
},
rules: [{
apiGroups: ['policy'],
resources: ['podsecuritypolicies'],
verbs: ['use'],
resourceNames: ['node-exporter'],
}],
},
'psp-rolebinding'+: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'RoleBinding',
metadata: {
name: 'node-exporter-psp',
namespace: $.values.common.namespace,
},
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
name: 'node-exporter-psp',
kind: 'Role',
},
subjects: [{
kind: 'ServiceAccount',
name: 'node-exporter',
}],
},
},
// Prometheus needs some extra custom config
prometheus+:: {
prometheus+: {
spec+: {
externalLabels: {
cluster: cluster_identifier,
},
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/exposing-prometheus-alertmanager-grafana-ingress.md
externalUrl: 'https://' + prometheus_host,
// Override reuest memory
resources: {
requests: {
memory: prometheus_request_memory,
},
},
// Override data retention period
retention: prometheus_data_retention_period,
},
},
},
// Additional prometheus rules
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/docs/developing-prometheus-rules-and-grafana-dashboards.md#pre-rendered-rules
// cat my-prometheus-rules.yaml | gojsontoyaml -yamltojson | jq . > my-prometheus-rules.json
prometheusMe: {
rules: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'PrometheusRule',
metadata: {
name: 'my-prometheus-rule',
namespace: $.values.common.namespace,
labels: {
'app.kubernetes.io/name': 'kube-prometheus',
'app.kubernetes.io/part-of': 'kube-prometheus',
prometheus: 'k8s',
role: 'alert-rules',
},
},
spec: {
groups: import 'my-prometheus-rules.json',
},
},
},
};
// Render
{ '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) }
{ [name + '-ingress']: kp.ingress[name] for name in std.objectFields(kp.ingress) } +
{ ['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) }
+ { ['prometheus-my-' + name]: kp.prometheusMe[name] for name in std.objectFields(kp.prometheusMe) }

View File

@ -0,0 +1,250 @@
## Example of conversion of a legacy my.jsonnet file
An example conversion of a legacy custom jsonnet file to release-0.8
format can be seen by viewing and comparing this
[release-0.3 jsonnet file](./my.release-0.3.jsonnet) (when the github
repo was under `https://github.com/coreos/kube-prometheus...`)
and the corresponding [release-0.8 jsonnet file](./my.release-0.8.jsonnet).
These two files have had necessary blank lines added so that they
can be compared side-by-side and line-by-line on screen.
The conversion covers both the change of stopping using ksonnet after
release-0.3 and also the major migration after release-0.7 as described in
[migration-guide.md](../migration-guide.md)
The sample files are intended as an example of format conversion and
not necessarily best practice for the files in release-0.3 or release-0.8.
Below are three sample extracts of the conversion as an indication of the
changes required.
<table>
<tr>
<th> release-0.3 </th>
<th> release-0.8 </th>
</tr>
<tr>
<td>
```jsonnet
local kp =
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') +
(import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') +
{
_config+:: {
// Override namespace
namespace: 'monitoring',
```
</td>
<td>
```jsonnet
local kp =
(import 'kube-prometheus/main.libsonnet') +
// kubeadm now achieved by setting platform value - see 9 lines below
(import 'kube-prometheus/addons/static-etcd.libsonnet') +
(import 'kube-prometheus/addons/podsecuritypolicies.libsonnet') +
{
values+:: {
common+: {
namespace: 'monitoring',
},
// Add kubeadm platform-specific items,
// including kube-contoller-manager and kube-scheduler discovery
kubePrometheus+: {
platform: 'kubeadm',
},
```
</td>
</tr>
</table>
<table>
<tr>
<th> release-0.3 </th>
<th> release-0.8 </th>
</tr>
<tr>
<td>
```jsonnet
// Add additional ingresses
// See https://github.com/coreos/kube-prometheus/...
// tree/master/examples/ingress.jsonnet
ingress+:: {
alertmanager:
ingress.new() +
ingress.mixin.metadata.withName('alertmanager') +
ingress.mixin.metadata.withNamespace($._config.namespace) +
ingress.mixin.metadata.withAnnotations({
'kubernetes.io/ingress.class': 'nginx-api',
}) +
ingress.mixin.spec.withRules(
ingressRule.new() +
ingressRule.withHost(alert_manager_host) +
ingressRule.mixin.http.withPaths(
ingressRuleHttpPath.new() +
ingressRuleHttpPath.mixin.backend
.withServiceName('alertmanager-operated') +
ingressRuleHttpPath.mixin.backend.withServicePort(9093)
),
) +
// Note we do not need a TLS secretName here as we are going to use the
// nginx-ingress default secret which is a wildcard
// secretName would need to be in the same namespace at this time,
// see https://github.com/kubernetes/ingress-nginx/issues/2371
ingress.mixin.spec.withTls(
ingressTls.new() +
ingressTls.withHosts(alert_manager_host)
),
```
</td>
<td>
```jsonnet
// Add additional ingresses
// See https://github.com/prometheus-operator/kube-prometheus/...
// blob/main/examples/ingress.jsonnet
ingress+:: {
alertmanager: {
apiVersion: 'networking.k8s.io/v1',
kind: 'Ingress',
metadata: {
name: 'alertmanager',
namespace: $.values.common.namespace,
annotations: {
'kubernetes.io/ingress.class': 'nginx-api',
},
},
spec: {
rules: [{
host: alert_manager_host,
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'alertmanager-operated',
port: {
number: 9093,
},
},
},
}],
},
}],
tls: [{
hosts: [alert_manager_host],
}],
},
},
```
</td>
</tr>
</table>
<table>
<tr>
<th> release-0.3 </th>
<th> release-0.8 </th>
</tr>
<tr>
<td>
```jsonnet
// Additional prometheus rules
// See https://github.com/coreos/kube-prometheus/docs/...
// developing-prometheus-rules-and-grafana-dashboards.md
//
// cat my-prometheus-rules.yaml | \
// gojsontoyaml -yamltojson | \
// jq . > my-prometheus-rules.json
prometheusRules+:: {
groups+: import 'my-prometheus-rules.json',
},
};
```
</td>
<td>
```jsonnet
// Additional prometheus rules
// See https://github.com/prometheus-operator/kube-prometheus/blob/main/...
// docs/developing-prometheus-rules-and-grafana-dashboards.md...
// #pre-rendered-rules
// cat my-prometheus-rules.yaml | \
// gojsontoyaml -yamltojson | \
// jq . > my-prometheus-rules.json
prometheusMe: {
rules: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'PrometheusRule',
metadata: {
name: 'my-prometheus-rule',
namespace: $.values.common.namespace,
labels: {
'app.kubernetes.io/name': 'kube-prometheus',
'app.kubernetes.io/part-of': 'kube-prometheus',
prometheus: 'k8s',
role: 'alert-rules',
},
},
spec: {
groups: import 'my-prometheus-rules.json',
},
},
},
};
...
+ { ['prometheus-my-' + name]: kp.prometheusMe[name] for name in std.objectFields(kp.prometheusMe) }
```
</td>
</tr>
</table>

87
docs/migration-guide.md Normal file
View File

@ -0,0 +1,87 @@
# 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)
## Legacy migration
An example of conversion of a legacy release-0.3 my.jsonnet file to release-0.8 can be found in [migration-example](./migration-example)
## 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/

View File

@ -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:

View File

@ -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
@ -7,7 +20,7 @@ This is done in the variable `prometheus.roleSpecificNamespaces`. You usually se
Example to create the needed `Role` and `RoleBinding` for the Namespace `foo` :
```
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
local kp = (import 'kube-prometheus/main.libsonnet') + {
_config+:: {
namespace: 'monitoring',

View File

@ -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
View 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"],
},
},
},
};
```

View File

@ -1,28 +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/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) }

View File

@ -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) }

View File

@ -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'],
},
},

View File

@ -1,5 +1,5 @@
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
_config+:: {
((import 'kube-prometheus/main.libsonnet') + {
values+:: {
alertmanager+: {
config: importstr 'alertmanager-config.yaml',
},

View File

@ -1,5 +1,5 @@
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
_config+:: {
((import 'kube-prometheus/main.libsonnet') + {
values+:: {
alertmanager+: {
config: |||
global:

View File

@ -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: [],
},
},

View File

@ -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) } +

View File

@ -0,0 +1,92 @@
local filter = {
kubernetesControlPlane+: {
prometheusRule+:: {
spec+: {
groups: std.map(
function(group)
if group.name == 'kubernetes-apps' then
group {
rules: std.filter(
function(rule)
rule.alert != 'KubeStatefulSetReplicasMismatch',
group.rules
),
}
else
group,
super.groups
),
},
},
},
};
local update = {
kubernetesControlPlane+: {
prometheusRule+:: {
spec+: {
groups: std.map(
function(group)
if group.name == 'kubernetes-apps' then
group {
rules: std.map(
function(rule)
if rule.alert == 'KubePodCrashLooping' then
rule {
expr: 'rate(kube_pod_container_status_restarts_total{namespace=kube-system,job="kube-state-metrics"}[10m]) * 60 * 5 > 0',
}
else
rule,
group.rules
),
}
else
group,
super.groups
),
},
},
},
};
local add = {
exampleApplication:: {
prometheusRule+: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'PrometheusRule',
metadata: {
name: 'example-application-rules',
namespace: $.values.common.namespace,
},
spec: (import 'existingrule.json'),
},
},
};
local kp = (import 'kube-prometheus/main.libsonnet') +
filter +
update +
add + {
values+:: {
common+: {
namespace: 'monitoring',
},
},
};
{ '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 } +
{ ['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) } +
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) } +
{ ['exampleApplication-' + name]: kp.exampleApplication[name] for name in std.objectFields(kp.exampleApplication) }

View File

@ -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',
},
},
};

View File

@ -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',
},
],
},
],
},
],
},
},
};

View File

@ -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',

View File

@ -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'],

View File

@ -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"}}]}]}

View File

@ -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.

View File

@ -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)')))
),
},
},
},
};

View File

@ -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'),
},
},
},
};

View File

@ -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'),
},
},
},
};

View File

@ -0,0 +1,25 @@
local kp =
(import 'kube-prometheus/main.libsonnet') +
{
values+:: {
common+: {
namespace: 'monitoring',
},
},
// Disable all grafana-related objects apart from dashboards and datasource
grafana: {
dashboardSources:: {},
deployment:: {},
serviceAccount:: {},
serviceMonitor:: {},
service:: {},
},
};
// Manifestation
{
[component + '-' + resource + '.json']: kp[component][resource]
for component in std.objectFields(kp)
for resource in std.objectFields(kp[component])
}

View File

@ -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,15 +49,19 @@ local kp =
ingress+:: {
'alertmanager-main': ingress(
'alertmanager-main',
$._config.namespace,
$.values.common.namespace,
[{
host: 'alertmanager.example.com',
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'alertmanager-main',
port: 'web',
port: {
name: 'web',
},
},
},
}],
@ -64,15 +70,19 @@ local kp =
),
grafana: ingress(
'grafana',
$._config.namespace,
$.values.common.namespace,
[{
host: 'grafana.example.com',
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'grafana',
port: 'http',
port: {
name: 'http',
},
},
},
}],
@ -81,15 +91,19 @@ local kp =
),
'prometheus-k8s': ingress(
'prometheus-k8s',
$._config.namespace,
$.values.common.namespace,
[{
host: 'prometheus.example.com',
http: {
paths: [{
path: '/',
pathType: 'Prefix',
backend: {
service: {
name: 'prometheus-k8s',
port: 'web',
port: {
name: 'web',
},
},
},
}],
@ -105,7 +119,7 @@ local kp =
kind: 'Secret',
metadata: {
name: 'basic-auth',
namespace: $._config.namespace,
namespace: $.values.common.namespace,
},
data: { auth: std.base64(importstr 'auth') },
type: 'Opaque',

View File

@ -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');

View File

@ -1,2 +0,0 @@
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-bootkube.libsonnet')

View File

@ -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')

View File

@ -1,2 +0,0 @@
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-kops.libsonnet')

View File

@ -1,2 +0,0 @@
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-kube-aws.libsonnet')

View File

@ -1,2 +0,0 @@
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet')

View File

@ -1,2 +0,0 @@
(import 'kube-prometheus/kube-prometheus.libsonnet') +
(import 'kube-prometheus/kube-prometheus-kubespray.libsonnet')

View File

@ -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')

View File

@ -0,0 +1,8 @@
(import 'kube-prometheus/main.libsonnet') +
{
values+:: {
common+: {
platform: 'example-platform',
},
},
}

View File

@ -1,4 +1,4 @@
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
((import 'kube-prometheus/main.libsonnet') + {
nodeExporter+: {
daemonset+: {
metadata+: {

View File

@ -0,0 +1,20 @@
local kp = (import 'kube-prometheus/main.libsonnet') + {
values+:: {
common+: {
namespace: 'monitoring',
},
kubernetesControlPlane+: {
kubeProxy: true,
},
},
};
{ ['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) } +
{ ['kubernetes-' + name]: kp.kubernetesControlPlane[name] for name in std.objectFields(kp.kubernetesControlPlane) }

View File

@ -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 = {

View File

@ -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+: {

View File

@ -0,0 +1,30 @@
local addMixin = (import 'kube-prometheus/lib/mixin.libsonnet');
local etcdMixin = addMixin({
name: 'etcd',
mixin: (import 'github.com/etcd-io/etcd/contrib/mixin/mixin.libsonnet') + {
_config+: {}, // mixin configuration object
},
});
local kp = (import 'kube-prometheus/main.libsonnet') +
{
values+:: {
common+: {
namespace: 'monitoring',
},
grafana+: {
// Adding new dashboard to grafana. This will modify grafana configMap with dashboards
dashboards+: etcdMixin.grafanaDashboards,
},
},
};
{ ['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) } +
// Rendering prometheusRules object. This is an object compatible with prometheus-operator CRD definition for prometheusRule
{ 'external-mixins/etcd-mixin-prometheus-rules': etcdMixin.prometheusRules }

View 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) }

View File

@ -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) }

View File

@ -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) }

View File

@ -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) }

View File

@ -1,4 +1,4 @@
((import 'kube-prometheus/kube-prometheus.libsonnet') + {
((import 'kube-prometheus/main.libsonnet') + {
prometheus+: {
prometheus+: {
metadata+: {

View File

@ -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+:: {

View File

@ -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',
},
},
};

View 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) }

View File

@ -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',
},
],
},
},
},

View File

@ -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
View 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) }

6
go.mod
View File

@ -1,13 +1,9 @@
module github.com/prometheus-operator/kube-prometheus
go 1.13
go 1.15
require (
github.com/Jeffail/gabs v1.4.0
github.com/brancz/gojsontoyaml v0.0.0-20200602132005-3697ded27e8c
github.com/campoy/embedmd v1.0.0
github.com/google/go-jsonnet v0.16.1-0.20200703153429-aaf50f5b655f
github.com/jsonnet-bundler/jsonnet-bundler v0.4.0
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.8.0
k8s.io/apimachinery v0.19.3

23
go.sum
View File

@ -54,10 +54,6 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/brancz/gojsontoyaml v0.0.0-20200602132005-3697ded27e8c h1:hb6WqfcKQZlNx/vahy51SaIvKnoXD5609Nm0PC4msEM=
github.com/brancz/gojsontoyaml v0.0.0-20200602132005-3697ded27e8c/go.mod h1:+00lOjYXPgMfxHVPvg9GDtc3BX5Xh5aFpB4gMB8gfMo=
github.com/campoy/embedmd v1.0.0 h1:V4kI2qTJJLf4J29RzI/MAt2c3Bl4dQSYPuflzwFH2hY=
github.com/campoy/embedmd v1.0.0/go.mod h1:oxyr9RCiSXg0M3VJ3ks0UGfp98BpSSGr0kpiX3MzVl8=
github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
@ -93,8 +89,6 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4=
github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -155,8 +149,6 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-jsonnet v0.16.1-0.20200703153429-aaf50f5b655f h1:mw4KoMG5/DXLPhpKXQRYTEIZFkFo0a1HU2R1HbeYpek=
github.com/google/go-jsonnet v0.16.1-0.20200703153429-aaf50f5b655f/go.mod h1:sOcuej3UW1vpPTZOr8L7RQimqai1a57bt5j22LzGZCw=
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g=
@ -216,8 +208,6 @@ github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/jsonnet-bundler/jsonnet-bundler v0.4.0 h1:4BKZ6LDqPc2wJDmaKnmYD/vDjUptJtnUpai802MibFc=
github.com/jsonnet-bundler/jsonnet-bundler v0.4.0/go.mod h1:/by7P/OoohkI3q4CgSFqcoFsVY+IaNbzOVDknEsKDeU=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
@ -241,15 +231,8 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
github.com/mattn/go-colorable v0.0.9 h1:UVL0vNpWh04HeJXV0KLcaT7r06gOH2l4OW6ddYRUIY4=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.6 h1:SrwhHcpV4nWrMGdNcC2kXpMfcBVYGDuTArqyhocJgvA=
github.com/mattn/go-isatty v0.0.6/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM=
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
@ -344,8 +327,6 @@ github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
@ -462,8 +443,6 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190310054646-10058d7d4faa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@ -474,8 +453,6 @@ golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
# exit immediately when a command fails
set -e
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
# error on unset variables
set -u
kubectl apply -f examples/example-app

View File

@ -1,9 +0,0 @@
#!/usr/bin/env bash
# exit immediately when a command fails
set -e
# only exit with zero if all commands of the pipeline exit successfully
set -o pipefail
# error on unset variables
set -u
kubectl delete -f examples/example-app

View File

@ -0,0 +1,22 @@
{
prometheus+:: {
clusterRole+: {
rules+: [
{
apiGroups: [''],
resources: ['services', 'endpoints', 'pods'],
verbs: ['get', 'list', 'watch'],
},
{
apiGroups: ['networking.k8s.io'],
resources: ['ingresses'],
verbs: ['get', 'list', 'watch'],
},
],
},
// There is no need for specific namespaces RBAC as this addon grants
// all required permissions for every namespace
roleBindingSpecificNamespaces:: null,
roleSpecificNamespaces:: null,
},
}

View 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',
},
},
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,
),
},
},
},
},
}

View File

@ -0,0 +1,110 @@
{
values+:: {
awsVpcCni: {
// `minimumWarmIPs` should be inferior or equal to `WARM_IP_TARGET`.
//
// References:
// https://github.com/aws/amazon-vpc-cni-k8s/blob/v1.9.0/docs/eni-and-ip-target.md
// https://github.com/aws/amazon-vpc-cni-k8s/blob/v1.9.0/pkg/ipamd/ipamd.go#L61-L71
minimumWarmIPs: 10,
minimumWarmIPsTime: '10m',
},
},
kubernetesControlPlane+: {
serviceAwsVpcCni: {
apiVersion: 'v1',
kind: 'Service',
metadata: {
name: 'aws-node',
namespace: 'kube-system',
labels: { 'app.kubernetes.io/name': 'aws-node' },
},
spec: {
ports: [
{
name: 'cni-metrics-port',
port: 61678,
targetPort: 61678,
},
],
selector: { 'app.kubernetes.io/name': 'aws-node' },
clusterIP: 'None',
},
},
serviceMonitorAwsVpcCni: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'ServiceMonitor',
metadata: {
name: 'aws-node',
namespace: $.values.common.namespace,
labels: {
'app.kubernetes.io/name': 'aws-node',
},
},
spec: {
jobLabel: 'app.kubernetes.io/name',
selector: {
matchLabels: {
'app.kubernetes.io/name': 'aws-node',
},
},
namespaceSelector: {
matchNames: [
'kube-system',
],
},
endpoints: [
{
port: 'cni-metrics-port',
interval: '30s',
path: '/metrics',
relabelings: [
{
action: 'replace',
regex: '(.*)',
replacement: '$1',
sourceLabels: ['__meta_kubernetes_pod_node_name'],
targetLabel: 'instance',
},
],
},
],
},
},
prometheusRuleAwsVpcCni: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'PrometheusRule',
metadata: {
labels: $.prometheus._config.commonLabels + $.prometheus._config.mixin.ruleLabels,
name: 'aws-vpc-cni-rules',
namespace: $.prometheus._config.namespace,
},
spec: {
groups: [
{
name: 'aws-vpc-cni.rules',
rules: [
{
expr: 'sum by(instance) (awscni_total_ip_addresses) - sum by(instance) (awscni_assigned_ip_addresses) < %s' % $.values.awsVpcCni.minimumWarmIPs,
labels: {
severity: 'critical',
},
annotations: {
summary: 'AWS VPC CNI has a low warm IP pool',
description: |||
Instance {{ $labels.instance }} has only {{ $value }} warm IPs which is lower than set threshold of %s.
It could mean the current subnet is out of available IP addresses or the CNI is unable to request them from the EC2 API.
||| % $.values.awsVpcCni.minimumWarmIPs,
},
'for': $.values.awsVpcCni.minimumWarmIPsTime,
alert: 'AwsVpcCniWarmIPsLow',
},
],
},
],
},
},
},
}

View File

@ -0,0 +1,36 @@
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
// grafana/grafana -> grafana $repository/grafana
local withImageRepository(repository) = {
local oldRepos = super.values.common.images,
local substituteRepository(image, repository) =
if repository == null then image else repository + '/' + imageName(image),
values+:: {
common+:: {
images:: {
[field]: substituteRepository(oldRepos[field], repository)
for field in std.objectFields(oldRepos)
},
},
},
};
{
withImageRepository:: withImageRepository,
}

View File

@ -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',
@ -133,7 +133,6 @@
metadata: {
name: 'custom-metrics-server-resources',
},
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'ClusterRole',
@ -142,7 +141,7 @@
subjects: [{
kind: 'ServiceAccount',
name: $.prometheusAdapter.serviceAccount.metadata.name,
namespace: $._config.prometheusAdapter.namespace,
namespace: $.values.prometheusAdapter.namespace,
}],
},
customMetricsClusterRoleBindingHPA: {
@ -151,7 +150,6 @@
metadata: {
name: 'hpa-controller-custom-metrics',
},
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'ClusterRole',

View File

@ -0,0 +1,139 @@
[
// Drop all kubelet metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'kubelet_(pod_worker_latency_microseconds|pod_start_latency_microseconds|cgroup_manager_latency_microseconds|pod_worker_start_latency_microseconds|pleg_relist_latency_microseconds|pleg_relist_interval_microseconds|runtime_operations|runtime_operations_latency_microseconds|runtime_operations_errors|eviction_stats_age_microseconds|device_plugin_registration_count|device_plugin_alloc_latency_microseconds|network_plugin_operations_latency_microseconds)',
action: 'drop',
},
// Drop all scheduler metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'scheduler_(e2e_scheduling_latency_microseconds|scheduling_algorithm_predicate_evaluation|scheduling_algorithm_priority_evaluation|scheduling_algorithm_preemption_evaluation|scheduling_algorithm_latency_microseconds|binding_latency_microseconds|scheduling_latency_seconds)',
action: 'drop',
},
// Drop all apiserver metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'apiserver_(request_count|request_latencies|request_latencies_summary|dropped_requests|storage_data_key_generation_latencies_microseconds|storage_transformation_failures_total|storage_transformation_latencies_microseconds|proxy_tunnel_sync_latency_secs)',
action: 'drop',
},
// Drop all docker metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'kubelet_docker_(operations|operations_latency_microseconds|operations_errors|operations_timeout)',
action: 'drop',
},
// Drop all reflector metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'reflector_(items_per_list|items_per_watch|list_duration_seconds|lists_total|short_watches_total|watch_duration_seconds|watches_total)',
action: 'drop',
},
// Drop all etcd metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'etcd_(helper_cache_hit_count|helper_cache_miss_count|helper_cache_entry_count|object_counts|request_cache_get_latencies_summary|request_cache_add_latencies_summary|request_latencies_summary)',
action: 'drop',
},
// Drop all transformation metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: 'transformation_(transformation_latencies_microseconds|failures_total)',
action: 'drop',
},
// Drop all other metrics which are deprecated in kubernetes.
{
sourceLabels: ['__name__'],
regex: '(' + std.join('|',
[
'admission_quota_controller_adds',
'admission_quota_controller_depth',
'admission_quota_controller_longest_running_processor_microseconds',
'admission_quota_controller_queue_latency',
'admission_quota_controller_unfinished_work_seconds',
'admission_quota_controller_work_duration',
'APIServiceOpenAPIAggregationControllerQueue1_adds',
'APIServiceOpenAPIAggregationControllerQueue1_depth',
'APIServiceOpenAPIAggregationControllerQueue1_longest_running_processor_microseconds',
'APIServiceOpenAPIAggregationControllerQueue1_queue_latency',
'APIServiceOpenAPIAggregationControllerQueue1_retries',
'APIServiceOpenAPIAggregationControllerQueue1_unfinished_work_seconds',
'APIServiceOpenAPIAggregationControllerQueue1_work_duration',
'APIServiceRegistrationController_adds',
'APIServiceRegistrationController_depth',
'APIServiceRegistrationController_longest_running_processor_microseconds',
'APIServiceRegistrationController_queue_latency',
'APIServiceRegistrationController_retries',
'APIServiceRegistrationController_unfinished_work_seconds',
'APIServiceRegistrationController_work_duration',
'autoregister_adds',
'autoregister_depth',
'autoregister_longest_running_processor_microseconds',
'autoregister_queue_latency',
'autoregister_retries',
'autoregister_unfinished_work_seconds',
'autoregister_work_duration',
'AvailableConditionController_adds',
'AvailableConditionController_depth',
'AvailableConditionController_longest_running_processor_microseconds',
'AvailableConditionController_queue_latency',
'AvailableConditionController_retries',
'AvailableConditionController_unfinished_work_seconds',
'AvailableConditionController_work_duration',
'crd_autoregistration_controller_adds',
'crd_autoregistration_controller_depth',
'crd_autoregistration_controller_longest_running_processor_microseconds',
'crd_autoregistration_controller_queue_latency',
'crd_autoregistration_controller_retries',
'crd_autoregistration_controller_unfinished_work_seconds',
'crd_autoregistration_controller_work_duration',
'crdEstablishing_adds',
'crdEstablishing_depth',
'crdEstablishing_longest_running_processor_microseconds',
'crdEstablishing_queue_latency',
'crdEstablishing_retries',
'crdEstablishing_unfinished_work_seconds',
'crdEstablishing_work_duration',
'crd_finalizer_adds',
'crd_finalizer_depth',
'crd_finalizer_longest_running_processor_microseconds',
'crd_finalizer_queue_latency',
'crd_finalizer_retries',
'crd_finalizer_unfinished_work_seconds',
'crd_finalizer_work_duration',
'crd_naming_condition_controller_adds',
'crd_naming_condition_controller_depth',
'crd_naming_condition_controller_longest_running_processor_microseconds',
'crd_naming_condition_controller_queue_latency',
'crd_naming_condition_controller_retries',
'crd_naming_condition_controller_unfinished_work_seconds',
'crd_naming_condition_controller_work_duration',
'crd_openapi_controller_adds',
'crd_openapi_controller_depth',
'crd_openapi_controller_longest_running_processor_microseconds',
'crd_openapi_controller_queue_latency',
'crd_openapi_controller_retries',
'crd_openapi_controller_unfinished_work_seconds',
'crd_openapi_controller_work_duration',
'DiscoveryController_adds',
'DiscoveryController_depth',
'DiscoveryController_longest_running_processor_microseconds',
'DiscoveryController_queue_latency',
'DiscoveryController_retries',
'DiscoveryController_unfinished_work_seconds',
'DiscoveryController_work_duration',
'kubeproxy_sync_proxy_rules_latency_microseconds',
'non_structural_schema_condition_controller_adds',
'non_structural_schema_condition_controller_depth',
'non_structural_schema_condition_controller_longest_running_processor_microseconds',
'non_structural_schema_condition_controller_queue_latency',
'non_structural_schema_condition_controller_retries',
'non_structural_schema_condition_controller_unfinished_work_seconds',
'non_structural_schema_condition_controller_work_duration',
'rest_client_request_latency_seconds',
'storage_operation_errors_total',
'storage_operation_status_count',
]) + ')',
action: 'drop',
},
]

View File

@ -0,0 +1,95 @@
// External metrics API allows the HPA v2 to scale based on metrics coming from outside of Kubernetes cluster
// For more details on usage visit https://github.com/DirectXMan12/k8s-prometheus-adapter#quick-links
{
values+:: {
prometheusAdapter+: {
namespace: $.values.common.namespace,
// Rules for external-metrics
config+:: {
externalRules+: [
// {
// seriesQuery: '{__name__=~"^.*_queue$",namespace!=""}',
// seriesFilters: [],
// resources: {
// overrides: {
// namespace: { resource: 'namespace' }
// },
// },
// name: { matches: '^.*_queue$', as: '$0' },
// metricsQuery: 'max(<<.Series>>{<<.LabelMatchers>>})',
// },
],
},
},
},
prometheusAdapter+: {
externalMetricsApiService: {
apiVersion: 'apiregistration.k8s.io/v1',
kind: 'APIService',
metadata: {
name: 'v1beta1.external.metrics.k8s.io',
},
spec: {
service: {
name: $.prometheusAdapter.service.metadata.name,
namespace: $.values.prometheusAdapter.namespace,
},
group: 'external.metrics.k8s.io',
version: 'v1beta1',
insecureSkipTLSVerify: true,
groupPriorityMinimum: 100,
versionPriority: 100,
},
},
externalMetricsClusterRoleServerResources: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'ClusterRole',
metadata: {
name: 'external-metrics-server-resources',
},
rules: [{
apiGroups: ['external.metrics.k8s.io'],
resources: ['*'],
verbs: ['*'],
}],
},
externalMetricsClusterRoleBindingServerResources: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'ClusterRoleBinding',
metadata: {
name: 'external-metrics-server-resources',
},
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'ClusterRole',
name: 'external-metrics-server-resources',
},
subjects: [{
kind: 'ServiceAccount',
name: $.prometheusAdapter.serviceAccount.metadata.name,
namespace: $.values.prometheusAdapter.namespace,
}],
},
externalMetricsClusterRoleBindingHPA: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'ClusterRoleBinding',
metadata: {
name: 'hpa-controller-external-metrics',
},
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'ClusterRole',
name: 'external-metrics-server-resources',
},
subjects: [{
kind: 'ServiceAccount',
name: 'horizontal-pod-autoscaler',
namespace: 'kube-system',
}],
},
},
}

View File

@ -1,5 +1,5 @@
{
prometheus+:: {
prometheus+: {
serviceMonitorKubelet+:
{
spec+: {

View File

@ -0,0 +1,136 @@
{
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+: {
clusterRole: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'ClusterRole',
metadata: { name: 'ksm-autoscaler' },
rules: [{
apiGroups: [''],
resources: ['nodes'],
verbs: ['list', 'watch'],
}],
},
clusterRoleBinding: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'ClusterRoleBinding',
metadata: { name: 'ksm-autoscaler' },
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'ClusterRole',
name: 'ksm-autoscaler',
},
subjects: [{ kind: 'ServiceAccount', name: 'ksm-autoscaler', namespace: $.values.common.namespace }],
},
roleBinding: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'RoleBinding',
metadata: {
name: 'ksm-autoscaler',
namespace: $.values.common.namespace,
},
roleRef: {
apiGroup: 'rbac.authorization.k8s.io',
kind: 'Role',
name: 'ksm-autoscaler',
},
subjects: [{ kind: 'ServiceAccount', name: 'ksm-autoscaler' }],
},
role: {
apiVersion: 'rbac.authorization.k8s.io/v1',
kind: 'Role',
metadata: {
name: 'ksm-autoscaler',
namespace: $.values.common.namespace,
},
rules: [
{
apiGroups: ['extensions'],
resources: ['deployments'],
verbs: ['patch'],
resourceNames: ['kube-state-metrics'],
},
{
apiGroups: ['apps'],
resources: ['deployments'],
verbs: ['patch'],
resourceNames: ['kube-state-metrics'],
},
],
},
serviceAccount: {
apiVersion: 'v1',
kind: 'ServiceAccount',
metadata: {
name: 'ksm-autoscaler',
namespace: $.values.common.namespace,
},
},
deployment:
local podLabels = { app: 'ksm-autoscaler' };
local c = {
name: 'ksm-autoscaler',
image: $.values.clusterVerticalAutoscaler.image,
args: [
'/cpvpa',
'--target=deployment/kube-state-metrics',
'--namespace=' + $.values.common.namespace,
'--logtostderr=true',
'--poll-period-seconds=10',
'--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' },
},
};
{
apiVersion: 'apps/v1',
kind: 'Deployment',
metadata: {
name: 'ksm-autoscaler',
namespace: $.values.common.namespace,
labels: podLabels,
},
spec: {
replicas: 1,
selector: { matchLabels: podLabels },
template: {
metadata: {
labels: podLabels,
},
spec: {
containers: [c],
serviceAccount: 'ksm-autoscaler',
nodeSelector: { 'kubernetes.io/os': 'linux' },
securityContext: {
runAsNonRoot: true,
runAsUser: 65534,
},
},
},
},
},
},
}

View 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
),
},
},
},
},
},
}

View 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'])
],
},
},
},
}

View File

@ -1,6 +1,6 @@
local patch(ports) = {
spec+: {
ports+: ports,
ports: ports,
type: 'NodePort',
},
};

View File

@ -0,0 +1,264 @@
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
{
metadata+: {
name: 'blackbox-exporter-psp',
},
};
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],
}],
},
},
}

View File

@ -1,7 +1,5 @@
local k = import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet';
(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,
@ -11,14 +9,14 @@ local k = import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet';
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: [
@ -28,23 +26,23 @@ local k = import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet';
},
},
endpointsEtcd: {
apiVersion: 'v1',
kind: 'Endpoints',
metadata: {
name: 'etcd',
namespace: 'kube-system',
labels: { 'k8s-app': 'etcd' },
},
subsets: [{
addresses: [
{ ip: etcdIP }
for etcdIP in $._config.etcd.ips
],
ports: [
{ name: 'metrics', port: 2379, protocol: 'TCP' },
],
}],
apiVersion: 'v1',
kind: 'Endpoints',
metadata: {
name: 'etcd',
namespace: 'kube-system',
labels: { 'app.kubernetes.io/name': 'etcd' },
},
subsets: [{
addresses: [
{ ip: etcdIP }
for etcdIP in $.values.etcd.ips
],
ports: [
{ name: 'metrics', port: 2379, protocol: 'TCP' },
],
}],
},
serviceMonitorEtcd: {
apiVersion: 'monitoring.coreos.com/v1',
kind: 'ServiceMonitor',
@ -52,11 +50,11 @@ local k = import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet';
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',
@ -67,14 +65,14 @@ local k = import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet';
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',
},
},
},
@ -86,20 +84,19 @@ local k = import 'github.com/ksonnet/ksonnet-lib/ksonnet.beta.4/k.libsonnet';
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+:
{
// Reference info: https://coreos.com/operators/prometheus/docs/latest/api.html#prometheusspec
spec+: {
secrets+: [$.prometheus.secretEtcdCerts.metadata.name],
},
prometheus+: {
// Reference info: https://coreos.com/operators/prometheus/docs/latest/api.html#prometheusspec
spec+: {
secrets+: [$.prometheus.secretEtcdCerts.metadata.name],
},
},
},
}

View 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-limit=0', '--config-reloader-memory-limit=0'] }
else c,
containers: std.map(addArgs, super.containers),
},
},
},
},
},
}

View 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.',
},
},
]

View 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'),
},
},
},
}

Some files were not shown because too many files have changed in this diff Show More