Monitor Mikrotik Router with Grafana and Prometheus (mikrotik-exporter)

We are going to deploy mikrotik-exporter to visualise Prometheus monitoring data for Mikrotik.

Pre-requisites

A Mikrotik router. I’ve been using Mikrotik for many years, and it’s done the job really well. In my honest opinion, the best thing you can do with your ISP-provided router is to recycle it.

I currently use RB951G-2HnD (upgraded my old RB751G-2HnD) and RB2011UiAS-2HnD-IN. The latter one is an absolute beast considering its £110 (~150$) price tag.

We are using our Kubernetes homelab to deploy mikrotik-exporter.

Configure Mikrotik Router

Enable API service from our homelab LAN:

/ip service set api address=10.11.1.0/24
/ip service enable api

Create a prometheus group on the router that has API and read-only access.

/user group add name=prometheus policy=api,read

Create a prometheus user to access the API.

/user add name=prometheus group=prometheus password=changeme

Download Files from GitHub

Configuration files used in this article are hosted on GitHub. Clone the following repository:

$ git clone https://github.com/lisenet/kubernetes-homelab.git
$ cd ./kubernetes-homelab/

Install and Configure mikrotik-exporter: Step by Step

Note that this homelab project is under development, therefore please refer to GitHub for any source code changes.

Create a Namespace

Create a monitoring namespace:

$ kubectl create ns monitoring

Create a Secret

Create a Kubernetes secret to store your Mikrotik password for the prometheus API user. Add your base64 encoded password to the file mikrotik-exporter-secret.yml and run the following command:

$ kubectl apply -f ./kubernetes/mikrotik-exporter/mikrotik-exporter-secret.yml

This is what the code looks like:

---
apiVersion: v1
kind: Secret
metadata:
  name: mikrotik-exporter-secret
  namespace: monitoring
data:
  password: base64-encoded-mikrotik-user-password

Create a Config Map

Create a config map that contains details about the router.

$ kubectl apply -f ./kubernetes/mikrotik-exporter/mikrotik-exporter-config-map.yml

This is what the code looks like:

---
apiVersion: v1
kind: ConfigMap
metadata:
  name: mikrotik-exporter-conf
  namespace: monitoring
  labels:
    app: mikrotik-exporter
data:
  device: mikrotik
  address: 10.11.1.1
  user: prometheus

Create a Deployment Configuration

$ kubectl apply -f ./kubernetes/mikrotik-exporter/mikrotik-exporter-deployment.yml

This is what the code looks like:

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mikrotik-exporter
  namespace: monitoring
  labels:
    app: mikrotik-exporter
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mikrotik-exporter
  template:
    metadata:
      labels:
        app: mikrotik-exporter
    spec:
      containers:
        - name: mikrotik-exporter
          image: nshttpd/mikrotik-exporter:1.0.11
          imagePullPolicy: IfNotPresent          
          env:
            - name: "DEVICE"
              valueFrom:
                configMapKeyRef:
                  name: mikrotik-exporter-conf
                  key: device
            - name: "ADDRESS"
              valueFrom:
                configMapKeyRef:
                  name: mikrotik-exporter-conf
                  key: address
            - name: "USER"
              valueFrom:
                configMapKeyRef:
                  name: mikrotik-exporter-conf
                  key: user
            - name: "PASSWORD"
              valueFrom:
                secretKeyRef:
                  name: mikrotik-exporter-secret
                  key: password
            - name: "LOG_LEVEL"
              value: DEBUG
          ports:
            - containerPort: 9436
          volumeMounts:
            - name: mikrotik-exporter-volume
              mountPath: /etc/mikrotik-exporter
      restartPolicy: Always
      terminationGracePeriodSeconds: 60
      volumes:
        - name: mikrotik-exporter-volume
          emptyDir: {}

Create a Service

$ kubectl apply -f ./kubernetes/mikrotik-exporter/mikrotik-exporter-service.yml

This is what the code looks like:

---
apiVersion: v1
kind: Service
metadata:
  name: mikrotik-exporter
  namespace: monitoring
  labels:
    app: mikrotik-exporter
spec:
  selector: 
    app: mikrotik-exporter
  type: NodePort  
  ports:
    - port: 9436
      targetPort: 9436

Check Monitoring Namespace

$ kubectl -n monitoring get all -l app=mikrotik-exporter
NAME                                    READY   STATUS    RESTARTS   AGE
pod/mikrotik-exporter-7cf8d9b85-dfxtx   1/1     Running   0          76s

NAME                        TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/mikrotik-exporter   NodePort   10.106.36.83   none          9436:30528/TCP   14d

NAME                                READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/mikrotik-exporter   1/1     1            1           14d

NAME                                          DESIRED   CURRENT   READY   AGE
replicaset.apps/mikrotik-exporter-7cf8d9b85   1         1         1       6d4h

Configure Prometheus Scraping

Add static config that matches your Mikrotik router to the Prometheus config map and restart the pod.

      - job_name: 'mikrotik-exporter'
        scrape_interval: 30s
        static_configs:
          - targets:
            - 10.11.1.1 # your Mikrotik router IP you wish to monitor
        metrics_path: /metrics
        params:
          module: [my_router]
        relabel_configs:
          - source_labels: [__address__]
            target_label: __param_target
          - source_labels: [__param_target]
            target_label: instance
          - target_label: __address__
            replacement: mikrotik-exporter:9436

Grafana Dashboard for Mikrotik

You can install a dashboard to monitor Mikrotik metrics: https://grafana.com/grafana/dashboards/12055

References

https://github.com/nshttpd/mikrotik-exporter

Leave a Reply

Your email address will not be published. Required fields are marked *