A Day In The Life

とあるプログラマの備忘録

Prometheus のサービスディスカバリを使って Kubernetes 上に構築した Redis を監視する

こちらの記事で Prometheus の static_config を設定して Redis のメトリクスを取得する方法について紹介しました。

glassonion.hatenablog.com

Prometheus で監視対象のサーバの設定をする方法は static_config の他に Service Discovery があります。static_config はわかりやすく簡単に設定できるので入門にはとても良いのですが、実運用を考えると static_config よりも Service Discovery を使ってメトリクスを取得するのがおすすめです。この記事では Service Discovery を使って監視対象を設定する方法を紹介します。

前回のおさらい

前回の記事では Kubernetes 上に構築したマスター/スレーブ構成の Redis を Prometheus の static_config を使って監視するまでの流れを紹介しました。

前回作成したファイルは以下です。

  • 監視対象のファイル
    • redis-service.yaml(Redisのサービス)
    • redis-ss.yaml(RedisのStatefulSet)
    • redis.conf(Redisの設定ファイル)
    • launch.sh(Redisの起動ファイル)
  • Prometheus関連のファイル
    • prom-service.yaml(Prometheusのサービス)
    • prom-deployment.yaml(Prometheusのデプロイメント)
    • prometheus.yaml(Prometheusのコンフィグファイル)

今回は主に prometheus.yaml に関する内容になります。それ以外は権限回りの設定で RBAC ファイル追加や prom-deployment.yaml の修正をします。

サービスディスカバリを使う場合のPrometheusコンフィグの設定

サービスディスカバリの説明やコンフィグの内容の説明は後回しにして Prometheus のコンフィグファイルの設定をしてみます。

前回は static_configs を使って以下のように設定しました。

scrape_configs:
- job_name: redis_exporter
  static_configs:
  - targets:
    - redis-0.redis.default.svc:9121
    - redis-1.redis.default.svc:9121
    - redis-2.redis.default.svc:9121

static_configs の場合は監視する Pod を一つづつ targets に設定する必要があります。直感的でわかりやすいものの Pod を増やしたり減らしたりした場合に毎回修正が必要になるのでコンフィグファイルのメンテナンスが大変です。サービスディスカバリを使う場合は Pod をひとつひとつ指定するのではなく、「サービスを介してポート 9121 を公開している Pod を検知すること」というような指定をします。具体的に以下のようになります。

static_configs に比べると設定行数も増えて複雑になりましたが、こうすることで監視対象の Pod が増減しても設定ファイルの修正なしで済みます。

PrometheusのService Discovery

Prometheus の Service Discovery はコンフィグファイルに設定された情報から動的に監視対象を検知してくれる仕組みです。Prometheus の Service Discovery には以下の種類があります。

  • azure_sd_config
  • consul_sd_config
  • dns_sd_config
  • ec2_sd_config
  • openstack_sd_config
  • file_sd_config
  • gce_sd_config
  • kubernetes_sd_config
  • marathon_sd_config
  • nerve_sd_config
  • serverset_sd_config
  • triton_sd_config

Configuration | Prometheus から引用

