Search
Close this search box.
How monitoring works in Kubernetes?

How monitoring works in Kubernetes?

Monitoring in Kubernetes involves observing and collecting data about the health, performance, and resource utilization of your cluster, nodes, pods, and containers. There are various tools available for monitoring Kubernetes applications, and one popular choice is Prometheus along with Grafana for visualization. In this tutorial, I’ll guide you through setting up monitoring for a simple Node.js application using Prometheus and Grafana.

Why is monitoring important?

Monitoring is essential in Kubernetes to ensure the health, performance, and reliability of applications and infrastructure. In the dynamic and distributed nature of Kubernetes, monitoring tools provide real-time insights into resource utilization, application behaviour, and system performance. This proactive approach allows for early issue detection, optimized resource allocation, and efficient troubleshooting. Monitoring aids in scaling applications, identifying bottlenecks, meeting security and compliance requirements, and making informed decisions about capacity planning. With alerts and notifications, monitoring enables rapid response to critical incidents, enhancing overall application stability. Ultimately, monitoring is a foundational practice that empowers organizations to maintain a resilient and high-performing Kubernetes environment, supporting both operational excellence and continuous improvement.

Let’s explore how monitoring works in Kubernetes through a simple tutorial.

Prerequisites:

Step 1: Set up the Node.js application

Let’s start with a basic Node.js application.

npm init -y

Create a file named app.js with the following code:

const http = require('http');

const server = http.createServer((req, res) => {

  res.writeHead(200, { 'Content-Type': 'text/plain' });

  res.end('Hello, Kubernetes monitoring tutorial!\n');

});

const PORT = process.env.PORT || 3000;

server.listen(PORT, () => {

  console.log(`Server running on port ${PORT}`);

});

If you run the application with the following command,

node app.js

Step 2: Set Up a Dockerfile

Create a Dockerfile and add the following code.

FROM node:14

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

EXPOSE 3000

CMD [ "node", "app.js" ]

Build the Docker image:
docker build -t nodejs-app .

Tag and push the Docker image to DockerHub

docker tag nodejs-app your-dockerhub-username/nodejs-app

Replace your-dockerhub-username with your actual Docker Hub username.

You need to authenticate with Docker Hub to be able to push images.

docker login

Push the tagged image to your Docker Hub repository.

docker push your-dockerhub-username/nodejs-app

Step 3: Deploy to Kubernetes

Assuming you have a Kubernetes cluster running. If not, start with Minikube.

minikube start

 Create a Kubernetes deployment for your application using a YAML file named app-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nodejs-app
  template:
    metadata:
      labels:
        app: nodejs-app
    spec:
      containers:
        - name: nodejs-app
          image: your-dockerhub-username/nodejs-app:latest
          ports:
            - containerPort: 3000

Apply the deployment:

kubectl apply -f app-deployment.yaml

Create a service YAML file

Create a file named app-service.yaml with the following content:

apiVersion: v1
kind: Service
metadata:
  name: nodejs-app-service
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 3000
      nodePort: 31080  # Change the node port to an available value
  selector:
    app: nodejs-app


Apply the service configuration:
kubectl apply -f app-service.yaml

Access the application

Now you should be able to access your Node.js application using the Minikube IP and the new node port (31080 in this case):

http://<minikube-ip>:31080

Step 4: Set up Prometheus

Create a file named prometheus-config.yaml for the Prometheus configuration:

apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
      - job_name: 'nodejs-app'
        static_configs:
          - targets: ['nodejs-app:3000']
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
        - name: prometheus
          image: prom/prometheus:v2.30.0
          args:
            - '--config.file=/etc/prometheus/prometheus.yml'
            - '--storage.tsdb.path=/prometheus'
          ports:
            - containerPort: 9090
          volumeMounts:
            - name: prometheus-config-volume
              mountPath: /etc/prometheus/
            - name: prometheus-storage-volume
              mountPath: /prometheus
      volumes:
        - name: prometheus-config-volume
          configMap:
            name: prometheus-config
        - name: prometheus-storage-volume
          emptyDir: {}

Apply the Prometheus configuration:

kubectl apply -f prometheus-config.yaml

Expose Prometheus using a NodePort service:

apiVersion: v1
kind: Service
metadata:
  name: prometheus-service
spec:
  type: NodePort
  ports:
    - port: 9090
      targetPort: 9090
      nodePort: 30000
  selector:
    app: prometheus

Apply the Prometheus service:
kubectl apply -f prometheus-service.yaml

Step 5: Set up Grafana

Create a file named grafana.yaml for the Grafana deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
        - name: grafana
          image: grafana/grafana:latest
          ports:
            - containerPort: 3000
          env:
            - name: GF_SECURITY_ADMIN_USER
              value: admin
            - name: GF_SECURITY_ADMIN_PASSWORD
              value: adminpassword

---
apiVersion: v1
kind: Service
metadata:
  name: grafana-service
spec:
  type: NodePort
  ports:
    - port: 3000
      targetPort: 3000
      nodePort: 31000
  selector:
    app: grafana

Apply the Grafana deployment and service:

kubectl apply -f grafana.yaml

Step 6: Accessing the services

Now you can access your application, Prometheus, and Grafana:

Step 7: Create a Grafana dashboard

Inside Grafana, you can create a new dashboard to visualize metrics collected by Prometheus.

Log in to Grafana.

Click on the “+” icon on the left panel and select “Dashboard.”

Click on “Add new panel.”

In the panel settings, choose “Panel Title” and “Visualization” (e.g., Time Series).

In the “Query” section, select “Prometheus” as the data source and enter a query (e.g., http_requests_total to visualize the total HTTP requests).

Customize the panel settings, such as axes, legends, and thresholds.

Click “Apply” to save the panel settings.

Understanding how monitoring works in Kubernetes is crucial for ensuring the smooth operation of complex containerized applications. By implementing a robust monitoring solution, such as Prometheus and Grafana, organizations can gain valuable insights into the health, performance, and resource utilization of their Kubernetes clusters and applications. Monitoring facilitates proactive issue detection, resource optimization, scalability, and fault tolerance. It empowers teams to analyze performance, plan capacity, and make data-driven decisions for continuous improvement. With real-time alerts and notifications, monitoring enables swift responses to critical incidents, enhancing application reliability and user experience. Ultimately, monitoring is an indispensable practice that empowers Kubernetes administrators and developers to maintain a resilient, high-performing environment, contributing to operational excellence in modern application deployment.


We are hiring!
Are you our new