sebastiandaschner blog
Discover applications running on Kubernetes with Prometheus
friday, february 15, 2019Prometheus supports scraping multiple application instances. Applications that run in orchestrated environments require to be discovered dynamically, since their IP addresses will change. Prometheus can be configured to use the Kubernetes API to discover changes in the list of running instances dynamically.
The following shows a minimalistic Prometheus example of instrumenting an application with multiple pod instances.
Prometheus configuration
We configure Prometheus to discover the pods of our config-example
application.
global:
scrape_interval: 15s
external_labels:
monitor: 'example-monitor'
scrape_configs:
- job_name: 'example-metric'
scrape_interval: 5s
metrics_path: /metrics/
scheme: https
basic_auth:
username: admin
password: adminadmin
tls_config:
insecure_skip_verify: true
kubernetes_sd_configs:
- role: endpoints
namespaces:
names:
- default
relabel_configs:
- source_labels: [__meta_kubernetes_service_label_app]
separator: ;
regex: config-example
replacement: $1
action: keep
- source_labels: [__meta_kubernetes_endpoint_port_name]
separator: ;
regex: https
replacement: $1
action: keep
- source_labels: [__meta_kubernetes_namespace]
separator: ;
regex: (.*)
target_label: namespace
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_pod_name]
separator: ;
regex: (.*)
target_label: pod
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_service_name]
separator: ;
regex: (.*)
target_label: service
replacement: $1
action: replace
- source_labels: [__meta_kubernetes_service_name]
separator: ;
regex: (.*)
target_label: job
replacement: ${1}
action: replace
- separator: ;
regex: (.*)
target_label: endpoint
replacement: https
action: replace
We need to adjust the app
label (here config-example
) and the port name (https
) under which the monitoring endpoint is available.
Instrumented application
This example uses the MicroProfile Metrics endpoint that runs on top of Open Liberty.
The application exposes the metrics in the Prometheus format under port 9443
and path /metrics/
.
Here you can see an example service and deployment:
kind: Service
apiVersion: v1
metadata:
name: config-example
labels:
app: config-example
spec:
selector:
app: config-example
ports:
- port: 9443
name: https
- port: 9080
name: http
kind: Deployment
apiVersion: apps/v1beta1
metadata:
name: config-example
spec:
replicas: 2
template:
metadata:
labels:
app: config-example
spec:
containers:
- name: config-example
image: sdaschner/config-example:1
# ...
You can find the full example including the running application on GitHub.
Prometheus setup & RBAC
In order to make the example work for a RBAC Kubernetes setup, the Prometheus service account needs to have the correct permissions. Therefore, we create a service account and corresponding cluster roles as included in the YAML definitions here. Similarly, we specify the service account when creating the Prometheus deployment.
We create a deployment and service for our Prometheus instance.
kind: Service
apiVersion: v1
metadata:
name: prometheus
labels:
app: prometheus
spec:
selector:
app: prometheus
ports:
- port: 9090
name: http
kind: Deployment
apiVersion: apps/v1beta1
metadata:
name: prometheus
spec:
replicas: 1
template:
metadata:
labels:
app: prometheus
version: v1
spec:
serviceAccountName: prometheus
containers:
- name: prometheus
image: prom/prometheus:v2.7.1
ports:
- containerPort: 9090
volumeMounts:
- name: prometheus-config-volume
mountPath: /etc/prometheus/prometheus.yml
subPath: prometheus.yml
volumes:
- name: prometheus-config-volume
configMap:
name: prometheus-config
restartPolicy: Always
The configuration shown earlier can be injected into the instance from a config map.
kind: ConfigMap
apiVersion: v1
metadata:
name: prometheus-config
data:
prometheus.yml: |
global:
scrape_interval: 15s
# content as shown earlier ...
For a full explanation on the Prometheus configuration, have a look at the documentation.
Accessing the targets
The running Prometheus instance can now discover both running config example applications which run as Kubernetes pods:
$> kubectl get pods
NAME READY STATUS RESTARTS AGE
config-example-69974cbc96-dqd96 1/1 Running 0 4m
config-example-69974cbc96-zstg7 1/1 Running 0 4m
grafana-8694db9d4f-nvn5s 1/1 Running 0 3m
prometheus-594dd9cdb8-95ftz 1/1 Running 0 3m
We can see the actual targets including their IP address under the Prometheus configuration.
Have a look at the full example on GitHub (deployment/
directory).
You might also see the following video how to implement business metrics in Java EE applications using MicroProfile.
For more complex microservice examples that define many more applications, this approach using the plain Prometheus configuration might be a bit cumbersome. To minimize boilerplate code, developers can use solutions that abstracts away the lower-level configuration, such as Prometheus Operator. In the next post we’ll see how Prometheus Operator facilitates the configuration of applications.
Happy monitoring!
Found the post useful? Subscribe to my newsletter for more free content, tips and tricks on IT & Java: