WireGuard 教程:使用 Prometheus 监控 WireGuard

云原生是一种信仰,是一种全新的技术模式,它不局限于你脑海中固有的那一亩三分地。人有多大胆,地有多大产,只要你敢想,万物皆可云原生。作为一个云原生狂热信徒,给大家看看我的狂热程度:

我的所有服务(包括博客、镜像加速、评论服务)都部署在云上 k3s 集群中,同时本地和家中设备均和云上集群 Pod 网络通过 WireGuard 打通,家中网关 DNS 用的是 CoreDNS 对国内外解析进行分流,网关使用 Envoy 来代理家中的各种服务,等等。

家中的所有设备和服务,包括云上的服务,全部使用 kube-prometheus 进行监控,具体我就不细说了,截几张图给大家看看:

现在还剩下个 WireGuard 没有监控,下面就来看看如何使用 Prometheus 来监控 WireGuard

如果看到这篇文章的你仍然是个 WireGuard 新手,请务必按照以下顺序阅读每一篇文章:

如果遇到不明白的,可以参考这篇文章的注解:

剩下这几篇文章是可选的,有兴趣就看看:

WireGuard 本身是不暴露任何指标的,需要通过第三方的 exporter 来暴露指标。目前有两个版本的 exporter,单纯使用其中一个都不太完美,所以我干脆都用。

1. 镜像构建

这两个 exporter 都没有提供 Docker 镜像,所以我只好自己动手了,Rust 版本 exporter 的 Dockerfile 如下:

FROM rust as builder

LABEL description="Docker container for building prometheus exporter for wireguard."
LABEL maintainer="Ryan Yang <yangchuansheng33@gmail.com>"

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"]

Go 版本 exporter 的 Dockerfile 如下:

FROM golang AS build

LABEL description="Docker container for building prometheus exporter for wireguard."
LABEL maintainer="Ryan Yang <yangchuansheng33@gmail.com>"

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"]

镜像的构建我就不赘述了,大家可以看我的 GitHub 仓库

2. prometheus_wireguard_exporter 部署

prometheus_wireguard_exporter 直接利用 wg 的配置文件来获取指标,它自己不需要单独准备配置文件,所以只需将 /etc/wireguard 目录映射到容器中。如果你的 wg 组网模式是中心辐射型,建议只需监控 wg 网关,如果是全互联模式,也可以只监控其中一个用来生成配置的节点,当然你也可以监控所有节点。

我这里只监控了其中一个用来生成配置的节点,以下是部署清单:

# 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

使用部署清单部署 prometheus_wireguard_exporter

$ kubectl apply -f wireguard_exporter.yaml

查看是否部署成功:

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

3. wireguard_exporter 部署

wireguard_exporter 需要单独准备配置文件,格式如下:

# /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"

你需要将 wg0.conf 中的配置内容转化为上面的格式保存到 wg0.toml 文件中,再将其映射到容器中。部署清单如下:

# 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

使用部署清单部署 wireguard_exporter

$ kubectl apply -f wireguard_exporter_go.yaml

查看是否部署成功:

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

4. 加入 Prometheus 监控

kube-prometheus 的部署方式这里略过,新手请自己查阅文档部署,我只讲关键的步骤。要想让 kube-prometheus 能获取到 WireGuard 的指标,需要创建相应的 ServiceMonitor 资源,资源清单如下:

# 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

使用资源清单创建 ServiceMonitor

$ kubectl apply -f prometheus-serviceMonitorWireguard.yaml

查看 Prometheus 中对应的 Target 是否已经获取成功:

最后在 Grafana 中添加仪表盘,通过环境变量来切换不同 wg 接口的监控仪表盘。

至于仪表盘的语法细节,我就不展开讲了,感兴趣的可以先导入我的仪表盘,后面遇到不懂的再来问我。仪表盘 json 文件链接:

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,444评论 4 365
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,867评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,157评论 0 248
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,312评论 0 214
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,673评论 3 289
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,802评论 1 223
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,010评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,743评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,470评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,696评论 2 250
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,187评论 1 262
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,538评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,188评论 3 240
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,127评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,902评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,889评论 2 283
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,741评论 2 274

推荐阅读更多精彩内容