Cloud native is a religion, a new model of technology, and it’s not limited to the one acre of space you have in mind. As long as you dare to think, everything can be original. As a cloud native fanatical believer, let me show you my fanatical degree:

All my services (including blog, image acceleration and comment service) are deployed in THE CLOUD K3S cluster. Meanwhile, the local and home devices are connected to the cloud cluster Pod network through WireGuard. The gateway DNS at home uses CoreDNS to split the resolution at home and abroad. Gateways use envoys to represent various services in your home, and so on.

All devices and services in the home, including those in the cloud, are monitored by Kube-Prometheus, which I won’t go into details about, but here are some pictures:

Now that there is one WireGuard left unmonitored, let’s take a look at using Prometheus to monitor WireGuard.

If you are still a WireGuard neophyte reading this, be sure to read each article in the following order:

  • WireGuard tutorial: How WireGuard works
  • WireGuard quick installation tutorial
  • WireGuard Configuration Tutorial: Use WG-gen-Web to manage the WireGuard configuration
  • Wireguard Full Mesh Configuration Guide

If you don’t understand, please refer to the notes of this article:

  • WireGuard tutorial: WireGuard setup and configuration in detail

The remaining articles are optional, if you are interested:

  • Why don’t I preach WireGuard
  • Why not “Why not WireGuard?”
  • WireGuard tutorial: Nat-to-NAT traversal using DNS-SD

WireGuard itself does not expose any indicators, and requires a third party’s EXPORTER to expose indicators. There are two versions of My friend, and neither is perfect, so I use both.

1. Build an image

Neither of my exporters offered a Docker image, so I had to do it myself. The Rust version of my exporter’s Dockerfile is as follows:

FROM rust as builder

LABEL description="Docker container for building prometheus exporter for wireguard."
LABEL maintainer="Ryan Yang <[email protected]>"

WORKDIR /usr/src/
RUN git clone https://github.com/MindFlavor/prometheus_wireguard_exporter.git; \
    cd prometheus_wireguard_exporter; \
    cargo install --path .

