Preface
最近把玩了 EKS 一陣子,基本上 EKS 就是 AWS 提供的 Managed Kubernetes,主要是幫你管理 Kubernetes 的 master node,我們只需要管理 worker node 就好了,所以很多的服務還是可以用原本的 helm chart 裝起來,這篇文章會介紹怎麼在 EKS 上面利用 helm 安裝 Prometheus 相關的套件,還有一些簡單的設定。
這篇文章會包含以下內容
- 利用 helm 安裝 Prometheus-operator 再透過 Operator 去部署 prometheus & alertmanager
- 如何設定 helm value 去避免一些 EKS 上面的錯誤問題
- Troubleshooting 的一些 tips
利用 helm 安裝 prometheus
因為 coreos/prometheus-operator
的 helm chart 已經被 deprecated 掉了,所以我們這邊會使用 stable/prometheus-operator
去做安裝,而這包 chart 其實有包含蠻多 components 像是 prometheus
& alertmanager
,還會幫你裝好 prometheus 需要監控用的 node-exporter
等等東西,所以非常大一包,很建議大家裝好後,可以回過頭來看看到底被安裝了哪些東西。
確認 stable/prometheus-operator 版本
1 | $ helm search -l stable/prometheus-operator |
可以看到目前最新的 Chart 版本是 4.0.0
1
2
3
4NAME CHART VERSION APP VERSION DESCRIPTION
stable/prometheus-operator 4.0.0 0.29.0 Provides easy monitoring definitions for Kubernetes servi...
stable/prometheus-operator 3.0.0 0.29.0 Provides easy monitoring definitions for Kubernetes servi...
stable/prometheus-operator 2.6.0 0.27.0 Provides easy monitoring definitions for Kubernetes servi...
安裝,這邊我們把安裝的名字取作 prom-op
1
$ helm install --name prom-op --namespace monitoring stable/prometheus-operator
透過以下的指令可以得知安裝了些什麼東西1
$ kubectl --namespace monitoring get pods
1 | NAME READY STATUS RESTARTS AGE |
因為我這台 k8s cluster 有起了 4 個 node,所以會安裝 4 個 node operator,然後還會安裝 prometheus-operator, alertmanager, grafana 和 kube-state-metrics。
Customizing the Chart
透過 port forward 讀取 localhost:9090 可以看到 prometheus 裡面的資訊1
$ kubectl port-forward svc/prom-op-prometheus-operato-prometheus -n monitoring 9090
其中我們會看到以下這些錯誤
因為我們無法監控到 EKS 的 master node,所以關於 master 上面的 services 像是 etcd, kube-apiserver, controller-manager, kube-schedule 都會在 prometheus 中發生錯誤,這也是為什麼我們需要客製化我們的 chart file。1
$ cp https://raw.githubusercontent.com/helm/charts/master/stable/prometheus-operator/values.yaml values.yaml
修改完後可以使用以下指令去覆寫1
helm upgrade --install prom-op stable/prometheus-operator --namespace monitoring -f values.yaml
這邊筆記下我有更改的部分,master 上面的 services 像是 etcd, kube-apiserver, controller-manager, kube-schedule 等等的 monitoring 機制需要被關閉1
2
3
4
5
6
7
8
9
10
11kubeApiServer
enabled: false
kubeControllerManager
enabled: false
kubeEtcd
enabled: false
kubeScheduler
enabled: false
kubelet 的話根據這個 issue,在 EKS 上面使用的話,我們需要把 https 的部分 enable 起來
1 | kubelet: |
EKS 上面的 coreDns 的 label 有點怪,還是用 k8s-app:kube-dns 而不是 coredns1
2
3
4
5
6
7coreDns:
enabled: true
service:
port: 9153
targetPort: 9153
selector:
k8s-app: kube-dns
還有一些 resource 的部分記得要調整下
1 | resources: |
設定 addtional scrape config
Prometheus 除了可以用來 monitor Kubernetes 內部的 service 外,其實也有提供一些方法去 scrape 外面的 service,像是有一些程式跑在既有的 EC2 上面,我們可以透過相對應的 EC2 service discovery 的方法去拉取資料,要達成相關的任務,則需要去設定 addtional config。
方法很簡單,需要先在 chart 的 value 中把原本的 additionalScrapeConfigs
1 | additionalScrapeConfigs: |
改寫為需要另外掛上去的 config
1 | additionalScrapeConfigs: |
但是這種做法需要一直更改 helm chart 的 value,而這邊也提供另外一種方法可以直接更改 config,讓 prometheus config reloader 去讀取,使用1
kubectl get secret -n monitoring
會看到有
1 | NAME TYPE DATA AGE |
我們可以透過直接更改這個 secret 的內容而改動 addtional-scrape-config,而以下這個 addtional-scrape-configs.yaml 以上面的例子會長成這樣
1 | - job_name: placeholder |
接著透過這行指令把這個 addtional-scrape-configs.yaml
轉成 k8s 認得的 secret yaml,在 apply 上去1
2$ kubectl create secret generic prom-op-prometheus-scrape-confg --from-file=additional-scrape-configs.yaml --dry-run -oyaml > prometheus-additional-scrape-configs.yaml
$ kubectl apply -f prometheus-additional-scrape-configs.yaml -n monitoring
設定 alert manager template
在使用完 prometheus-operator 的 helm 部署完後,其實可以從 UI 中的 status -> rules 中看到許多內建好的 prometheus 的 rule,而如果想要把這個警告發到 slack 上面還需要設定 alertmanager 的 route config,而內建的 config 其實沒做任何事情,都是導到 null 而已
1 | config: |
而這邊我們可以參考 Monza 的 alertmanager slack template ,這個 template 的好處就是可以幫 alert 都合併為一個發出來,然後也有吃內建的 rule 的 format,舉個例子像下面的這個 rule,裡面用到的 labels 是 serverity: critical
,然後 annotations 裡面是 message
& runbook_url
1 | alert: KubeAPIDown |
而透過 Monza 的 template 我們可以先設定 alertmanager 的 endpoint
1 | receivers: |
在透過定義好的 template 中,我們可以看到已經有確認收到的警告是 .Annotations.message
會被顯示出來,這樣一來就可以把相關的 rule alert 打到 slack 上了。
1 | # This builds the silence URL. We exclude the alertname in the range |
這邊還有一個很重要的步驟,讓我卡了蠻久的,其實 template 也是一樣定義在 prometheus-operator 的 helm chart value.yaml 裡面,在定義完 template 後,一定要加上1
2templates:
- '/etc/alertmanager/config/*.tmpl'
大概的範例長得像這樣
1 | config |
Troubleshoot
如果一直沒收到 alert 的話,有可能是 alertmanager 的 template 寫錯,可以透過
kubectl logs -f po/<alertmanager_pod_name> -n monitoring -c alertmanager
去確認下是不是有產生一些 error log。想要確認 alertmanager template 的語法的話,可以使用下面這個 script 去測試,主要是從這個 gist 看來的,這樣就可以邊改 template 邊驗證,不用真的去產生一些錯誤條件出來。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#!/bin/bash
name=$RANDOM
url='http://localhost:9093/api/v1/alerts'
echo "firing up alert $name"
# change url o
curl -XPOST $url -d "[{
\"status\": \"firing\",
\"labels\": {
\"alertname\": \"$name\",
\"service\": \"my-service\",
\"severity\":\"warning\",
\"instance\": \"$name.example.net\"
},
\"annotations\": {
\"summary\": \"High latency is high!\"
},
\"generatorURL\": \"http://prometheus.int.example.net/<generating_expression>\"
}]"
echo ""
echo "press enter to resolve alert"
read
echo "sending resolve"
curl -XPOST $url -d "[{
\"status\": \"resolved\",
\"labels\": {
\"alertname\": \"$name\",
\"service\": \"my-service\",
\"severity\":\"warning\",
\"instance\": \"$name.example.net\"
},
\"annotations\": {
\"summary\": \"High latency is high!\"
},
\"generatorURL\": \"http://prometheus.int.example.net/<generating_expression>\"
}]"
或是用
1 |
|
可以使用看看是否自己的 secret 內容是正確的
1
kubectl get secret -n monitoring alertmanager-prom-op-alertmanager -o go-template='{{ index .data "alertmanager.yaml" }}' | base64
完整移除 prometheus-operator
1 | $ helm delete --purge <name> |
後記
原本使用 prometheus-operator 其實還有個雷就是 servicemonitor 需要打上 release: <deploy_name>
,這樣 operator 才真的會去吃這個 service monitor,但是隨著 4.0.0 的更新也把這個惱人的東西修掉了,所以建議大家常常去看下到底更新了什麼,其實 prometheus & alertmanager 的版本也是一直推進很快的,而接下來有想到什麼更多的內容,還會繼續更新這篇。
Reference
- https://github.com/helm/charts/tree/master/stable/prometheus-operator
- https://github.com/prometheus/alertmanager/issues/437