1. 程式人生 > 其它 >Traefik SRE 之使用 Prometheus 進行監控報警

Traefik SRE 之使用 Prometheus 進行監控報警

當我們使用 Traefik 作為 Kubernetes 的 Ingress 控制器的時候,我們自然也非常有必要對其進行監控。本文我們將探討如何使用 Prometheus 和 Grafana 從 Traefik 提供的 metrics 指標中進行監控報警。

安裝

首先你需要一個可以訪問的 Kubernetes 叢集。

部署 Traefik

這裡我們使用更加簡單的 Helm 方式來安裝部署 Traefik。首先使用以下命令將 Traefik 新增到 Helm 的倉庫中:

$ helm repo add traefik https://helm.traefik.io/
$ helm repo update

然後我們可以在 kube-system 名稱空間下來部署最新版本的 Traefik,在我們這個示例中,我們還需要確保在叢集中啟用了 Prometheus 指標,可以通過給 Helm 傳遞 --metrics.prometheus=true 標誌來實現,這裡我們將所有配置都放置到下面的 traefik-values.yaml 檔案中:

# traefik-values.yaml

# 簡單使用 hostPort 模式
ports:
  web:
    port: 8000
    hostPort: 80
  websecure:
    port: 8443
    hostPort: 443
   
service:
  enabled: false
# 不暴露 dashboard
ingressRoute:
  dashboard:
    enabled: false

# 開啟 prometheus 監控指標
additionalArguments:
- --api.debug=true
- --metrics.prometheus=true

# kubeadm 安裝的叢集預設情況下master是有汙點,需要容忍這個汙點才可以部署
# 這裡我們將 traefik 固定在 master 節點
tolerations:   
- key: "node-role.kubernetes.io/master"
  operator: "Equal"
  effect: "NoSchedule"

nodeSelector: 
  kubernetes.io/hostname: "master1"

直接使用如下所示的命令安裝:

$ helm install traefik traefik/traefik -n kube-system -f ./traefik-values.yaml
NAME: traefik
LAST DEPLOYED: Mon Apr  5 11:49:22 2021
NAMESPACE: kube-system
STATUS: deployed
REVISION: 1
TEST SUITE: None

由於我們預設沒有為 Traefik 的 Dashboard 建立 IngressRoute 物件,這裡我們使用 port-forward 來臨時訪問即可,當然首先需要為 Traefik Dashboard 建立一個 Service:

# traefik-dashboard-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: traefik-dashboard
  namespace: kube-system
  labels:
    app.kubernetes.io/instance: traefik
    app.kubernetes.io/name: traefik-dashboard
spec:
  type: ClusterIP
  ports:
  - name: traefik
    port: 9000
    targetPort: traefik
    protocol: TCP
  selector:
    app.kubernetes.io/instance: traefik
    app.kubernetes.io/name: traefik

直接建立,然後使用埠轉發來訪問:

$ kubectl apply -f traefik-dashboard-service.yaml
$ kubectl port-forward service/traefik-dashboard 9000:9000 -n kube-system
Forwarding from 127.0.0.1:9000 -> 9000
Forwarding from [::1]:9000 -> 9000

接下來我們就可以通過瀏覽器 http://localhost:9000/dashboard/(注意 URL 中的尾部斜槓,這是必須的)訪問 Traefik Dashboard 了,現在應該可以看到在儀表板的 Features 部分啟用了 Prometheus 指標。

此外我們還可以訪問 http://localhost:9000/metrics 端點來檢視 Traefik 提供的一些 metrics 指標:

部署 Prometheus Stack

Prometheus 完整的工具鏈由許多元件組成,如果要完全手動去安裝配置需要較長時間,感興趣的朋友可以參考前面我們的文章相關介紹。同樣這裡我們直接使用 Prometheus 的 Helm Charts 來部署:

$ helm repo add prometheus-community https://github.com/prometheus-community/helm-charts
$ helm repo update

上述資源庫提供了許多 Chart,要檢視完整的列表,你可以使用搜索命令:

$ helm search repo prometheus-community

這裡我們需要安裝的是 kube-prometheus-stack 這個 Chart,它會部署所需要的相關元件:

$ helm install prometheus-stack prometheus-community/kube-prometheus-stack
NAME: prometheus-stack
LAST DEPLOYED: Mon Apr  5 12:25:22 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
NOTES:
kube-prometheus-stack has been installed. Check its status by running:
  kubectl --namespace default get pods -l "release=prometheus-stack"

Visit https://github.com/prometheus-operator/kube-prometheus for instructions on how to create & configure Alertmanager and Prometheus instances using the Operator.

配置 Traefik 監控

Prometheus Operator 提供了 ServiceMonitor 這個 CRD 來配置監控指標的採集,這裡我們定義一個如下所示的物件:

# traefik-service-monitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name:  traefik
  namespace: default
  labels:
    app: traefik
    release: prometheus-stack
spec:
  jobLabel: traefik-metrics
  selector:
    matchLabels:
      app.kubernetes.io/instance: traefik
      app.kubernetes.io/name: traefik-dashboard
  namespaceSelector:
    matchNames:
    - kube-system
  endpoints:
  - port: traefik
    path: /metrics

根據上面的配置,Prometheus 將獲取 traefik-dashboard 服務的 /metrics 端點。主要注意的是 traefik-dashboard 服務是在 kube-system 名稱空間中建立的,而 ServiceMonitor 則部署在預設的 default 名稱空間中,所以這裡面我們使用了 namespaceSelector 進行名稱空間匹配。

