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,暴露你的環境的一些關鍵資料。