摘要
本文範圍: Prometheus-Operator & kube-prometheus 安裝;以及在解決使用ServiceMonitor時遇到的坑。
Prometheus Operator 簡介
隨著雲原生概念盛行,對於容器、服務、節點以及叢集的監控變得越來越重要。Prometheus 作為 Kubernetes 監控的事實標準,有著強大的功能和良好的生態。但是它不支援分散式,不支援資料匯入、匯出,不支援透過 API 修改監控目標和報警規則,所以在使用它時,通常需要寫指令碼和程式碼來簡化操作。Prometheus Operator 為監控 Kubernetes service、deployment 和 Prometheus 例項的管理提供了簡單的定義,簡化在 Kubernetes 上部署、管理和執行 Prometheus 和 Alertmanager 叢集。
Prometheus Operator 功能如下:
- 建立/銷燬:在 Kubernetes namespace 中更加容易地啟動一個 Prometheues 例項,一個特定應用程式或者團隊可以更容易使用 Operator。
- 便捷配置:透過 Kubernetes CRD資源配置 Prometheus 的基本資訊,比如版本、(分散式)儲存、副本集、高可用等。
- 透過標籤標記目標服務: 基於常見的 Kubernetes label 查詢自動生成監控目標配置;不需要學習 Prometheus 特定的配置語言。
它使用如下的 Kubernetes CRD 資源對 Prometheus進行配置:
- Prometheus
- Alertmanager
- ThanosRuler
- ServiceMonitor
- PodMonitor
- Probe
- PrometheusRule
- AlertmanagerConfig
參考文件:
- https://github.com/prometheus-operator/kube-prometheus
- https://prometheus-operator.dev/docs/operator/design/
kube-prometheus 包含的軟體包:
- The Prometheus Operator
- Highly available Prometheus
- Highly available Alertmanager
- Prometheus node-exporter
- Prometheus Adapter for Kubernetes Metrics APIs
- kube-state-metrics
- Grafana
Prometheus Operator 相容性
- Kubernetes 1.16+ ,如需更低版本的 Kubernetes 相容性,請參考官方文件對應的版本分支。
以下程式碼分支對應的 Kubernetes 版本如下:
- release-0.9 1.21,1.22
- release-0.10 1.22,1.23
- release-0.11 1.23,1.24
- release-0.12 1.24,1.25
文章中已驗證的版本(PaaS 安裝版本)
- 本地叢集(kind 1.25) release-0.12
- 騰訊雲叢集(TKE 1.20) release-0.9
kube-prometheus 安裝解除安裝
安裝
git clone https://github.com/prometheus-operator/kube-prometheus.git
git checkout release-0.12
cd kube-prometheus
kubectl apply --server-side -f manifests/setup
kubectl wait \
--for condition=Established \
--all CustomResourceDefinition \
--namespace=monitoring
kubectl apply -f manifests/
解除安裝
kubectl delete --ignore-not-found=true -f manifests/ -f manifests/setup
helm安裝
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install prometheus-community/kube-prometheus-stack --namespace monitoring --generate-name
無論哪種安裝方式,遇到映象拉取失敗的情況,可以使用如下命令手動拉取映象並推送到自己的倉庫,本文中推送到自己的docker hub倉庫中,替換yaml中的image地址,然後再次執行安裝命令。
ServiceMonitor
ServiceMonitor 自定義資源(CRD)能夠宣告如何監控一組動態服務的定義。它使用標籤選擇定義一組需要被監控的服務。這樣就允許組織引入如何暴露 metrics 的規定,只要符合這些規定新服務就會被發現列入監控,而不需要重新配置系統。
一個 Service 可以公開一個或多個服務埠,通常情況下,這些埠由指向一個 Pod 的多個 Endpoints 支援。這也反映在各自的 Endpoints 物件中。
ServiceMonitorSpec 的 endpoints 部分用於配置需要收集 metrics 的 Endpoints 的埠和其他引數。在一些用例中會直接監控不在服務 endpoints 中的 pods 的埠。
例子
之前寫過一篇 《YoyoGo微服務框架入門系列-使用Prometheus監控Golang服務》 文章中的暴露的指標服務與本例中為同一個。
有如下 Service 指向 labels: k8s-app=dev-yoyogodemo-kind-kind 的 部署(Deployment):
apiVersion: v1
kind: Service
metadata:
name: dev-yoyogodemo-kind-kind-svc-cluster-sgr
namespace: klns-administration
labels:
k8s-app: dev-yoyogodemo-kind-kind
spec:
ports:
- name: default-tcp
protocol: TCP
port: 8080
targetPort: 8080
selector:
k8s-app: dev-yoyogodemo-kind-kind
type: ClusterIP
sessionAffinity: None
為其建立 ServiceMonitor 資源定義如下:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: dev-yoyogodemo-kind-kind-servicemontor
namespace: klns-administration
labels:
k8s-app: dev-yoyogodemo-kind-kind
spec:
endpoints:
- interval: 15s
path: /app/actuator/metrics
port: default-tcp
namespaceSelector:
matchNames:
- klns-administration
selector:
matchLabels:
k8s-app: dev-yoyogodemo-kind-kind
採坑
在預設配置中,此 ServiceMonitor 會因為 Kubenertes RBAC 叢集許可權問題,導致 ServiceMonitor不生效,表現為在Prometheus 的 targets 中看不到該 ServiceMonitor 的 targets。
檢視StatefulSet工作負載 prometheus-k8s 的狀態,檢視日誌,看到如下報錯:
services is forbidden: User "system:serviceaccount:monitoring:prometheus-k8s" cannot list services in the namespace monitoring
這是因為預設只配置了get許可權 。解決辦法是為 ServiceMonitor 新增如下的 ClusterRoleBinding,編輯 prometheus-k8s 角色繫結,新增如下內容:
...
- apiGroups:
- ""
resources:
- services
- endpoints
- pods
verbs:
- get
- list
- watch
修改後重啟 StatefulSet: prometheus-k8s; ServiceMonitor就會找到對應 Service 資源的 labels 選擇器的Endpoint資源, 並且會被 Prometheus Operator 自動配置為 Prometheus 的 targets。
當然ServiceMonitor不生效的原因還有很多,比如ServiceMonitor的namespaceSelector和selector不匹配,或者ServiceMonitor的namespaceSelector和Service的namespace不匹配等等。
為什麼配置的ServiceMonitor或PodMonitor未生效?
排查步驟:
- 確認Target是否已經被發現,找到目標Prometheus例項,然後在左側導航欄單擊服務發現,然後單擊Targets頁籤,檢查相應的Target是否已經被發現。
- 檢視叢集CRD中是否存在相應的ServiceMonitor資源。
- 確認Label Selector是否能選擇到期望的Pod或者Service
# 以上面那個例子為例。執行以下命令,觀察返回結果,若無返回結果,則需要調整Label Selector或Namespace Selector,即可篩選出期望的Pod或者Service。 kubectl get service -l k8s-app=dev-yoyogodemo-kind-kind -n klns-administration
- 檢查埠設定,埠port欄位,需要指定為pod定義中spec.containers[i].ports[i].name,或services定義中spec.ports[i].name欄位的值。
推廣
目前正在將Prometheus Operator整合到PaaS專案中,後續會將整合過程中遇到的問題和解決方案分享出來。
kubelilin 多雲 PaaS 開源專案: https://github.com/KubeLilin/kubelilin