はじめに
これは、監視ひよっこの inductor が Prometheus Operator に入門したときの記録です。意外と情報が古いものが多く、2022年現在だと何をどう入れるべきなのかがよくわからなくて困ったので誰かの助けになれば幸いです。
Prometheus Operator とは
Prometheus Operator は名前の通り Kubernetes のオペレーター実装の1つで、主要な監視ツールの1つである Prometheus 及びその関連コンポーネントを Kubernetes リソースとして管理できるようにしたものです。主に以下のようなリソースを管理することができます。
リソース名 | 役割 |
---|---|
Prometheus | Prometheus のデプロイ管理 |
Alertmanager | Alertmanager のデプロイ管理 |
ThanosRuler | Thanos Ruler をリソースとして管理 |
ServiceMonitor | Service リソースの監視ルールの定義 |
PodMonitor | Pod リソースの監視ルールの定義 |
Probe | 何に使うのかよくわかってないが、blackbox_exporter で使えるらしい |
PrometheusRule | Prometheus のアラートやメトリクスの保存に関するルールの定義 |
AlertmanagerConfig | Alertmanager の設定 (custom receiver とか) |
まだちょっと遊んだだけなので、僕自身が触ったのは Prometheus
、ServiceMonitor
、PrometheusRule
の3つだけです。
インストールするものがどれなのかわからない問題
まずは全体像の説明とかをする前に最初にハマった話を共有します。いいやって人は飛ばして全体像を見てからここに戻ってくるのもありです。
Prometheus Operator 単体では CRD とコントローラーのインストールまではしてくれますが、具体的にメトリクスを取れるまで手探りで育てていくのは結構難しいなと思いました。そこで、コミュニティが提供するさまざまなモニタリングの例を一気にインストールできるプロジェクトがあります。それが kube-prometheus です。これを使うと一気にバーン!とモニタリングできるようになって Grafana までデプロイしてくれるので、すごい!となります。これを読むと ServiceMonitor リソースと Service リソースの連携をどう設定すればよいかがわかるので勉強にもなります。
git clone https://github.com/prometheus-operator/kube-prometheus.git && kube-prometheus kubectl apply --server-side -f manifests/setup until kubectl get servicemonitors --all-namespaces ; do date; sleep 1; echo ""; done kubectl apply -f manifests/
なお、Helm で入れたい場合は kube-prometheus-stack という Chart もありますが、こちらは Prometheus Operator のチームが直接サポートしているものではないため、注意が必要です。
Prometheus Operator の全体像
Prometheus Operator は名前の通り Prometheus に関する様々なリソースを管理します。Prometheus のインスタンス自体を作成し、作成したPrometheus に対して監視のルールを仕込み、アラートの発火まで設定できるので、クラスター全体で1つの Prometheus スタックを管理することもできますし、クラスター規模によっては Namespace 単位で別々の Prometheus スタックを構築することもできます。
Prometheus が特定の namespace からしかメトリクスを取得できない問題
上記のようなユースケースの幅広さから、デフォルト設定における Prometheus
の設定ではモニターリソースをスクレイプできる namespace
が Prometheus がデプロイされたものだけに限定されています。この値は以下の2つの方法で変更することができます。
- Prometheus リソースの
serviceMonitorNamespaceSelector
フィールドに、スクレイプさせたい Namespace を 明示的に 指定する - Prometheus が使用する
ClusterRole
に権限を追加で付与する
自分はそれをやったおかげで NGINX Ingress Controller と ArgoCD のメトリクスまで Grafana で公開できるところまでやれました。長かった。
kubeadm における考慮点
Prometheus Operator を kubeadm で作ったクラスターでデプロイする場合、公式ドキュメントにあるようないくつかの考慮点があります。具体的には kube-controller-manager
と kube-scheduler
が listen するアドレスを変更する (127.0.0.1 -> 0.0.0.0) わけですが、このドキュメントでは apiVersion: kubeadm.k8s.io/v1alpha1
とあり、最新の apiVersion: kubeadm.k8s.io/v1beta3
に比べて非常に古く今の API では使えません。これに対応する PR を下記に作成したので、これを見て便利だと思った方はぜひ 👍 をお願いします。
Prometheus カスタムリソースがデプロイできない問題
CustomResourceDefinition.apiextensions.k8s.io "prometheuses.monitoring.coreos.com" is invalid: metadata.annotations: Too long: must have at most 262144 bytes
このエラーは prometheuses.monitoring.coreos.com
の CRD がでかすぎて kubectl apply
できないという話ですが、まだ解決していないので以下の issue で議論されている内容で workaround しつつウォッチしておくのがよさそうです。
アドオンとの連携
ArgoCD、Cilium、NGINX Ingressなどいくつかのリソースでは、Helm chart のオプションで ServiceMonitor
リソースをデプロイしてくれるような設定があります。NGINX Ingress の場合は以下のような values.yaml
が使えると思います。
controller: metrics: enabled: true serviceMonitor: enabled: true namespace: "" namespaceSelector: {} # Default: scrape .Release.Namespace only # To scrape all, use the following: # namespaceSelector: # any: true scrapeInterval: 30s # honorLabels: true targetLabels: [] relabelings: [] metricRelabelings: [] prometheusRule: enabled: true additionalLabels: {} # namespace: "" rules: # These are just examples rules, please adapt them to your needs - alert: NGINXConfigFailed expr: count(nginx_ingress_controller_config_last_reload_successful == 0) > 0 for: 1s labels: severity: critical annotations: description: bad ingress config - nginx config test failed summary: uninstall the latest ingress changes to allow config reloads to resume - alert: NGINXCertificateExpiry expr: (avg(nginx_ingress_controller_ssl_expire_time_seconds) by (host) - time()) < 604800 for: 1s labels: severity: critical annotations: description: ssl certificate(s) will expire in less then a week summary: renew expiring certificates to avoid downtime - alert: NGINXTooMany500s expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"5.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 for: 1m labels: severity: warning annotations: description: Too many 5XXs summary: More than 5% of all requests returned 5XX, this requires your attention - alert: NGINXTooMany400s expr: 100 * ( sum( nginx_ingress_controller_requests{status=~"4.+"} ) / sum(nginx_ingress_controller_requests) ) > 5 for: 1m labels: severity: warning annotations: description: Too many 4XXs summary: More than 5% of all requests returned 4XX, this requires your attention
さいごに
Prometheus Operator を一通り触ってみましたが、思ったよりも対応しているアドオンも多く、便利に使っていくことができそうです。それでは、今日はこのへんで。