$ kubectl apply -f traefik-service-monitor.yaml

接下來我們可以來驗證一下 Prometheus 是否已經開始抓取 Traefik 的指標了。

配置 Traefik 報警

接下來我們還可以新增一個報警規則,當條件匹配的時候會觸發報警,同樣 Prometheus Operator 也提供了一個名為 PrometheusRule 的 CRD 物件來配置報警規則:

# traefik-rules.yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  annotations:
    meta.helm.sh/release-name: prometheus-stack
    meta.helm.sh/release-namespace: default
  labels:
    app: kube-prometheus-stack
    release: prometheus-stack
  name: traefik-alert-rules
  namespace: default
spec:
  groups:
  - name: Traefik
    rules:
    - alert: TooManyRequest
      expr: avg(traefik_entrypoint_open_connections{job="traefik-dashboard",namespace="kube-system"}) > 5
      for: 1m
      labels:
        severity: critical

這裡我們定義了一個規則:如果1分鐘內有超過5個 open connections 機會觸發一個 TooManyRequest 報警,直接建立這個物件即可:

$ kubectl apply -f traefik-rules.yaml

建立完成後正常在 Promethues 的 Dashboard 下的 Status > Rules 頁面就可以看到對應的報警規則:

Grafana 配置

前面使用 kube-prometheus-stack 這個 Helm Chart 部署的時候就已經部署上了 Grafana,接下來我們可以為 Traefik 的監控指標配置一個 Dashboard,同樣首先我們使用埠轉發的方式來訪問 Grafana:

$ kubectl port-forward service/rometheus-stack-grafana 10080:80

然後訪問 Grafana GUI(http://localhost:10080)時,它會要求輸入登入名和密碼,預設的登入使用者名稱是 admin,密碼是 prom-operator,密碼可以從名為 prometheus-operator-grafana 的 Kubernetes Secret 物件中獲取。

當然我們可以自己為 Traefik 自定義一個 Dashboard,也可以從 Grafana 的官方社群中匯入一個合適的即可,點選左側導航欄上的四方形圖示,導航到 Dashboards > Manage,即可新增儀表盤。

點選右上角的 Import 按鈕,輸入 11462 作為 Dashboard 的 ID,對應使用者 timoreymann 貢獻的 Traefik 2 儀表盤。

點選 Load 後,你應該看到匯入的儀表盤的相關資訊。

在最下面有一個下拉選單,選擇 Prometheus 資料來源,然後點選 Import,即可生成如下所示的 Dashboard。

測試

現在,Traefik 已經開始工作了,並且指標也被 Prometheus 和 Grafana 獲取到了,接下來我們需要使用一個應用程式來測試。這裡我們部署 HTTPBin 服務,它提供了許多端點,可用於模擬不同型別的使用者流量。對應的資源清單檔案如下所示:

# httpbin.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: httpbin
  labels:
    app: httpbin
spec:
  replicas: 1
  selector:
    matchLabels:
      app: httpbin
  template:
    metadata:
      labels:
        app: httpbin
    spec:
      containers:
      - image: kennethreitz/httpbin
        name: httpbin
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: httpbin
spec:
  ports:
  - name: http
    port: 8000
    targetPort: 80
  selector:
    app: httpbin
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: httpbin
spec:
  entryPoints:
    - web
  routes:
  - match: Host(`httpbin.local`)
    kind: Rule
    services:
    - name: httpbin
      port: 8000

直接建立上面的資源清單:

$ kubectl apply -f httpbin.yaml
deployment.apps/httpbin created
service/httpbin created
ingressroute.traefik.containo.us/httpbin created

httpbin 路由會匹配 httpbin.local 的主機名,然後將請求轉發給 httpbin Service:

$ curl -I http://192.168.31.75  -H "host:httpbin.local"
HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Content-Length: 9593
Content-Type: text/html; charset=utf-8
Date: Mon, 05 Apr 2021 05:43:16 GMT
Server: gunicorn/19.9.0

我們這裡部署的 Traefik 使用的是 hostPort 模式,固定到 master 節點上面的,這裡的 IP 地址 192.168.31.75 就是 master 節點的 IP 地址。

接下來我們使用 ab 來訪問 HTTPBin 服務模擬一些流量,這些請求會產生對應的指標,執行以下指令碼:

$ ab -c 5 -n 10000  -m PATCH -H "host:httpbin.local" -H "accept: application/json" http://192.168.31.75/patch
$ ab -c 5 -n 10000  -m GET -H "host:httpbin.local" -H "accept: application/json" http://192.168.31.75/get
$ ab -c 5 -n 10000  -m POST -H "host:httpbin.local" -H "accept: application/json" http://192.168.31.75/post

正常一段時間後再去檢視 Grafana 的 Dashboard 可以看到顯示了更多的資訊:

包括:正常執行的時間、平均響應時間、請求總數、基於 HTTP 方法和服務的請求計數等。

最後,當我們測試應用流量時,Prometheus 可能會觸發報警,之前建立的 TooManyRequest 報警將顯示在 Alertmanager 儀表板上,然後可以自己根據需要配置接收報警資訊的 Receiver 即可。

$ kubectl port-forward service/prometheus-stack-kube-prom-alertmanager 9093:9093
Forwarding from 127.0.0.1:9093 -> 9093

總結

在本文中,我們已經看到了將 Traefik 連線到 Prometheus 和 Grafana 以從 Traefik 指標中建立視覺化的過程是非常簡單的。當熟悉這些工具後,我們也可以根據實際需求建立一些 Dashboard,暴露你的環境的一些關鍵資料。