Kubernetes のノードや Kubernetes 上に構築したサービスまたは Pod を監視する場合は kubernetes_sd_config を使います。kubernetes_sd_config は Kubernetes 向けの Service Discovery です。Prometheus のコンフィグに kubernetes_sd_config を設定することによって Prometheus が kube-apiserver(Kubernetes' REST API)を使って Pod や Service のメトリクスを収集することができるようになります。

static_config と kubernetes_sd_config の監視対象に対するアクセス方法の違いは以下のようになります。

種類 監視対象に対するアクセス方法
static_config HTTP アドレスを直指定してアクセスする
kubernetes_sd_config kube-apiserver を使って監視対象を探してから HTTP アクセスする

kubernetes_sd_configのロールの種類

kubernetes_sd_config は以下の5種類のロールを指定してメトリクスを取得します。種類によってそれぞれ検知できる監視対象が異なります。

Role 内容
node nodeを検出する
endpoints サービスに紐づいたPodを検出する
service サービスを検出する(Podは検出できない)
pod サービスに紐づいていないPodも含めて検出する
ingress ingressを検出する

Pod の監視設定をする場合は endpoints または pod を使います。Pod はサービス経由で公開していることが多いので endpoints を使うことが多いです。

設定したprometheus.yamlの説明

Prometheus のサービスディスカバリがどのようなものか理解できたと思うので、先ほど設定した prometheus.yaml ファイルの内容について説明していきます。

まずはロールの設定から見ていきます。以下はロールに endpoints を指定してサービス経由の Pod を検出できるようにしています。

kubernetes_sd_configs:
- role: endpoints

次は source_labels の action の部分です。こちらを指定することによりどのような条件の Pod を検知するか設定することができます。以下はネームスペース名 default かつポート番号が9121の Pod を検出するように指定しています。action には keep 以外に drop を指定することができます。drop を指定すると監視対象から外れます(明示的に監視対象から外したいときに使います)。

- source_labels:
  - __meta_kubernetes_namespace
  - __meta_kubernetes_pod_container_port_number
  regex: default;9121
  action: keep

最後に Prometheus の監視画面に表示される job 名と pod 名を設定します。こちらの設定は表示の設定なのでこだわりがなければ無くても問題ありません。

- source_labels:
  - __meta_kubernetes_service_name
  target_label: job
- source_labels:
  - __meta_kubernetes_pod_name
  target_label: pod

以上で Kubernetes 上に構築した Pod の監視設定は終わりです。

Kubernetes 1.8以上はRBACの設定が必要

Prometheus の static_config は直接 HTTP アドレスを指定してメトリクスを取得するので Kubernetes の権限まわりのことを考慮する必要はありませんでした。一方サービスディスカバリを使う場合は kube-apiserver から Kubernetes の情報を取得する必要があります。kube-apiserver から情報を取得するためには RBAC を設定する必要があります。GKE Kubernetes 1.7までは RBAC がまだ stable になっていなかったので設定は不要でした。しかし GKE Kubernetes 1.8から RBAC が stable になり、Prometheus の Pod に対して RBAC を設定しないと、サービスディスカバリを使った監視対象の検出ができなくなりました。RBAC のカスタムロールを作成して Prometheus の Pod に権限を付与する必要があります(監視対象のリソースに対して RBAC を設定することもできますが、それをすると Redis 側に修正を入れないといけなくなるため今回はその方法はとりません)。

RBAC を設定する

RBAC を設定するときにポイントは以下です。

  • Prometheus と監視対象(今回はRedis)の Namespace を分ける
    • Prometheus 側は stats、Redis 側は default ネームスペースを設定しています
  • カスタムロールを作成する
    • all-readerという名前のカスタムロールを作成します
  • Prometheus 側の Namespace にサービスアカウントを作成する
    • prometheusという名前のサービスアカウントを作成します
  • 作成したサービスアカウントにカスタムロールを紐づけて権限を付与する
    • prometheusサービスアカウントとall-readerロールを紐付けます
  • Prometheus の Pod にサービスアカウントを設定して監視対象を検出できるようにする
    • 別途 Prometheus の Deployment の yaml を修正します

上記ポイントを加味した RBAC の設定は以下のようになります。

Prometheus の Pod にサービスアカウントを設定して監視対象を検出できるようにする

RBAC の設定ができたので Prometheus の Pod に対して先ほど作成したサービスアカウントを以下のように紐付けます。

前回の記事の Deployment 設定に1行追加(17行目)しただけです。

... 省略 ...
    spec:
      serviceAccount: prometheus # 追加した設定
      containers:
... 省略 ...

デプロイして Prometheus の管理画面から Redis の状態を確認する

それでは設定したファイルをデプロイして Prometheus が監視対象を検知できるか確認してみます。Kustomize ファイルの内容は前回の記事から rbac.yaml が追加になった以外は同じです。

resources:
- redis-service.yaml
- redis-ss.yaml
- prom-service.yaml
- prom-deployment.yaml # 今回修正したファイル
- brac.yaml # 新規追加したファイル
configMapGenerator:
- name: redis-config
  files:
    - launch.sh
    - redis.conf
- name: prometheus-config
  namespace: stats
  files:
    - prometheus.yaml # 今回修正したファイル

今回修正したのは prom-deployment.yaml と prometheus.yaml の2ファイルです。あと新たに brac.yaml が追加になりました。 kustomize.yaml を base ディレクトリに保存して以下のコマンドを実行します。

kubectl apply -k base

デプロイが終わったら、ブラウザから Prometheus の管理画面(http://35.1x9.1x0.XXX:9090)にアクセスして Targets 画面に移動します。以下のように Redis Exporter が認識されて入れば成功です。

f:id:glass-_-onion:20200509194108p:plain
targets画面

まとめ

Prometheus のサービスディスカバリを使って Kubernetes のメトリクスを取得するには kubernetes_sd_config を使います。Kubernetes 1.8以上で Prometheus のサービスディスカバリを使うには RBAC の設定が必要です。

サンプルコード

今回のサンプルコードはこちらに置いています。

github.com

参考書籍

Prometheus について一番詳しく書かれている書籍です。

参考記事

関連記事