Merge pull request #1732 from jolson490/kube-prometheus_documentation
kube-prometheus documentation
This commit is contained in:
253
README.md
253
README.md
@@ -22,16 +22,24 @@ This stack is meant for cluster monitoring, so it is pre-configured to collect m
|
||||
* [Prerequisites](#prerequisites)
|
||||
* [minikube](#minikube)
|
||||
* [Quickstart](#quickstart)
|
||||
* [Usage](#usage)
|
||||
* [Customizing Kube-Prometheus](#customizing-kube-prometheus)
|
||||
* [Installing](#installing)
|
||||
* [Compiling](#compiling)
|
||||
* [Containerized Installing and Compiling](#containerized-installing-and-compiling)
|
||||
* [Configuration](#configuration)
|
||||
* [Customization](#customization)
|
||||
* [Customization Examples](#customization-examples)
|
||||
* [Cluster Creation Tools](#cluster-creation-tools)
|
||||
* [NodePorts](#nodeports)
|
||||
* [Prometheus Object Name](#prometheus-object-name)
|
||||
* [node-exporter DaemonSet namespace](#node-exporter-daemonset-namespace)
|
||||
* [Alertmanager configuration](#alertmanager-configuration)
|
||||
* [Static etcd configuration](#static-etcd-configuration)
|
||||
* [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)
|
||||
* [Minikube Example](#minikube-example)
|
||||
* [Troubleshooting](#troubleshooting)
|
||||
* [Error retrieving kubelet metrics](#error-retrieving-kubelet-metrics)
|
||||
* [kube-state-metrics resource usage](#kube-state-metrics-resource-usage)
|
||||
* [Contributing](#contributing)
|
||||
|
||||
## Prerequisites
|
||||
@@ -53,29 +61,49 @@ $ minikube delete && minikube start --kubernetes-version=v1.10.1 --memory=4096 -
|
||||
|
||||
## Quickstart
|
||||
|
||||
Although this project is intended to be used as a library, a compiled version of the Kubernetes manifests generated with this library is checked into this repository in order to try the content out quickly.
|
||||
|
||||
Simply create the stack:
|
||||
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).
|
||||
|
||||
Though for a quickstart a compiled version of the Kubernetes [manifests](manifests) generated with this library (specifically with `example.jsonnet`) is checked into this repository in order to try the content out quickly. To try out the stack un-customized run:
|
||||
* Simply create the stack:
|
||||
```
|
||||
$ kubectl create -f manifests/
|
||||
$ kubectl create -f manifests/ || true
|
||||
$ kubectl create -f manifests/ 2>/dev/null || true # This command sometimes may need to be done twice
|
||||
```
|
||||
* And to teardown the stack:
|
||||
```
|
||||
$ kubectl delete -f manifests/ || true
|
||||
```
|
||||
|
||||
## Usage
|
||||
## Customizing Kube-Prometheus
|
||||
|
||||
This section:
|
||||
* describes how to customize the kube-prometheus library via compiling the kube-prometheus manifests yourself (as an alternative to the [Quickstart section](#Quickstart)).
|
||||
* still doesn't require you to make a copy of this entire repository, but rather only a copy of a few select files.
|
||||
|
||||
### Installing
|
||||
|
||||
The content of this project consists of a set of [jsonnet](http://jsonnet.org/) files making up a library to be consumed.
|
||||
|
||||
Install this library in your own project with [jsonnet-bundler](https://github.com/jsonnet-bundler/jsonnet-bundler#install):
|
||||
|
||||
Install this library in your own project with [jsonnet-bundler](https://github.com/jsonnet-bundler/jsonnet-bundler#install) (the jsonnet package manager):
|
||||
```
|
||||
$ mkdir my-kube-prometheus; cd my-kube-prometheus
|
||||
$ jb init
|
||||
$ jb install github.com/coreos/prometheus-operator/contrib/kube-prometheus/jsonnet/kube-prometheus
|
||||
$ jb init # Creates the initial/empty `jsonnetfile.json`
|
||||
# Install the kube-prometheus dependency
|
||||
$ jb install github.com/coreos/prometheus-operator/contrib/kube-prometheus/jsonnet/kube-prometheus # Creates `vendor/` & `jsonnetfile.lock.json`, and fills in `jsonnetfile.json`
|
||||
```
|
||||
|
||||
> `jb` can be installed with `go get github.com/jsonnet-bundler/jsonnet-bundler/cmd/jb`
|
||||
|
||||
You may wish to not use ksonnet and simply render the generated manifests to files on disk, this can be done with:
|
||||
> An e.g. of how to install a given version of this library: `jb install github.com/coreos/prometheus-operator/contrib/kube-prometheus/jsonnet/kube-prometheus/@v0.22.0`
|
||||
|
||||
In order to update the kube-prometheus dependency, simply use the jsonnet-bundler update functionality:
|
||||
`$ jb update`
|
||||
|
||||
### Compiling
|
||||
|
||||
e.g. of how to compile the manifests: `./build.sh example.jsonnet`
|
||||
|
||||
Here's [example.jsonnet](example.jsonnet):
|
||||
|
||||
[embedmd]:# (example.jsonnet)
|
||||
```jsonnet
|
||||
@@ -94,15 +122,14 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
```
|
||||
|
||||
This renders all manifests in a json structure of `{filename: manifest-content}`.
|
||||
|
||||
### Compiling
|
||||
|
||||
To compile the above and get each manifest in a separate file on disk use the following script:
|
||||
And here's the [build.sh](build.sh) script (which uses `vendor/` to render all manifests in a json structure of `{filename: manifest-content}`):
|
||||
|
||||
[embedmd]:# (build.sh)
|
||||
```sh
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# This script uses arg $1 (name of *.jsonnet file to use) to generate the manifests/*.yaml files.
|
||||
|
||||
set -e
|
||||
set -x
|
||||
# only exit with zero if all commands of the pipeline exit successfully
|
||||
@@ -117,56 +144,110 @@ jsonnet -J vendor -m manifests "${1-example.jsonnet}" | xargs -I{} sh -c 'cat {}
|
||||
|
||||
```
|
||||
|
||||
> Note you need `jsonnet` and `gojsonyaml` (`go get github.com/brancz/gojsontoyaml`) installed. If you just want json output, not yaml, then you can skip the pipe and everything afterwards.
|
||||
> Note you need `jsonnet` (`go get github.com/google/go-jsonnet/jsonnet`) and `gojsontoyaml` (`go get github.com/brancz/gojsontoyaml`) installed to run `build.sh`. If you just want json output, not yaml, then you can skip the pipe and everything afterwards.
|
||||
|
||||
This script reads each key of the generated json and uses that as the file name, and writes the value of that key to that file.
|
||||
This script runs the jsonnet code, then reads each key of the generated json and uses that as the file name, and writes the value of that key to that file, and converts each json manifest to yaml.
|
||||
|
||||
> You can also run this script executing the command `make generate-raw` from kube-prometheus base directory of this repository but the above option it is recommended so that you run it in your own infrastructure repository.
|
||||
### Containerized Installing and Compiling
|
||||
|
||||
If you don't care to have `jb` nor `jsonnet` nor `gojsontoyaml` installed, then build the `po-jsonnet` Docker image (this is something you'll need a copy of this repository for). Do the following from this `kube-prometheus` directory:
|
||||
```
|
||||
$ make ../../hack/jsonnet-docker-image
|
||||
```
|
||||
|
||||
Then you can do commands such as the following:
|
||||
```
|
||||
docker run \
|
||||
--rm \
|
||||
-v `pwd`:`pwd` \
|
||||
--workdir `pwd` \
|
||||
po-jsonnet jb init
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
-v `pwd`:`pwd` \
|
||||
--workdir `pwd` \
|
||||
po-jsonnet jb install github.com/coreos/prometheus-operator/contrib/kube-prometheus/jsonnet/kube-prometheus
|
||||
|
||||
docker run \
|
||||
--rm \
|
||||
-v `pwd`:`pwd` \
|
||||
--workdir `pwd` \
|
||||
po-jsonnet ./build.sh example.jsonnet
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
A hidden `_config` field is located at the top level of the object this library provides. These are the available fields with their respective default values:
|
||||
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 [Usage section](#Usage), 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:
|
||||
```
|
||||
{
|
||||
_config+:: {
|
||||
namespace: "default",
|
||||
namespace: "default",
|
||||
|
||||
versions+:: {
|
||||
alertmanager: "v0.14.0",
|
||||
nodeExporter: "v0.15.2",
|
||||
kubeStateMetrics: "v1.3.0",
|
||||
kubeRbacProxy: "v0.3.0",
|
||||
addonResizer: "1.0",
|
||||
prometheusOperator: "v0.18.1",
|
||||
prometheus: "v2.2.1",
|
||||
},
|
||||
versions+:: {
|
||||
alertmanager: "v0.15.0",
|
||||
nodeExporter: "v0.15.2",
|
||||
kubeStateMetrics: "v1.3.1",
|
||||
kubeRbacProxy: "v0.3.1",
|
||||
addonResizer: "1.0",
|
||||
prometheusOperator: "v0.18.1",
|
||||
prometheus: "v2.2.1",
|
||||
},
|
||||
|
||||
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",
|
||||
addonResizer: "quay.io/coreos/addon-resizer",
|
||||
nodeExporter: "quay.io/prometheus/node-exporter",
|
||||
prometheusOperator: "quay.io/coreos/prometheus-operator",
|
||||
},
|
||||
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",
|
||||
addonResizer: "quay.io/coreos/addon-resizer",
|
||||
nodeExporter: "quay.io/prometheus/node-exporter",
|
||||
prometheusOperator: "quay.io/coreos/prometheus-operator",
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
replicas: 2,
|
||||
rules: {},
|
||||
},
|
||||
prometheus+:: {
|
||||
names: 'k8s',
|
||||
replicas: 2,
|
||||
rules: {},
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
config: alertmanagerConfig,
|
||||
replicas: 3,
|
||||
},
|
||||
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: DeadMansSwitch
|
||||
receiver: 'null'
|
||||
receivers:
|
||||
- name: 'null'
|
||||
|||,
|
||||
replicas: 3,
|
||||
},
|
||||
|
||||
kubeStateMetrics+:: {
|
||||
collectors: '', // empty string gets a default set
|
||||
scrapeInterval: '30s',
|
||||
scrapeTimeout: '30s',
|
||||
|
||||
baseCPU: '100m',
|
||||
baseMemory: '150Mi',
|
||||
cpuPerNode: '2m',
|
||||
memoryPerNode: '30Mi',
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
The grafana definition is located in a different project (https://github.com/brancz/kubernetes-grafana), but needed configuration can be customized from the same file. F.e. to allow anonymous access to grafana, add the `_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 `_config` field. For example to allow anonymous access to grafana, add the following `_config` section:
|
||||
```
|
||||
grafana+:: {
|
||||
config: {
|
||||
@@ -177,12 +258,13 @@ The grafana definition is located in a different project (https://github.com/bra
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## Customization
|
||||
## Customization Examples
|
||||
|
||||
Jsonnet is a turing complete language, any logic can be reflected in it. It also has powerful merge functionalities, allowing sophisticated customizations of any kind simply by merging it into the object the library provides.
|
||||
|
||||
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]() and [bootkube]() clusters there are mixins available to easily configure these:
|
||||
### 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) and [bootkube](examples/jsonnet-snippets/bootkube.jsonnet) and [kops](examples/jsonnet-snippets/kops.jsonnet) clusters there are mixins available to easily configure these:
|
||||
|
||||
kubeadm:
|
||||
|
||||
@@ -208,6 +290,8 @@ kops:
|
||||
(import 'kube-prometheus/kube-prometheus-kops.libsonnet')
|
||||
```
|
||||
|
||||
### NodePorts
|
||||
|
||||
Another mixin that may be useful for exploring the stack is to expose the UIs of Prometheus, Alertmanager and Grafana on NodePorts:
|
||||
|
||||
[embedmd]:# (examples/jsonnet-snippets/node-ports.jsonnet)
|
||||
@@ -216,7 +300,9 @@ Another mixin that may be useful for exploring the stack is to expose the UIs of
|
||||
(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet')
|
||||
```
|
||||
|
||||
For example the name of the `Prometheus` object provided by this library can be overridden:
|
||||
### Prometheus Object Name
|
||||
|
||||
To give another customization example, the name of the `Prometheus` object provided by this library can be overridden:
|
||||
|
||||
[embedmd]:# (examples/prometheus-name-override.jsonnet)
|
||||
```jsonnet
|
||||
@@ -231,6 +317,8 @@ For example the name of the `Prometheus` object provided by this library can be
|
||||
}).prometheus.prometheus
|
||||
```
|
||||
|
||||
### node-exporter DaemonSet namespace
|
||||
|
||||
Standard Kubernetes manifests are all written using [ksonnet-lib](https://github.com/ksonnet/ksonnet-lib/), so they can be modified with the mixins supplied by ksonnet-lib. For example to override the namespace of the node-exporter DaemonSet:
|
||||
|
||||
[embedmd]:# (examples/ksonnet-example.jsonnet)
|
||||
@@ -316,35 +404,9 @@ local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') + {
|
||||
|
||||
### Static etcd configuration
|
||||
|
||||
In order to configure a static etcd cluster to scrape there is a simple mixin prepared, so only the IPs and certificate information need to be configured. Simply append the `kube-prometheus/kube-prometheus-static-etcd.libsonnet` mixin to the rest of the configuration, and configure the `ips` to be the IPs to scrape, and the `clientCA`, `clientKey` and `clientCert` to values that are valid to scrape etcd metrics with.
|
||||
In order to configure a static etcd cluster to scrape there is a simple [kube-prometheus-static-etcd.libsonnet](jsonnet/kube-prometheus/kube-prometheus-static-etcd.libsonnet) mixin prepared - see [etcd.jsonnet](examples/etcd.jsonnet) for an example of how to use that mixin, and [Monitoring external etcd](docs/monitoring-external-etcd.md) for more information.
|
||||
|
||||
Most likely these certificates are generated somewhere in an infrastructure repository, so using the jsonnet `importstr` function can be useful here. All the sensitive information on the certificates will end up in a Kubernetes Secret.
|
||||
|
||||
[embedmd]:# (examples/etcd.jsonnet)
|
||||
```jsonnet
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-static-etcd.libsonnet') + {
|
||||
_config+:: {
|
||||
namespace: 'monitoring',
|
||||
|
||||
etcd+:: {
|
||||
ips: ['127.0.0.1'],
|
||||
clientCA: importstr 'etcd-client-ca.crt',
|
||||
clientKey: importstr 'etcd-client.key',
|
||||
clientCert: importstr 'etcd-client.crt',
|
||||
serverName: 'etcd.my-cluster.local',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
{ ['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) }
|
||||
```
|
||||
> Note that monitoring etcd in minikube is currently not possible because of how etcd is setup. (minikube's etcd binds to 127.0.0.1:2379 only, and within host networking namespace.)
|
||||
|
||||
### Customizing Prometheus alerting/recording rules and Grafana dashboards
|
||||
|
||||
@@ -356,30 +418,7 @@ See [exposing Prometheus/Alertmanager/Grafana](docs/exposing-prometheus-alertman
|
||||
|
||||
## Minikube Example
|
||||
|
||||
To use an easy to reproduce example, let's take the minikube setup as demonstrated in [prerequisites](#Prerequisites). It is a kubeadm cluster (as we use the kubeadm bootstrapper) and because we would like easy access to our Prometheus, Alertmanager and Grafana UI we want the services to be exposed as NodePort type services:
|
||||
|
||||
> Note that NodePort type services is likely not a good idea for your production use case, it is only used for demonstration purposes here.
|
||||
|
||||
[embedmd]:# (examples/minikube.jsonnet)
|
||||
```jsonnet
|
||||
local kp =
|
||||
(import 'kube-prometheus/kube-prometheus.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-kubeadm.libsonnet') +
|
||||
(import 'kube-prometheus/kube-prometheus-node-ports.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
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) }
|
||||
```
|
||||
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.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
@@ -387,7 +426,7 @@ local kp =
|
||||
|
||||
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.
|
||||
|
||||
As described in the [prerequisites](#prerequisites) section, in order to retrieve metrics from the kubelet token authentication and authorization must be enabled. Some Kubernetes setup tools do not enable this by default.
|
||||
As described in the [Prerequisites](#prerequisites) section, in order to retrieve metrics from the kubelet token authentication and authorization must be enabled. Some Kubernetes setup tools do not enable this by default.
|
||||
|
||||
If you are using Google's GKE product, see [docs/GKE-cadvisor-support.md].
|
||||
|
||||
|
Reference in New Issue
Block a user