{"id":631,"date":"2025-04-02T01:20:00","date_gmt":"2025-04-02T01:20:00","guid":{"rendered":"https:\/\/blog.ngocha.biz\/?p=631"},"modified":"2025-04-02T01:20:00","modified_gmt":"2025-04-02T01:20:00","slug":"setup-prometheus-monitoring-on-kubernetes","status":"publish","type":"post","link":"https:\/\/blog.ngocha.biz\/?p=631","title":{"rendered":"How to Setup Prometheus Monitoring On Kubernetes [Tutorial]"},"content":{"rendered":"<p>This Prometheus kubernetes tutorial will guide you through setting up Prometheus on a Kubernetes cluster for monitoring the Kubernetes cluster.<\/p>\n<p>This setup collects node, pods, and service metrics automatically using Prometheus service discovery configurations.<\/p>\n<p>By the end of this guide, you will:<\/p>\n<ul>\n<li>Understand all the core components of Prometheus<\/li>\n<li>Know the key Kubernetes objects and manifests involved in setting up Prometheus<\/li>\n<li>Learn how to update the Prometheus configuration<\/li>\n<li>Access the Prometheus dashboard using different methods<\/li>\n<li>Enable Alertmanager, kube-state-metrics, and Node Exporter<\/li>\n<li>Connect Grafana dashboards for clear and useful monitoring<\/li>\n<\/ul>\n<h2 id=\"about-prometheus\">About Prometheus<\/h2>\n<p><a href=\"https:\/\/prometheus.io\/?ref=devopscube.com\" rel=\"noopener noreferrer\">Prometheus<\/a> is a high-scalable open-source monitoring framework. It provides out-of-the-box monitoring capabilities for the Kubernetes <a href=\"https:\/\/devopscube.com\/docker-container-clustering-tools\/\" rel=\"noreferrer noopener\">container orchestration platform<\/a>. <\/p>\n<p>Also, In the <a href=\"https:\/\/devopscube.com\/what-is-observability\/\" rel=\"noreferrer noopener\">observability<\/a> space, it is gaining huge popularity as it helps with metrics and alerts.<\/p>\n<p>Explaining Prometheus is out of the scope of this article. If you want to know more about Prometheus, You can watch all the Prometheus-related videos <a href=\"https:\/\/www.youtube.com\/channel\/UC4pLFely0-Odea4B2NL1nWA\/videos?ref=devopscube.com\" rel=\"noopener noreferrer\">from here<\/a>.<\/p>\n<p>However, there are a few key concepts I would like to list for your reference.<\/p>\n<ol>\n<li><strong>Metric Collection:<\/strong> Prometheus uses the pull model to retrieve metrics over HTTP. There is an option to push metrics to Prometheus using <a href=\"https:\/\/prometheus.io\/docs\/practices\/pushing\/?ref=devopscube.com\" rel=\"noreferrer noopener\"><code>Pushgateway<\/code><\/a> for use cases where Prometheus cannot Scrape the metrics. One such example is collecting custom metrics from short-lived <a href=\"https:\/\/devopscube.com\/create-kubernetes-jobs-cron-jobs\/\" rel=\"noreferrer noopener\">kubernetes jobs &amp; Cronjobs<\/a><\/li>\n<li><strong>Metric Endpoint<\/strong>: The systems that you want to monitor using Prometheus should expose the metrics on an <code>\/metrics<\/code> endpoint. Prometheus uses this endpoint to pull the metrics in regular intervals.<\/li>\n<li><strong>PromQL:<\/strong> Prometheus comes with <a href=\"https:\/\/prometheus.io\/docs\/prometheus\/latest\/querying\/basics\/?ref=devopscube.com\" rel=\"noreferrer noopener\"><code>PromQL<\/code><\/a>, a very flexible query language that can be used to query the metrics in the Prometheus dashboard. Also, the PromQL query will be used by Prometheus UI and Grafana to visualize metrics<a href=\"https:\/\/devopscube.com\/integrate-visualize-prometheus-grafana\/\" rel=\"noreferrer noopener\">.<\/a><\/li>\n<li><strong>Prometheus Exporters:<\/strong> Exporters are libraries that convert existing metrics from third-party apps to Prometheus metrics format. There are many official and community Prometheus exporters. One example is, the Prometheus node exporter. It exposes all Linux system-level metrics in Prometheus format.<\/li>\n<li><strong>TSDB (time-series database):<\/strong> Prometheus uses TSDB for storing all the data efficiently. By default, all the data gets stored locally. However, to avoid a single point of failure, there are options to integrate remote storage for Prometheus TSDB.<\/li>\n<\/ol>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">If you would like to install Prometheus on a Linux VM, please see the <a href=\"https:\/\/devopscube.com\/install-configure-prometheus-linux\/\" rel=\"noopener noreferrer\">Prometheus on Linux<\/a> guide.<\/div>\n<\/div>\n<h2 id=\"prometheus-architecture\">Prometheus Architecture<\/h2>\n<p>Here is the high-level <strong>architecture of Prometheus.<\/strong> <\/p>\n<figure class=\"kg-card kg-image-card kg-card-hascaption\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/prometheus-architecture-3.gif\" class=\"kg-image\" alt=\"Prometheus Architecture- Components Workflow\" loading=\"lazy\" width=\"1280\" height=\"720\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/prometheus-architecture-3.gif 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/prometheus-architecture-3.gif 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/prometheus-architecture-3.gif 1280w\" sizes=\"auto, (min-width: 720px) 720px\"><figcaption><span style=\"white-space: pre-wrap;\">Click to view in HD<\/span><\/figcaption><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">If you want to understand prometheus components in detail, please read the detailed <a href=\"https:\/\/devopscube.com\/prometheus-architecture\/\">Prometheus Architecture<\/a> blog.<\/div>\n<\/div>\n<p>The Kubernetes Prometheus monitoring stack has the following components.<\/p>\n<ol>\n<li>Prometheus Server<\/li>\n<li>Alert Manager<\/li>\n<li>Grafana<\/li>\n<\/ol>\n<p>In a nutshell, the following image depicts the high-level <strong>Prometheus kubernetes architecture<\/strong> that we are going to build. We have separate blogs for each component setup.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/kubernetes-1.png\" class=\"kg-image\" alt=\"Prometheus kubernetes architecture\" loading=\"lazy\" width=\"2000\" height=\"973\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/kubernetes-1.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/kubernetes-1.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/kubernetes-1.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/03\/kubernetes-1.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">Note<\/strong><\/b>: The Linux Foundation has a Prometheus <a href=\"https:\/\/devopscube.com\/recommends\/pca-certification\/\" rel=\"noreferrer noopener\">Certified Associate (PCA) certification exam<\/a>. PCA focuses on showcasing skills related to observability, open-source monitoring, and alerting toolkit. Use code <b><strong style=\"white-space: pre-wrap;\">DCUBE30<\/strong><\/b> Today to get<b><strong style=\"white-space: pre-wrap;\"> instance discount<\/strong><\/b> on the certificatication.<\/div>\n<\/div>\n<h2 id=\"prometheus-monitoring-setup-on-kubernetes\">Prometheus Monitoring Setup on Kubernetes<\/h2>\n<p>I assume that you have a Kubernetes cluster up and running with kubectl setup on your workstation.<\/p>\n<p>The latest Prometheus is available as a <a href=\"https:\/\/hub.docker.com\/r\/prom\/prometheus\/?ref=devopscube.com\" rel=\"noopener noreferrer\">docker image<\/a> in its official docker hub account. We will use that image for the setup.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">If you are looking for Helm based setup, please checkout <a href=\"https:\/\/devopscube.com\/setup-prometheus-helm-chart\/\">Prometheus setup using helm charts<\/a>.<\/div>\n<\/div>\n<h2 id=\"connect-to-the-kubernetes-cluster\">Connect to the Kubernetes Cluster<\/h2>\n<p>Connect to your Kubernetes cluster and make sure you have admin privileges to create cluster roles.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-grey\">\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">Only for GKE:<\/strong><\/b> If you are using Google cloud GKE, you need to run the following commands as you need privileges to create cluster roles for this Prometheus setup.<\/div>\n<\/div>\n<pre><code class=\"language-bash\">ACCOUNT=$(gcloud info --format='value(config.account)')\nkubectl create clusterrolebinding owner-cluster-admin-binding \\\n    --clusterrole cluster-admin \\\n    --user $ACCOUNT<\/code><\/pre>\n<h2 id=\"prometheus-kubernetes-manifest-files\">Prometheus Kubernetes Manifest Files<\/h2>\n<p>All the configuration files I mentioned in this guide are <a href=\"https:\/\/github.com\/bibinwilson\/kubernetes-prometheus?ref=devopscube.com\" rel=\"noreferrer noopener\"><strong>hosted on Github<\/strong><\/a>. You can clone the repo using the following command.<\/p>\n<pre><code class=\"language-bash\">git clone https:\/\/github.com\/techiescamp\/kubernetes-prometheus<\/code><\/pre>\n<p>Please don&#8217;t hesitate to contribute to the repo for adding features.<\/p>\n<p>You can use the GitHub repo config files or create the files on the go for a better understanding, as mentioned in the steps.<\/p>\n<p>Let&#8217;s get started with the setup.<\/p>\n<h2 id=\"create-a-namespace-clusterrole\">Create a Namespace &amp; ClusterRole<\/h2>\n<p>First, we will create a Kubernetes namespace for all our monitoring components. If you don&#8217;t create a dedicated namespace, all the Prometheus kubernetes deployment objects get deployed on the default namespace.<\/p>\n<p>Execute the following command to create a new <strong>namespace named monitoring<\/strong>.<\/p>\n<pre><code class=\"language-bash\">kubectl create namespace monitoring<\/code><\/pre>\n<p>Prometheus uses Kubernetes APIs to read all the available metrics from Nodes, Pods, Deployments, etc. For this reason, we need to create an RBAC policy with <code>read access<\/code> to required API groups and bind the policy to the <code>monitoring<\/code> namespace.<\/p>\n<p><strong>Step 1:<\/strong> Create a file named <code>clusterRole.yaml<\/code> and copy the following RBAC role.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-emoji\">\ud83d\udca1<\/div>\n<div class=\"kg-callout-text\">Note: In the role, given below, you can see that we have added <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">get<\/code>, <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">list<\/code>, and <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">watch<\/code> permissions to nodes, services endpoints, pods, and ingresses. The role binding is bound to the monitoring namespace. If you have any use case to retrieve metrics from any other object, you need to add that in this cluster role.<\/div>\n<\/div>\n<pre><code class=\"language-yaml\">apiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRole\nmetadata:\n  name: prometheus\nrules:\n- apiGroups: [\"\"]\n  resources:\n  - nodes\n  - nodes\/proxy\n  - services\n  - endpoints\n  - pods\n  verbs: [\"get\", \"list\", \"watch\"]\n- apiGroups:\n  - extensions\n  resources:\n  - ingresses\n  verbs: [\"get\", \"list\", \"watch\"]\n- nonResourceURLs: [\"\/metrics\"]\n  verbs: [\"get\"]\n---\napiVersion: rbac.authorization.k8s.io\/v1\nkind: ClusterRoleBinding\nmetadata:\n  name: prometheus\nroleRef:\n  apiGroup: rbac.authorization.k8s.io\n  kind: ClusterRole\n  name: prometheus\nsubjects:\n- kind: ServiceAccount\n  name: default\n  namespace: monitoring<\/code><\/pre>\n<p><strong>Step 2:<\/strong> Create the role using the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl create -f clusterRole.yaml<\/code><\/pre>\n<h2 id=\"create-a-config-map-to-externalize-prometheus-configurations\">Create a Config Map To Externalize Prometheus Configurations<\/h2>\n<p>All configurations for Prometheus are part of <code>prometheus.yaml<\/code> file and all the alert rules for Alertmanager are configured in <code>prometheus.rules<\/code>.<\/p>\n<ol>\n<li><code>prometheus.yaml<\/code>: This is the main Prometheus configuration which holds all the scrape configs, service discovery details, storage locations, data retention configs, etc)<\/li>\n<li><code>prometheus.rules<\/code>: This file contains all the Prometheus alerting rules<\/li>\n<\/ol>\n<p>By externalizing Prometheus configs to a Kubernetes config map, you don&#8217;t have to build the Prometheus image whenever you need to add or remove a configuration. You just need to update the Configmap and restart the Prometheus pods to apply the new configuration.<\/p>\n<p>The config map with all the <a href=\"https:\/\/raw.githubusercontent.com\/bibinwilson\/kubernetes-prometheus\/master\/config-map.yaml?ref=devopscube.com\" rel=\"noopener noreferrer\">Prometheus scrape config<\/a> and alerting rules gets mounted to the Prometheus container in <code>\/etc\/prometheus<\/code> location as <code>prometheus.yaml<\/code> and <code>prometheus.rules<\/code> files.<\/p>\n<p>Lets create the configmap.<\/p>\n<p>Execute the following command to create the config map in Kubernetes.<\/p>\n<pre><code class=\"language-bash\">kubectl create -f https:\/\/raw.githubusercontent.com\/bibinwilson\/kubernetes-prometheus\/master\/config-map.yaml<\/code><\/pre>\n<p>It creates two files inside the container.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">Note:<\/strong><\/b> In Prometheus terms, the config for collecting metrics from a collection of endpoints is called a <code spellcheck=\"false\" style=\"white-space: pre-wrap;\">job<\/code>.<\/div>\n<\/div>\n<p>The <code>prometheus.yaml<\/code> contains all the configurations to discover pods and services running in the Kubernetes cluster dynamically. We have the following <a href=\"https:\/\/prometheus.io\/docs\/concepts\/jobs_instances\/?ref=devopscube.com\" rel=\"noreferrer noopener\">scrape jobs<\/a> in our Prometheus scrape configuration.<\/p>\n<ol>\n<li><code>kubernetes-apiservers<\/code>: It gets all the metrics from the API servers.<\/li>\n<li><code>kubernetes-nodes<\/code>: It collects all the kubernetes node metrics.<\/li>\n<li><code>kubernetes-pods<\/code>: All the pod metrics get discovered if the pod metadata is annotated with <code>prometheus.io\/scrape<\/code> and<code> prometheus.io\/port<\/code> annotations.<\/li>\n<li><code>kubernetes-cadvisor<\/code>: Collects all cAdvisor metrics.<\/li>\n<li><code>kubernetes-service-endpoints<\/code>: All the Service endpoints are scrapped if the service metadata is annotated with prometheus.io\/scrape and prometheus.io\/port annotations. It can be used for black-box monitoring.<\/li>\n<\/ol>\n<p><code>prometheus.rules<\/code> contains all the alert rules for sending alerts to the Alertmanager.<\/p>\n<h2 id=\"create-a-prometheus-deployment\">Create a Prometheus Deployment<\/h2>\n<p><strong>Step 1:<\/strong> Create a file named <code>prometheus-deployment.yaml<\/code> and copy the following contents onto the file. In this configuration, we are mounting the Prometheus config map as a file inside<code> \/etc\/prometheus<\/code> as explained in the previous section.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">Note:<\/strong><\/b> This deployment uses the latest <a href=\"https:\/\/hub.docker.com\/r\/prom\/prometheus\/?ref=devopscube.com\" rel=\"noreferrer noopener\">official Prometheus image<\/a> from the docker hub. Also, we are not using any <a href=\"https:\/\/devopscube.ghost.io\/persistent-volume-google-kubernetes-engine\/?ref=devopscube.com\" rel=\"noreferrer noopener\">persistent storage volumes<\/a> for Prometheus storage as it is a basic setup. When setting up Prometheus for production uses cases, make sure you add persistent storage to the deployment.<\/div>\n<\/div>\n<pre><code class=\"language-yaml\">apiVersion: apps\/v1\nkind: Deployment\nmetadata:\n  name: prometheus-deployment\n  namespace: monitoring\n  labels:\n    app: prometheus-server\nspec:\n  replicas: 1\n  selector:\n    matchLabels:\n      app: prometheus-server\n  template:\n    metadata:\n      labels:\n        app: prometheus-server\n    spec:\n      containers:\n        - name: prometheus\n          image: prom\/prometheus\n          args:\n            - \"--storage.tsdb.retention.time=12h\"\n            - \"--config.file=\/etc\/prometheus\/prometheus.yml\"\n            - \"--storage.tsdb.path=\/prometheus\/\"\n          ports:\n            - containerPort: 9090\n          resources:\n            requests:\n              cpu: 500m\n              memory: 500M\n            limits:\n              cpu: 1\n              memory: 1Gi\n          volumeMounts:\n            - name: prometheus-config-volume\n              mountPath: \/etc\/prometheus\/\n            - name: prometheus-storage-volume\n              mountPath: \/prometheus\/\n      volumes:\n        - name: prometheus-config-volume\n          configMap:\n            defaultMode: 420\n            name: prometheus-server-conf\n  \n        - name: prometheus-storage-volume\n          emptyDir: {}<\/code><\/pre>\n<p><strong>Step 2:<\/strong> Create a deployment on monitoring namespace using the above file.<\/p>\n<pre><code class=\"language-bash\">kubectl create  -f prometheus-deployment.yaml <\/code><\/pre>\n<p><strong>Step 3:<\/strong> You can check the created deployment using the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl get deployments --namespace=monitoring<\/code><\/pre>\n<p>You can also get details from the kubernetes dashboard as shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/screen-shot-2017-10-11-at-11-26-15-am-3.jpg\" class=\"kg-image\" alt=\"prometheus on kubernetes\" loading=\"lazy\" width=\"2000\" height=\"747\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/screen-shot-2017-10-11-at-11-26-15-am-3.jpg 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/screen-shot-2017-10-11-at-11-26-15-am-3.jpg 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/screen-shot-2017-10-11-at-11-26-15-am-3.jpg 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/03\/screen-shot-2017-10-11-at-11-26-15-am-3.jpg 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h2 id=\"connecting-to-prometheus-dashboard\">Connecting To Prometheus Dashboard<\/h2>\n<p>You can view the deployed Prometheus dashboard in three different ways.<\/p>\n<ol>\n<li>Using Kubectl port forwarding<\/li>\n<li>Exposing the Prometheus deployment as a service with NodePort or a Load Balancer.<\/li>\n<li>Adding an <a href=\"https:\/\/devopscube.com\/kubernetes-ingress-tutorial\/\" rel=\"noreferrer noopener\">Ingress object<\/a> if you have an Ingress controller deployed.<\/li>\n<\/ol>\n<p>Let&#8217;s have a look at all three options.<\/p>\n<h3 id=\"method-1-using-kubectl-port-forwarding\">Method 1: Using Kubectl port forwarding<\/h3>\n<p>Using kubectl port forwarding, you can access a pod from your local workstation using a selected port on your <code>localhost<\/code>. This method is primarily used for debugging purposes.<\/p>\n<p><strong>Step 1:<\/strong> First, get the Prometheus pod name.<\/p>\n<pre><code class=\"language-bash\">kubectl get pods --namespace=monitoring<\/code><\/pre>\n<p>The output will look like the following.<\/p>\n<pre><code class=\"language-bash\">\u279c  kubectl get pods --namespace=monitoring\nNAME                                     READY     STATUS    RESTARTS   AGE\nprometheus-monitoring-3331088907-hm5n1   1\/1       Running   0          5m<\/code><\/pre>\n<p><strong>Step 2:<\/strong> Execute the following command with your pod name to access Prometheus from localhost port 8080.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">Note: <\/strong><\/b>Replace prometheus-monitoring-3331088907-hm5n1 with your pod name.<\/div>\n<\/div>\n<pre><code class=\"language-bash\">kubectl port-forward prometheus-monitoring-3331088907-hm5n1 8080:9090 -n monitoring<\/code><\/pre>\n<p><strong>Step 3:<\/strong> Now, if you access <code>http:\/\/localhost:8080<\/code> on your browser, you will get the Prometheus home page.<\/p>\n<h3 id=\"method-2-exposing-prometheus-as-a-service-nodeport-loadbalancer\">Method 2: Exposing Prometheus as a Service [NodePort &amp; LoadBalancer]<\/h3>\n<p>To access the Prometheus dashboard over a <code>IP<\/code> or a <code>DNS<\/code> name, you need to expose it as a Kubernetes service.<\/p>\n<p><strong>Step 1:<\/strong> Create a file named <code>prometheus-service.yaml<\/code> and copy the following contents. We will expose Prometheus on all kubernetes node IP&#8217;s on port <code>30000<\/code>.<\/p>\n<div class=\"kg-card kg-callout-card kg-callout-card-blue\">\n<div class=\"kg-callout-text\"><b><strong style=\"white-space: pre-wrap;\">Note:<\/strong><\/b> If you are on AWS, Azure, or Google Cloud, You can use Loadbalancer type, which will create a load balancer and automatically points it to the Kubernetes service endpoint.<\/div>\n<\/div>\n<pre><code class=\"language-bash\">apiVersion: v1\nkind: Service\nmetadata:\n  name: prometheus-service\n  namespace: monitoring\n  annotations:\n      prometheus.io\/scrape: 'true'\n      prometheus.io\/port:   '9090'\nspec:\n  selector: \n    app: prometheus-server\n  type: NodePort  \n  ports:\n    - port: 8080\n      targetPort: 9090 \n      nodePort: 30000<\/code><\/pre>\n<p>The <code>annotations<\/code> in the above service <code>YAML<\/code> makes sure that the service endpoint is scrapped by Prometheus. The <code>prometheus.io\/port<\/code> should always be the target port mentioned in service YAML<\/p>\n<p><strong>Step 2:<\/strong> Create the service using the following command.<\/p>\n<pre><code class=\"language-bash\">kubectl create -f prometheus-service.yaml --namespace=monitoring<\/code><\/pre>\n<p><strong>Step 3:<\/strong> Once created, you can access the Prometheus dashboard using any of the Kubernetes node&#8217;s IP on port <code>30000<\/code>. If you are on the cloud, make sure you have the right firewall rules to access port <code>30000<\/code> from your workstation.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/screen-shot-2017-10-11-at-12-15-57-pm-3.jpg\" class=\"kg-image\" alt=\"Prometheus dashboard\" loading=\"lazy\" width=\"1496\" height=\"646\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/screen-shot-2017-10-11-at-12-15-57-pm-3.jpg 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/screen-shot-2017-10-11-at-12-15-57-pm-3.jpg 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/screen-shot-2017-10-11-at-12-15-57-pm-3.jpg 1496w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p><strong>Step 4:<\/strong> Now, if you browse to <code>status --&gt; Targets<\/code>, you will see all the Kubernetes endpoints connected to Prometheus automatically using service discovery as shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-14-43.png\" class=\"kg-image\" alt=\"Prometheus targets\" loading=\"lazy\" width=\"2000\" height=\"1079\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-14-43.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-14-43.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/image-14-43.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/03\/image-14-43.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<p>The kube-state-metrics down is expected and I&#8217;ll discuss it shortly.<\/p>\n<p><strong>Step 5:<\/strong> You can head over to the homepage and select the metrics you need from the drop-down, and get the graph for the time range you mention. An example graph for <code>container_cpu_usage_seconds_total<\/code> is shown below.<\/p>\n<figure class=\"kg-card kg-image-card\"><img decoding=\"async\" src=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/2025\/03\/image-13-30.png\" class=\"kg-image\" alt=\"Prometheus graph dashboard\" loading=\"lazy\" width=\"2000\" height=\"1196\" srcset=\"https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w600\/2025\/03\/image-13-30.png 600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1000\/2025\/03\/image-13-30.png 1000w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w1600\/2025\/03\/image-13-30.png 1600w, https:\/\/storage.ghost.io\/c\/5f\/2f\/5f2f4d20-2abf-4534-8d40-7aa233aedd43\/content\/images\/size\/w2400\/2025\/03\/image-13-30.png 2400w\" sizes=\"auto, (min-width: 720px) 720px\"><\/figure>\n<h3 id=\"method-3-exposing-prometheus-using-ingress\">Method 3: Exposing Prometheus Using Ingress<\/h3>\n<p>If you have an existing <a href=\"https:\/\/devopscube.com\/setup-ingress-kubernetes-nginx-controller\/\" rel=\"noreferrer noopener\">ingress controller setup<\/a>, you can create an ingress object to route the Prometheus DNS to the Prometheus backend service.<\/p>\n<p>Also, you can add SSL for Prometheus in the ingress layer. You can refer to the <a href=\"https:\/\/devopscube.com\/configure-ingress-tls-kubernetes\/\" rel=\"noreferrer noopener\">Kubernetes ingress TLS\/SSL Certificate guide<\/a> for more details.<\/p>\n<p>Here is a sample ingress object. Please refer to this <a href=\"https:\/\/github.com\/techiescamp\/kubernetes-prometheus\/blob\/master\/prometheus-ingress.yaml?ref=devopscube.com\" rel=\"noreferrer noopener\">GitHub link <\/a>for a sample ingress object with SSL<\/p>\n<pre><code class=\"language-yaml\">apiVersion: extensions\/v1beta1\nkind: Ingress\nmetadata:\n  name: prometheus-ui\n  namespace: monitoring\n  annotations:\n    kubernetes.io\/ingress.class: nginx\nspec:\n  rules:\n  # Use the host you used in your kubernetes Ingress Configurations\n  - host: prometheus.example.com\n    http:\n      paths:\n      - backend:\n          serviceName: prometheus-service\n          servicePort: 8080<\/code><\/pre>\n<h2 id=\"setting-up-kube-state-metrics\">Setting Up Kube State Metrics<\/h2>\n<p><strong>Kube state metrics<\/strong> service will provide many metrics that are not available by default. <\/p>\n<p>Please make sure you deploy Kube state metrics to monitor all your Kubernetes API objects like <code>deployments<\/code>, <code>pods<\/code>, <code>jobs<\/code>, <code>cronjobs<\/code> etc.<\/p>\n<p>Please follow this article to setup Kube state metrics on Kubernetes ==&gt; <a href=\"https:\/\/devopscube.com\/setup-kube-state-metrics\/\" rel=\"noreferrer noopener\">How To Setup Kube State Metrics on Kubernetes<\/a><\/p>\n<h2 id=\"setting-up-alertmanager\">Setting Up Alertmanager<\/h2>\n<p>Alertmanager handles all the alerting mechanisms for Prometheus metrics. There are many integrations available to receive alerts from the Alertmanager (Slack, email, API endpoints, etc)<\/p>\n<p>I have covered the Alert Manager setup in a separate article. Please follow ==&gt; <a href=\"https:\/\/devopscube.com\/alert-manager-kubernetes-guide\/\" rel=\"noopener noreferrer\">Alert Manager Setup on Kubernetes<\/a><\/p>\n<h2 id=\"setting-up-grafana\">Setting Up Grafana<\/h2>\n<p>Using Grafana, you can create dashboards from Prometheus metrics to monitor the Kubernetes cluster.<\/p>\n<p>The best part is, you don&#8217;t have to write all the PromQL queries for the dashboards.<\/p>\n<p>There are many community dashboard templates available for Kubernetes. You can import it and modify it as per your needs. I have covered it in the article.<\/p>\n<p>Please follow this article for the Grafana setup ==&gt; <a href=\"https:\/\/devopscube.com\/setup-grafana-kubernetes\/\" rel=\"noreferrer noopener\">How To Setup Grafana On Kubernetes<\/a><\/p>\n<h2 id=\"setting-up-node-exporter\">Setting Up Node Exporter<\/h2>\n<p>Node Exporter will provide all the Linux system-level metrics of all Kubernetes nodes.<\/p>\n<p>I have written a separate step-by-step guide on node-exporter daemonset deployment. Please follow <a href=\"https:\/\/devopscube.com\/node-exporter-kubernetes\/\" rel=\"noreferrer noopener\">Setting up Node Exporter on Kubernetes<\/a><\/p>\n<p>The scrape config for node-exporter is part of the Prometheus config map. Once you deploy the node-exporter, you should see node-exporter targets and metrics in Prometheus.<\/p>\n<h2 id=\"prometheus-production-setup-considerations\">Prometheus Production Setup Considerations<\/h2>\n<p>For the <strong>production Prometheus setup<\/strong>, there are more configurations and parameters that need to be considered for scaling, high availability, and storage. It all depends on your environment and data volume.<\/p>\n<p>For example, <a href=\"https:\/\/devopscube.com\/setup-prometheus-operator\/\" rel=\"noreferrer\">Prometheus Operator<\/a>  project makes it easy to automate Prometheus setup and its configurations.<\/p>\n<p>If you have multiple production clusters, you can use the CNCF project <a href=\"https:\/\/github.com\/thanos-io\/thanos?ref=devopscube.com\">Thanos<\/a> to aggregate metrics from multiple Kubernetes Prometheus sources.<\/p>\n<p>Thanos provides features like multi-tenancy, horizontal scalability, and disaster recovery, making it possible to operate Prometheus at scale with high availability.<\/p>\n<p>With Thanos, you can query data from multiple Prometheus instances running in different <a href=\"https:\/\/devopscube.com\/setup-kubernetes-cluster-kubeadm\/\">kubernetes clusters<\/a> in a single place, making it easier to aggregate metrics and run complex queries.<\/p>\n<p>Additionally, Thanos can store Prometheus data in an object storage backend, such as Amazon S3 or Google Cloud Storage, which provides an efficient and cost-effective way to retain long-term metric data.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>In this comprehensive <strong>Prometheus kubernetes tutorial<\/strong>, I have covered the setup of important monitoring components to understand Kubernetes monitoring.<\/p>\n<p>Also, If you are learning Kubernetes, you can check out my <a href=\"https:\/\/devopscube.com\/kubernetes-tutorials-beginners\/\" rel=\"noreferrer noopener\">Kubernetes beginner tutorials<\/a> where I have 60+ comprehensive guides.<\/p>\n<p>Let me know what you think about the Prometheus monitoring setup by leaving a comment.<\/p>\n<p>You can also use this setup to prepare for the Prometheus Certified Associate Certification.<\/p>\n<hr>\n<p><strong>Ngu\u1ed3n:<\/strong> <a href=\"https:\/\/devopscube.com\/setup-prometheus-monitoring-on-kubernetes\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to Setup Prometheus Monitoring On Kubernetes [Tutorial] \u2014 DevOpsCube<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Source: https:\/\/devopscube.com\/setup-prometheus-monitoring-on-kubernetes\/<\/p>\n","protected":false},"author":1,"featured_media":632,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-631","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-devops"],"_links":{"self":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/631","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=631"}],"version-history":[{"count":0,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/posts\/631\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=\/wp\/v2\/media\/632"}],"wp:attachment":[{"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=631"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=631"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.ngocha.biz\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=631"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}