FROM debian:buster-slim
RUN sh -c "echo 'deb http://deb.debian.org/debian buster-backports main contrib non-free' > /etc/apt/sources.list.d/buster-backports.list"; \
    apt update; \
    apt install -y wireguard; \
    rm -rf /var/lib/apt/lists/*
COPY --from=builder /usr/local/cargo/bin/prometheus_wireguard_exporter /usr/local/bin/prometheus_wireguard_exporter
CMD ["prometheus_wireguard_exporter"]
Copy the code

The Go version of the Dockerfile is as follows:

FROM golang AS build

LABEL description="Docker container for building prometheus exporter for wireguard."
LABEL maintainer="Ryan Yang <[email protected]>"

WORKDIR /src
RUN git clone https://github.com/mdlayher/wireguard_exporter; \
    cd wireguard_exporter/cmd/wireguard_exporter/; \
    go build .

FROM busybox:glibc
COPY --from=build /src/wireguard_exporter/cmd/wireguard_exporter/wireguard_exporter .
CMD ["./wireguard_exporter"]
Copy the code

I won’t go into the construction of the image, you can look at my GitHub repository.

2. Prometheus_wireguard_exporter deployment

Prometheus_wireguard_exporter directly uses WARGAMING’s configuration files to extract metrics. Prometheus_wireguard_exporter does not need to prepare a separate configuration file itself, so it only needs to map the /etc/wireguard directory to the container. If your WARgaming networking mode is hub-and-spoke, it is recommended to monitor only the WARgaming gateway, or if you are in full interconnection mode, you can monitor only one of the nodes used to generate the configuration, or you can monitor all the nodes.

I only monitored one of the nodes used to generate the configuration here, and here is the deployment checklist:

# wireguard_exporter.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wireguard-exporter
  labels:
    app: wireguard-exporter
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: wireguard-exporter
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: wireguard-exporter
    spec:
      nodeSelector:
        kubernetes.io/hostname: blog-k3s03 
      tolerations:
      - key: node-role.kubernetes.io/ingress
        operator: Exists
        effect: NoSchedule
      hostNetwork: true 
      containers:
      - name: wireguard-exporter
        image: yangchuansheng/wireguard_exporter 
        command: ["/usr/local/bin/prometheus_wireguard_exporter"]
        args: ["-n"."/etc/wireguard/wg0.conf"."-r"]
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]
        ports:
        - containerPort: 9586 
          protocol: TCP
          name: http-metrics
        volumeMounts:
        - mountPath: /etc/localtime
          name: localtime
        - mountPath: /etc/wireguard
          name: config
      volumes:
      - name: localtime
        hostPath:
          path: /etc/localtime
      - name: config
        hostPath:
          path: /etc/wireguard
---
apiVersion: v1
kind: Service
metadata:
  name: wireguard-exporter
  labels:
    app: wireguard-exporter
spec:
  sessionAffinity: ClientIP
  selector:
    app: wireguard-exporter
  ports:
    - protocol: TCP
      name: http-metrics
      port: 9586
      targetPort: 9586
Copy the code

Deploy Prometheus_WireGuard_EXPORTER with the deployment list:

$ kubectl apply -f wireguard_exporter.yaml
Copy the code

Check whether the deployment is successful:

$ kubectl get pod -l app=wireguard-exporter
NAME                                  READY   STATUS    RESTARTS   AGE
wireguard-exporter-78d44b8bd9-ppm9t   1/1     Running   0          41s
Copy the code

3. Wireguard_exporter deployment

Wireguard_exporter requires an independent configuration file in the following format:

# /etc/wireguard/wg0.toml

[[Peer]]
public_key = "cGsHfwmPEiLJj6Fv3GU5xFvdyQByn50PC5keVGJEe0w="
name = "RouterOS"

[[Peer]]
public_key = "izv5L8Kn48+SVwE3D498mdi7YfSrn6aKDNIRxIAHDkU="
name = "macOS"

[[Peer]]
public_key = "EOM0eLVxsj9jGKWamuIn65T3Wmqw36uLOg2ss7yJ2gw="
name = "blog-k3s02"

[[Peer]]
public_key = "1RxEokE41ypnIMsbE5OVHFVx199V71MOYzpzQ8bbsFY="
name = "blog-k3s01"

[[Peer]]
public_key = "b3JiuvdOUV7cFpXyJzLbO2Ea4V4c4AoyugIC/ufGZ18="
name = "Openwrt"

[[Peer]]
public_key = "FIbzqNv10cdCDO/Ka2GIN9rpxNVV2tO2f00R71EHeSg="
name = "Oneplus"
Copy the code

You need to convert the configuration from wg0.conf to the wg0.toml file and map it to the container. The deployment list is as follows:

# wireguard_exporter_go.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wireguard-exporter-go
  labels:
    app: wireguard-exporter-go
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: wireguard-exporter-go
  strategy:
    rollingUpdate:
      maxSurge: 0
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: wireguard-exporter-go
    spec:
      nodeSelector:
        kubernetes.io/hostname: blog-k3s03 
      tolerations:
      - key: node-role.kubernetes.io/ingress
        operator: Exists
        effect: NoSchedule
      hostNetwork: true 
      containers:
      - name: wireguard-exporter-go
        image: docker.io/yangchuansheng/wireguard_exporter:golang 
        command: ["/wireguard_exporter"]
        args: ["-wireguard.peer-file"."/etc/wireguard/wg0.toml"."-metrics.addr".": 9587"]
        securityContext:
          capabilities:
            add: ["NET_ADMIN"]
        ports:
        - containerPort: 9587 
          protocol: TCP
          name: http-metrics
        volumeMounts:
        - mountPath: /etc/localtime
          name: localtime
        - mountPath: /etc/wireguard
          name: config
      volumes:
      - name: localtime
        hostPath:
          path: /etc/localtime
      - name: config
        hostPath:
          path: /etc/wireguard
---
apiVersion: v1
kind: Service
metadata:
  name: wireguard-exporter-go
  labels:
    app: wireguard-exporter-go
spec:
  sessionAffinity: ClientIP
  selector:
    app: wireguard-exporter-go
  ports:
    - protocol: TCP
      name: http-metrics
      port: 9587
      targetPort: 9587
Copy the code

Deploy WireGuard_exporter using the deployment list:

$ kubectl apply -f wireguard_exporter_go.yaml
Copy the code

Check whether the deployment is successful:

$ kubectl get pod -l app=wireguard-exporter-go NAME READY STATUS RESTARTS AGE wireguard-exporter-go-7f5c88fc68-h45x5 1/1  Running 0 52sCopy the code

4. Add Prometheus to the monitoring list

The deployment of Kube-Prometheus is omitted here, but I will only cover the key steps. To enable Kube-Prometheus to access the WireGuard metrics, create a ServiceMonitor resource as follows:

# prometheus-serviceMonitorWireguard.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    app: wireguard-exporter 
  name: wireguard-exporter
  namespace: monitoring
spec:
  endpoints:
  - interval: 15s
    port: http-metrics
  namespaceSelector:
    matchNames:
    - default 
  selector:
    matchLabels:
      app: wireguard-exporter 
---
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    app: wireguard-exporter-go
  name: wireguard-exporter-go
  namespace: monitoring
spec:
  endpoints:
  - interval: 15s
    port: http-metrics
  namespaceSelector:
    matchNames:
    - default
  selector:
    matchLabels:
      app: wireguard-exporter-go
Copy the code

Create the ServiceMonitor using the resource manifest:

$ kubectl apply -f prometheus-serviceMonitorWireguard.yaml
Copy the code

Check whether the Target of Prometheus has been obtained successfully:

Finally, a dashboard was added to Grafana to switch between monitoring dashboards for different WARgaming interfaces using environment variables.

As for the grammar details of the dashboard, I will not expand on it. Those who are interested can enter my dashboard first, and then ask me if they don’t understand. Dashboard JSON file link:

  • Cdn.jsdelivr.net/gh/yangchua…