Prometheus Operator — 為 Kubernetes 設定及管理 Prometheus

最近在公司內架設 Prometheus,昨天碰巧參加 DevOps Taiwan — Monitoring Tools 大亂鬥,現場有兩位講者介紹同一套工具,分別使用 PMM(註1) 及 kubectl(註2) 部署,而我則是使用 Prometheus Operator 完成這項任務

背景介紹

什麼叫做 Operator 呢?它是由 CoreOS 所主導的一項計畫,目的在於使複雜的 Application 可以輕鬆的架設及維護在 Kubernetes 中,可以到官網參見詳細說明(註3) 或是期待下一篇文章介紹,在開始之前先用圖解大概說明一般的 Prometheus 及 Prometheus Operator 不同之處

一般的 Prometheus 三個角色分別是 Exporter, Prometheus 及 Alertmanager,組態主要定義在 Prometheus 的 YAML 當中

  • Exporter: 必須把想要傳送給 Prometheus 的資料給暴露出來
  • Prometheus: 組態中會決定要去哪些 Exporter 把資料給拉 (Pull) 回來;假如事先定義的 alerting rules 被觸發,就會把 event 傳送給 Alertmanager
  • Alertmanager: 接收到從 Prometheus 來的 event,再根據定義的 notification 組態決定要通知的方法

上圖為透過 Prometheus Operator 安裝完的超簡易示意圖,透過 Operator 安裝就跟原本的有些差異,但在使用完後,我覺得管理上變得更簡潔乾淨,e.g. 譬如想要監控所有 K8S Node 該如何達成(註4) ?

  1. 負責輸出 Node Metric 的 Exporter 必須要存在
  2. 建立好連接到該 Exporter 的 K8S Service
  3. 需有一個 K8S CRD ServiceMonitor 透過 Label 對應到 K8S Service,該 CRD 會根據定義自動產生 scrape 組態,進而讓 Prometheus 可以取得 Metric 資料
  4. 負責監控的 rule 組態則定義在 K8S ConfigMap

所以假如要監控其他的 K8S Application 就是把上面的 4 個東西都準備好,Prometheus 就可以開始收到資料嘍~


開始安裝

必要條件

  • Kubernetes Cluster: 畢竟是 Prometheus Kubernetes Operator,必須要有 Kubernetes Cluster 才有辦法開始安裝 (本範例使用 minikube,切記要下 flag --memory 8192 把記憶體加大一點,避免 Prometheus 開不起來)
# 簡單檢查一下可以存取 Kubernetes Cluster
~$ kubectl get node
# 如下成功的取得 Node 資訊:

NAME STATUS ROLES AGE VERSION
minikube Ready master 13s v1.10.0
...
# 如下失敗無法取得 Node 資訊:

The connection to the server xxxxx was refused - did you specify the right host or port?
...
  • Helm: Helm 為 Kubernetes 的安裝管理套件,建議有使用 Kubernetes 的人,一定要使用它 (參見官方安裝教學)
# 安裝 Helm client
~$ brew install kubernetes-helm
# 安裝 Helm tiller 至 Kubernetes Cluster 中
~$ helm init
$HELM_HOME has been configured at /Users/smalltown/.helm.
Tiller (the Helm server-side component) has been installed into your Kubernetes Cluster.
Please note: by default, Tiller is deployed with an insecure 'allow unauthenticated users' policy.
For more information on securing your installation see: https://docs.helm.sh/using_helm/#securing-your-helm-installation
Happy Helming!
# 加入 CoreOS Helm repo,為後續安裝做準備
~$ helm repo add coreos https://s3-eu-west-1.amazonaws.com/coreos-charts/stable/

"coreos" has been added to your repositories

Prometheus Operator

首先安裝 Prometheus Operator,安裝完後感覺什麼都沒有,因為其主要是用來管理 Prometheus ,因此安裝完不會有 Prometheus 可以使用

  • 客製化組態 (可略過):假如有想要更改的組態值,可以建立一個新的 YAML檔案, e.g. prometheus-operator.yaml 並參考官方文件(註5),把想要更改的值定義在其中
  • 安裝指令如下:
