Adding Observability To A Kubernetes Cluster Using Prometheus - by Martin Hodges - Jan, 2024 - Medium
Adding Observability To A Kubernetes Cluster Using Prometheus - by Martin Hodges - Jan, 2024 - Medium
Search Write
Adding observability to a
Kubernetes cluster using
Prometheus
Monitoring your services is vital and should be considered as part of
your underlying infrastructure for your services. You should put this in
place ahead of creating and deploying your services. In this article I
look at how to deploy Prometheus provide the observability you need
to run your services.
When things do go wrong, the results for your users and for you could be
catastrophic, frustrating or plain old embarrassing. It might be that your
service fails completely, partially, slowly, or worse, without anyone noticing.
Hopefully you now understand why you need to ensure that you know about
problems first and that you can fix things before they become catastrophes.
Whilst I will introduce the concepts around monitoring and alerting, there
are many great articles and descriptions that describe these in detail.
I would recommend you always consider how you will operate and manage
your services from the start of the project. Do not leave it until after your
first major production outage.
Monitoring
Let’s say you have your Kubernetes cluster running a set of services that you
have deployed. It needs to run 24 x 7. As mentioned earlier, there are many
reasons why it may not, such as running out of resources, unexpected
events, defects and cyber events.
To ensure your services are always available for your users to use, you want
to be able to see how your services are performing at any given time.
Another reason you should start your monitoring system early is that it can
take time to optimise the information you are going to make available
through the system. By starting early, you stand more chance of having a
functional, operational and beneficial monitoring system for when you
launch.
When it comes to the type information you need your monitoring system to
collect, it is important to understand the difference between logs and
metrics:
A log is a time ordered list of events that your service recorded and
generally contains information that helps you work out what was
happening at that point in time.
Alerting
Ok, so you are monitoring your services (and the underlying infrastructure
that supports them) but you cannot stay glued to your screen 24x7. Instead,
you need to be told when something has gone wrong (or better still, that
something will go wrong without your action).
When things do go wrong (or start to go wrong), you want to know quickly,
regardless of where you might be. For this reason, you want your alert to be
delivered through a channel that is likely to catch your attention no matter
where you are. Channels such as email, Slack, text message, push
notification are examples that are likely to be effective.
You should now be building a picture of how your service, your monitoring
and alerting systems work together.
It is important that your monitoring and alerting system is reliable and fault
tolerant. In a failure case you do not want to find that your service
monitoring failed to capture the required information or that it lost it. You
do not want your alerts to fail to reach you.
We will now look at how Prometheus can help within a Kubernetes cluster
by providing monitoring. Prometheus also provides alerting but I want to
come back to that in another article.
Architecture
From my previous articles, I am assuming that you have a Kubernetes cluster
that looks like this:
Kubernetes cluster
We will now install Prometheus onto this cluster, using a Persistent Volume
backed by the nfs-server .
Monitoring solution
Prometheus
We need a place for Prometheus to store its data safely. We do this using a
Persistent Volume (PV), which the application claims through a Persistent
Volume Claim (PVC). I have written about creating PVs and PVCs here.
I would strongly suggest that you create a separate share for Prometheus. If
you have followed my previous articles, you will need to set up this share.
Log in to your nfs-server and modify this file as root (keep any other
changes you may have made):
/etc/exports
/pv-share *(rw,async,no_subtree_check)
/pv-share/prometheus *(rw,async,no_subtree_check)
Note that these file permissions are weak and should not be used for production.
For this article I am showing an example to get you started.
Now load this share and ensure the service starts correctly.
Log in to your k8s-master and create the following file (I am assuming here
that you are accessing your cluster via kubectl on your master node. If not,
use whatever access you typically use to deploy to your cluster):
Remember to replace any fields between < and > with your own values.
prometheus-pv.yml
apiVersion: v1
kind: PersistentVolume
metadata:
name: prometheus-pv
spec:
capacity:
storage: 10Gi
storageClassName: prometheus-class
accessModes:
- ReadWriteOnce
nfs:
path: /pv-share/prometheus
server: <nfs-server IP address>
persistentVolumeReclaimPolicy: Retain
Remember to change the path and the server IP addresses to those used by
your cluster. You may also need to change the overall size of these PVs,
which I have set to 10GB.
We now need to create a PVC for the PV. Before we do that, we need to create
the namespace for them:
prometheus-pvc.yml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: prometheus-pvc
namespace: monitoring
spec:
storageClassName: prometheus-class
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
Now create them and check they are bound to the PV:
Installing Helm
It is possible to create manifest files (deployment, service, secrets and
configuration yaml files) for Prometheus and Grafana and then deploy them.
This is a complex process to get right and it is better to use Helm charts
instead, which come with these two applications integrated.
Helm is installed where you run kubectl , which in my case is on the k8s-
master node.
helm version
helm
This will show you the version of Helm you have installed as well a list of
commands you can use with Helm.
There are many ways to deploy Prometheus. In fact, you can see a list of
available charts in the Artifacthub alone with:
The list is very long and can be quite daunting. Some are no longer
supported.
The instructions here are working at the time of writing, Jan 2024.
Deploying Prometheus
First we will add the community Helm chart repository to our system:
To do this we create a values file. A values file is a yaml file that overrides or
defines additional configuration for a Helm chart. In this case we will use a
values file to override the defaults in the Helm chart.
Whilst we are telling Prometheus to use our PV/PVC, we can also tell it not to
start its Alerts Manager as we will be using Grafana for this. We will also
remove the Push Gateway as we will not be using this.
Create the following file (remember to replace the < > fields with your own
values).
prometheus-values.yml
alertmanager:
enabled: false
prometheus-pushgateway:
enabled: false
server:
service:
externalIPs:
- <k8s-master IP address>
servicePort: 9090
type: NodePort
nodePort: 31190
persistentVolume:
enabled: true
existingClaim: prometheus-pvc
Now let’s install Prometheus, from the community supported Helm chart,
with our values override file. We will install it into the monitoring
NAME READY
STATUS RESTARTS AGE
prometheus-monitoring-kube-state-metrics-84945c4bd5-n29mr 1/1
Running 0 12m
prometheus-monitoring-prometheus-node-exporter-ksmnl 1/1
Running 0 12m
prometheus-monitoring-prometheus-node-exporter-swrhj 1/1
Running 0 12m
prometheus-monitoring-prometheus-node-exporter-zp5mz 1/1
Running 0 12m
prometheus-monitoring-server-94f974648-x7jxs 2/2
Running 0 12m
Some descriptions:
You should not lose any data as the PVC is still retained:
Testing Prometheus
You should now be able to go to a browser on your development machine
and access the UI at: http://<k8s-master IP address>:9090/graph .
All being well, you will be presented with the Prometheus graph page. From
here you can type a search criteria into the search bar. For example
kubelet_active_pods . When you click Execute you will see the number of
pods created since you started Prometheus.
These are vital components in our architecture and, even though they are
not in our cluster, we need to monitor them.
Welcome to the Prometheus Node Exporter. This is a service that will run on
our external nodes and collect metrics from the node’s Operating Systems
(OS) and present them in a way that Prometheus can scrape them.
We will need to install Node Exporter on both of our external servers. I’ll
only explain one of them for brevity.
First go to the official set of downloads to find the correct version. At the
time of writing, I am selecting 1.7.0 linux on amd64.
wget https://github.com/prometheus/node_exporter/releases/download/v1.7.0/node_exporter-
tar xvf node_exporter-1.7.0.linux-amd64.tar.gz
This will download 3 files into a folder within your current folder. Copy the
executable as follows:
It is recommended that you run node exporter under a separate user. The
user should not be able to log in. Create the user and assign the binary to
them.
We now need to create the service to run the exporter. As root create the
following file (remember to change < > fields to match your set up):
/etc/systemd/system/node_exporter.service
[Unit]
Description=Node Exporter
Wants=network-online.target
After=network-online.target
[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/usr/local/bin/node_exporter $ARGS --web.listen-address
<server private IP address>:9100
Restart=always
RestartSec=3
[Install]
WantedBy=multi-user.target
Reload the service daemon so it picks up the new service and then start and
enable the service.
For the gateway server, you should not be able to access this end point from
the Internet but you may also find you cannot access it from the k8s-master
node either. This is because the gateway has a firewall preventing the
connection. On the gateway server, enable the port with:
At this point your two servers should now have node_exporter running on
them. Now we need to get Prometheus to scrape these two new data sources.
Updating Prometheus
We now need to add our two new node_exporter instances to our Prometheus
deployment.
Update your prometheus-values.yml to the following, replacing < > fields with
your values.
alertmanager:
enabled: false
prometheus-pushgateway:
enabled: false
server:
service:
externalIPs:
- <k8s-master IP address>
servicePort: 9090
type: NodePort
nodePort: 31190
persistentVolume:
enabled: true
existingClaim: prometheus-pvc
extraScrapeConfigs: |
- job_name: 'rs-nfs-server'
metrics_path: /metrics
static_configs:
- targets:
- <nfs server IP address>:9100
- job_name: 'rs-gw'
metrics_path: /metrics
static_configs:
- targets:
- <gw server IP address>:9100
Note that the extra scrape config is added as a string representing additional
yaml so make sure you copy and paste the config above.
Once you update this configuration, you will need to delete and reinstall
your helm charts.
Now when you look at the Prometheus UI, you should see your additional
servers in your node metrics.
Summary
In this article we looked at the need to implement monitoring and alerting to
ensure our services remain available and meeting the expectation of our
users.
We then create a Persistent Volumes to hold our data and followed this up by
installing Helm so we could then install Prometheus using a community
Helm chart.
If you found this article of interest, please give me a clap as that helps me
identify what people find useful and what future articles I should write. If
you have any suggestions, please add them in the comments section.
28 Followers
61 5
12
224 3 5
Lists
17 13
1 1 6 1