inductor's blog

nothing but self note :)

Prometheus Operator に入門した

はじめに

これは、監視ひよっこの 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 とか)

まだちょっと遊んだだけなので、僕自身が触ったのは PrometheusServiceMonitorPrometheusRule の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 に権限を追加で付与する

github.com

github.com

自分はそれをやったおかげで NGINX Ingress Controller と ArgoCD のメトリクスまで Grafana で公開できるところまでやれました。長かった。

kubeadm における考慮点

Prometheus Operator を kubeadm で作ったクラスターでデプロイする場合、公式ドキュメントにあるようないくつかの考慮点があります。具体的には kube-controller-managerkube-scheduler が listen するアドレスを変更する (127.0.0.1 -> 0.0.0.0) わけですが、このドキュメントでは apiVersion: kubeadm.k8s.io/v1alpha1 とあり、最新の apiVersion: kubeadm.k8s.io/v1beta3 に比べて非常に古く今の API では使えません。これに対応する PR を下記に作成したので、これを見て便利だと思った方はぜひ 👍 をお願いします。

github.com

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 しつつウォッチしておくのがよさそうです。

github.com

github.com

アドオンとの連携

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 を一通り触ってみましたが、思ったよりも対応しているアドオンも多く、便利に使っていくことができそうです。それでは、今日はこのへんで。