# 按照預設組態安裝
~$ helm install coreos/prometheus-operator --name prometheus-operator --namespace monitoring
# 或是讀取客製化組態安裝(可略過)
~$ helm install coreos/prometheus-operator --name prometheus-operator --namespace monitoring --values
prometheus-operator.yaml
NAME:   prometheus-operator
LAST DEPLOYED: Sun May 27 22:13:19 2018
NAMESPACE: monitoring
STATUS: DEPLOYED
RESOURCES:
==> v1/ConfigMap
NAME DATA AGE
prometheus-operator 1 1m
...

kube-prometheus

kube-prometheus 有點像是一個 wrapper,安裝它的同時,會順便把 Prometheus/Alertmanager/Grafana 以及各種 K8S 內要用到的 Exporter 都一次安裝完畢!

  • 客製化組態 (可略過):假如有想要更改的組態值,可以建立一個新的 YAML檔案, e.g. kube-prometheus.yaml 並參考官方文件(註6, 註7),把想要更改的值定義在其中
  • 安裝指令如下
# 按照預設組態安裝
~$ helm install coreos/kube-prometheus --name kube-prometheus --namespace monitoring
# 或是讀取客製化組態安裝 (可略過)
~$ helm install coreos/kube-prometheus --name kube-prometheus --namespace monitoring --values
kube-prometheus.yaml
NAME:   kube-prometheus
LAST DEPLOYED: Sun May 27 22:16:11 2018
NAMESPACE: monitoring
STATUS: DEPLOYED
RESOURCES:
==> v1/Secret
NAME TYPE DATA AGE
alertmanager-kube-prometheus Opaque 1 1s
kube-prometheus-grafana Opaque 2 1s
...

驗證安裝

Helm 指令執行完成之後,當然要驗證有沒有正確安裝成功

# 觀察所有的 Pod 是不是已經都 ready 了
~$ kubectl get pod -n=monitoring
NAME                                                   READY     STATUS    RESTARTS   AGE
alertmanager-kube-prometheus-0 2/2 Running 0 3m
kube-prometheus-exporter-kube-state-76f498d465-qz928 2/2 Running 0 2m
kube-prometheus-exporter-node-fvf4l 1/1 Running 0 3m
kube-prometheus-grafana-b9bb6d4f-8vbc2 2/2 Running 0 3m
prometheus-kube-prometheus-prometheus-0 2/2 Running 2 3m
prometheus-operator-6d94d55b6d-trh48 1/1 Running 0 5m
# 利用 port forward 從 local 存取 K8S 內的 Grafana Service
~$ kubectl port-forward -n=monitoring svc/kube-prometheus-grafana 8080:80
Forwarding from 127.0.0.1:8080 -> 3000
Forwarding from [::1]:8080 -> 3000
Handling connection for 8080
...

打開瀏覽器連接 http://localhost:8080 (預設帳密 admin/admin),底下為 kubernetes-cluster-status Grafana 範本


高可用問題 (High Availability)

Prometheus Operator 如何解決 HA 的問題呢?!官方有詳細討論 (註8),底下我就 Prometheus 和 Alertmanager 稍微述說一下

Prometheus

Prometheus 在 Operator 中的 HA 作法很簡單,就是再多開幾台,每台都跑去拿 metric 資料,理論上都儲存一樣的資料,但實際上卻不可能,因為不可能每一台都同一個時間點去 exporter 拿,所以拿到的資料一定會有些許的差異 ( 可以使用 sessionAffinity 在 K8S Service 中解掉使用者看到不同資料的問題),但畢竟 alert 觸發是要經過一段時間的累積,所以也無傷大雅;最佳解是透過 sharding 跟 federation,不過複雜度相對高,CoreOS 正在思考怎麼做才是相對好的解法,並且實作在 Operator 讓大家可以輕鬆使用

Alertmanager

Alertmanager 在 Operator 中的 HA 作法也是再多開幾台,但這樣會不會造成 notification 被重複發送呢?版本 v0.5.0 後,有新增 HA 模式,透過Gossip Protocol 避免此種情況發生,而且保證 notification 有被送出

接下來…

當然就是花時間把 Application 的 Exporter 一個一個搞定,涵蓋在 Prometheus 監管的羽翼之下 !

Reference