LoginSignup
19
13

More than 1 year has passed since last update.

kube-state-metrics でカスタムリソースのメトリクスを取得する方法

Last updated at Posted at 2023-04-05

はじめに

Kubernetes を利用していると、カスタムリソースやカスタムコントローラーをして使用して機能を追加するケースが出てきます。それらのメトリクスを取得したい場合は対応する Exporter を自作するなりして用意する必要があります。

そこで、kube-state-metrics でもカスタムリソースをサポートするための機能(Custom Resource State Metrics)が v2.4.0 から追加されました。該当機能のリリース当初はそこまで使いやすい機能ではなかったのですが、執筆時点の最新版の v2.8.2 ではだいぶ改善されて使いやすくなりました。

ただ、ドキュメントがそこまで整備されておらず、ソースコードを確認しながらでないと使うのが難しいので記事にまとめてみました。

kube-state-metrics とは

以下が公式の Overview から一部抜粋してきた説明文になります。

kube-state-metrics is a simple service that listens to the Kubernetes API server and generates metrics about the state of the objects.

上記の説明に書いてある通り、 Kubernetes の API server を定期的に確認して Kubernetes のオブジェクトの状態をメトリクスとして提供してくれます。

今回の話は、メトリクスを取得する対象のオブジェクトに任意のカスタムリソースを指定する機能(Custom Resource State Metrics)の話になります。

概要

実際の利用イメージ

詳細な説明をする前に、簡単な利用イメージを先に説明します。

  1. 設定ファイルの作成
    以下のような設定ファイルを作成します。

    kind: CustomResourceStateMetrics
    spec:
      resources:
      - groupVersionKind:  # 対象となるカスタムリソースの情報を設定
          group: myteam.io
          kind: "Foo"
          version: "v1"
    
        metrics:   
          - name: "uptime"  # メトリクス名
            help: "Foo uptime"  # HELP に表示するメッセージを設定
            each:  
              type: Gauge  # メトリクスの Type を選択
              gauge:
                path: [status, uptime]  # メトリクスの値の設定。 e.g. `sataus.uptime` の値が設定される
    
          - name: "info"
            help: "Foo version"
            each:
              type: Info  
              info:  # 条件に一致するときに value が `1` になるメトリクス 
                labelsFromPath:
                       version: [spec, version]  # e.g. `spec.version` に値が存在するときにメトリクスが出力される 
    
          - name: "phase"
            help: "Foo phase"
            each:
              type: StateSet
              stateSet:  # list で指定した条件に一致する数をカウントして出力するメトリクス
                path: [status, phase]  # e.g. `status.phase` の配下で list に一致するものをカウントする
                labelName: phase  # list のラベルをメトリクスに追加する時の key 名の設定
                list: [Active, Running, Terminating, Pending]
    
    
  2. kube-state-metrcsの引数に設定
    --custom-resource-state-config-file 等を用いて、kube-state-metrics に設定を読み込ませます。

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        k8s-app: kube-state-metrics
      name: kube-state-metrics
      namespace: kube-system
    spec:
      replicas: 1
      selector:
        matchLabels:
          k8s-app: kube-state-metrics
      template:
        metadata:
          labels:
            k8s-app: kube-state-metrics
        spec:
          containers:
          - name: kube-state-metrics
            args:
            - --custom-resource-state-config-file=/ksm-config/custom-resource-state-metrics.yaml  # 引数に設定ファルの path を設定する
            image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.8.2
                :
            volumeMounts:
            - mountPath: /ksm-config
              name: custom-resource-state-config-volume
          volumes:
          - configMap:
              items:
              - key: custom-resource-state-metrics.yaml
                path: custom-resource-state-metrics.yaml
              name: custom-resource-state-config
            name: custom-resource-state-config-volume
    

    注意点
    kind: CustomResourceStateMetrics カスタムリソースではなく、単にそういう設定ファイルを用意して --custom-resource-state-config-file で対象のファイルパスを指定して使います。Kubernetes に使い慣れているとそういうカスタムリソースがあると誤解するケースが多いですが、ただの設定ファイルのフォーマットの話なので気をつけてください。CustomResourceStateMetricsをカスタムリソースにする件についてはこちらの issue で現在検討中になります。

  3. メトリクスの出力
    正しく設定できていると以下のようなメトリクスが出力されます

    • メトリクスタイプがGaugeの場合
    # HELP kube_customresource_uptime Foo uptime
    # TYPE kube_customresource_uptime gauge
    kube_customresource_uptime{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21
    
    • メトリクスタイプがInfoの場合
    # HELP kube_customresource_info Foo version
    # TYPE kube_customresource_info info
    kube_customresource_info{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",version="v1.2.3"} 1
    
    • メトリクスタイプがStateSetの場合
    # HELP kube_customresource_phase Foo phase
    # TYPE kube_customresource_phase stateset
    kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Active"} 0
    kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Pending"} 1
    kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Running"} 0
    kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Terminating"} 0
    

利用用途

kube-state-metrics でもカスタムリソースのメトリクスを出力する機能をCustom Resource State Metricsと言います。こちらの機能を使用する利用用途について記載します。

カスタムリソースのメトリクスを取得する

カスタムコントローラーを自作したり、OSSで公開されているものを利用したりする際に、カスタムリソースのメトリクスを取得したいケースで利用します。

自分達で exporter を作成して運用していくコストと kube-state-metrics の該当機能を使用して運用していくコストを比較して採用の可否を決定していくことになります。

VerticalPodAutoscaler のメトリクスを取得する

kube-state-metrics のv2.9.0から VerticalPodAutoscaler のメトリクスが出力されなく
なります。そのため該当のメトリクスを使用している既存の利用者は Custom Resource State Metrics を使用する必要があります。

こちらの変更については VerticalPodAutoscaler のv1beta2からv1への移行をどうするかが話し合われた結果、この方針となりました。詳細はこちらの issue に記載されています。

上記の決定になった理由としては、「kube-state-metrics で出力するメトリクスについて Kubernetes のコアリソースのみを対象とする」と方針に従うためです。

今後、「Gateway API」等のリソースに関するメトリクスについては、kube-state-metrics としては Custom Resource State Metrics機能を使用する方向になっていく可能性があることに注意してください。

詳細な説明

利用方法

Custom Resource State Metricsを用いてカスタムリソースのメトリクスを取得するためには、以下の2つの作業が必要になります。

  • 設定ファイルの追加
  • 対象リソースに対する参照権限の追加

1. 設定ファイルの追加

Custom Resource State Metrics の設定ファイルを作成して以下のいずれかの方法で kube-state-metrics に設定します。

  • --custom-resource-state-config を利用して、インラインで設定を記述する
  • --custom-resource-state-config-file でファイルパスを指定する

2. 対象リソースに対する参照権限の追加

kube-state-metrics に対して対象のリソースのlistwatchの権限を付与します。

e.g.

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: kube-state-metrics
rules:
- apiGroups: ["autoscaling.k8s.io"]
  resources:
  - verticalpodautoscalers
  verbs: ["list", "watch"]

Custom Resource State metricsの設定

Custom Resource State metricsの設定に関する内容について記載します。

Custom Resource State metricsに関するフラグの一覧

Name Value Description
--custom-resource-state-config String Custom Resource State metrics の設定ファイルをインラインで記述できる
--custom-resource-state-config-file String Custom Resource State metrics の設定ファイルのパスを指定できる
--custom-resource-state-only Boolean 有効化するとコアリソースのメトリクスを出力せずにカスタムリソースのメトリクスのみを出力するようになる

--custom-resource-state-config--custom-resource-state-config-fileの両方を指定した場合は--custom-resource-state-configの設定が優先されます

--custom-resource-state-configの説明

--custom-resource-state-configを使用するとインラインで設定を記述できます。

e.g.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kube-state-metrics
  namespace: kube-system
spec:
  template:
    spec:
      containers:
      - name: kube-state-metrics
        args:
          - --custom-resource-state-config
          -  |
              spec:
                resources:
                  - groupVersionKind:
                      group: myteam.io
                      version: "v1"
                      kind: Foo
                    metrics:
                      - name: active_count
                        help: "Count of active Foo"
                        each:
                          type: Gauge
                          ...

設定が長くなると管理が難しくなるので、後述する--custom-resource-state-config-fileを使うケースの方が多いと思います。

--custom-resource-state-config-fileの説明

--custom-resource-state-config-fileに設定ファイルのパスを指定することができます。

e.g.

spec:
  containers:
  - name: kube-state-metrics
    image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.8.2
    args:
    - --custom-resource-state-config-file=/ksm-config/custom-resource-state-metrics.yaml
    :

パスに指定しているファイルについては初回起動時だけでなく、定期的の読み込んで設定を反映してくれるので、設定変更時にkube-state-metricsの再起動は不要です。

現時点で使用する場合はインラインで記述する--custom-resource-state-configよりも本機能を使用するのがいいと思います。

こちらのissueの内容が反映されればフラグでの設定ではなく該当の設定用のカスタムリソースを使用するケースが一般的になるかもしれません。

--custom-resource-state-onlyの説明

--custom-resource-state-only=trueを指定するとDeployment等のコアリソースに関するメトリクスを出力せずに、カスタムメトリクスのメトリクス専用にすることができます。

spec:
  containers:
  - name: kube-state-metrics
    image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.8.2
    args:
    - --custom-resource-state-config-file=/ksm-config/custom-resource-state-metrics.yaml
    - --custom-resource-state-only=true
    :

主なユースケースは以下の2つになると思います。

  • 開発時
    Custom Resource State metricsの設定ファイル作成時に、他のメトリクスが出力されないと確認が楽になるのでそういうケースで利用します。

  • 商用運用時
    コアリソースのメトリクスを出力しているkube-state-metricsと分けて管理したいときの利用が考えられます。Custom Resource State metricsの設定ファイルの書き方を間違えるとkube-state-metricsが落ちるので、その影響を避けるため等で分けたいケースがあると思います。

Custom Resource State metricsの設定ファイルの設定イメージ

上述の簡単な利用イメージ に対して、オプショナルで設定できる値を追加した場合のイメージを記載します。

kind: CustomResourceStateMetrics
spec:
  resources:
  - groupVersionKind:     
      group: myteam.io
      kind: "Foo"
      version: "v1"
    resourcePlural: "" 
    metricNamePrefix: "myteam_foos"
    errorLogV: 0
    commonLabels:  
      crd_type: "foo"
    labelsFromPath:
      name: [metadata, name]

    metrics:   
    - name: "ready_count"
      help: "Number Foo ready"
      each:  
        type: Gauge 
        gauge:
          path: [status, sub]
        labelFromKey: type
        labelsFromPath:
          active: [active]
      labelsFromPath:
        "*": [metadata, labels]
      commonLabels:  
        metrics_type: "gauge"
      errorLogV: 9

    - name: "info"
      help: "Foo version"
      each:
        type: Info
        info:
          path: [spec]
          labelsFromPath:
            version: [version]
          labelFromKey: spec
      labelsFromPath:
        "*": [metadata, labels]
      commonLabels:  
        metrics_type: "info"
      errorLogV: 9

    - name: "phase"
      help: "Foo phase"
      each:
        type: StateSet
        stateSet:
          path: [status, phase]
          labelName: phase
          list: [Active, Running, Terminating, Pending]
      labelsFromPath:
        "*": [metadata, labels]
      commonLabels:  
        metrics_type: "info"
      errorLogV: 9

設定内容を大きく分けると以下の3つに分かれます。

  • resources: リソース全体に対する設定
  • resources.metrics: メトリクス毎の設定
  • resources.metrics.each: 選択したメトリクスタイプ毎の固有の設定

Custom Resource State metricsの設定値の説明

Custom Resource State metricsで設定値について記載します。

spec.resources

リソース全体に関する設定

Name Require Description
groupVersionKind 必須 対象となるカスタムリソースの情報の group, version, kind を指定する
resourcePlural 任意 未指定の場合は kind の lower case の複数形が代入される。CRD で設定した plural と異なる場合は指定が必要
metricNamePrefix 任意 メトリクス名の prefix の設定。未指定の場合はkube_customresource_が代入される
commonLabels 任意 ラベルの追加。メトリクスに指定した任意のkey,valueのラベルを追加できる
labelsFromPath 任意 ラベルの追加。メトリクスに指定した任意のkeyとCRの値に応じたvalueのラベルを追加できる
errorLogV 任意 ログレベルを指定できる
metrics 必須 メトリクスに関する設定

ref https://github.com/kubernetes/kube-state-metrics/blob/v2.8.2/pkg/customresourcestate/config.go#L45-L65

  • 設定イメージ
kind: CustomResourceStateMetrics
spec:
  resources:
  - groupVersionKind:     
      group: myteam.io
      kind: "Foo"
      version: "v1"
    resourcePlural: "" 
    metricNamePrefix: "myteam_foos"
    errorLogV: 0
    commonLabels:  
      crd_type: "foo"
    labelsFromPath:
      name: [metadata, name]
groupVersionKindの説明

メトリクスを取得をしたい対象のカスタムリソースの group, version, kind (GVK)を指定します。

- groupVersionKind:      
    group: myteam.io
    kind: "Foo"
    version: "v1"

ちなみ、こちらで既存のDeployment等のリソースを指定した場合には以下のようなエラーとなり取得できません。

E0330 13:33:15.578686       1 reflector.go:513] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: expected gvk apps/v1, Kind=deployments, but watch event object had gvk apps/v1, Kind=Deployment
E0330 13:33:15.582022       1 reflector.go:513] pkg/mod/k8s.io/client-go@v0.26.1/tools/cache/reflector.go:169: expected gvk apps/v1, Kind=deployments, but watch event object had gvk apps/v1, Kind=Deployment

指定できるのはカスタムリソースのみになります。

resourcePluralの説明

対象のリソースのpluralの値を指定します。未指定の場合はkubebuilderでのデフォルトの作成時の挙動に合わせるためにkindのlower caseの複数形が代入されるようになっています。

kind=Fooを設定している場合に以下の指定をするとresourcePlural=foosが設定されます。

- resourcePlural: ""   
metricNamePrefixの説明

出力されるメトリクスをの Prefix を指定できます。未指定の場合は kube_customresource_ がメトリクスの Prefix になります。

- metricNamePrefix: "myteam_foos" 

e.g.

# 未設定  `kube_customresource_`が prefix になる
- kube_customresource_uptime{crd_type="foo",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",name="foo",namespace="kube-system"} 43.21

# "myteam_foos" を設定時
+ myteam_foos_uptime{crd_type="foo",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",name="foo",namespace="kube-system"} 43.21
errorLogVの説明

ログレベルを指定できます。未指定の場合は0になります。

- errorLogV: 0   

実際に触ってみた感じだと、kind: Custom Resource State Metricsを記述する際にどこで設定を間違えてる確認する時に一時的にログレベルを上げるのが主な使い道になるかなと思います。

commonLabelsの説明

出力するメトリクスに任意のラベルを追加する機能になります。

- commonLabels:    
    crd_type: "foo"

上記の例だと、crd_typeがkeyでfooがvalueに入る形でラベルが追加されます。

# 未設定
- kube_customresource_uptime{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21

# 設定時 e.g. crd_type="foo" が追加される
+ kube_customresource_uptime{crd_type="foo",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21
labelsFromPathの説明

対象のリソースの状態に合わせてメトリクスにラベルを追加する機能になります。
ラベルに付与するkey名の指定方法が2パターンあります。

  • key名に任意の値を指定する
  • *を使用して条件に合致する全てをラベルに追加する

e.g. key名に任意の値を指定する

- labelsFromPath:    
    name: [metadata, name]

上記の場合だと name が key になり、[ metadata, name ]を指定するとカスタムリソースのmetadata.nameの値がメトリクスのラベルに追加されます。

e.g.

# 未設定
- myteam_foos_uptime{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21

# 設定時 e.g. name="foo" が追加される
+ myteam_foos_uptime{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",name="foo"} 43.21

e.g. *を使用して条件に合致する全てをラベルに追加する

- labelsFromPath:    
    "*": [metadata, labels]  
# 未設定
- myteam_foos_uptime{crd_type="foo",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21

# 設定時 e.g. `metadata.labels` に該当する全てがメトリクスに追加される bar="baz" foo="bar"
+ myteam_foos_uptime{bar="baz",crd_type="foo",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",foo="bar"} 43.21

labels や annotations などの情報の全てをラベルとしてメトリクスに追加したいケースで使用します。ただ、メトリクスのラベルが大量に増えると Prometheus等の性能の問題を引き起こす恐れがあるのでkey名を指定したものを使用した方が良いです。もし、*を使う場合は Infoのメトリクスだけに使用して、他のメトリクスで使用したいときはInfoのメトリクスとjoinする使い方をした方が良いです。

commonLabelskey/valueを指定してラベルを追加するのに対して、labelsFromPathはカスタムリソースの内容に応じてラベルを追加する機能になります。

spec.resources.metrics

各メトリクス単位の設定

Name Require Description
name 必須 メトリクスの名前を指定する。メトリクス名は metricNamePrefix + name となる
help 任意 HELPに表示するメッセージに任意の文字列を追加できる
commonLabels 任意 resourcescommonLabels と設定方法は同じ。こちらは設定の範囲がメトリクス単位となる
labelsFromPath 任意 resourceslabelsFromPath と設定方法は同じ。こちらは設定の範囲がメトリクス単位となる
errorLogV 任意 resourceserrorLogV と設定方法は同じ。こちらは設定の範囲がメトリクス単位となる
each 必須 メトリクスの type の選択し、固有の設定を指定する

ref https://github.com/kubernetes/kube-state-metrics/blob/v2.8.2/pkg/customresourcestate/config.go#L123-L136

  • 設定イメージ
metrics:    
- name: "uptime"   
  help: "Foo uptime"  
  each:  
    type: Gauge  
    gauge:
      path: [status, uptime]
  commonLabels:
    custom_metric: "yes"
  labelsFromPath:    
    name: [metadata, name]
  errorLogV: 0   
nameの説明

出力するメトリクスの名前になります。 resources.metricNamePrefix で設定した値とnameで指定した値によって出力するメトリクス名前が決まります。

- name: "uptime"    

resources.metricNamePrefixが未指定の場合はkube_customresource_が代入されるので出力されるメトリクスは以下のようになります。

kube_customresource_uptime{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21
helpの説明

メトリクスの HELP に表示するメッセージを指定できます。

- help: "Foo uptime" 

e.g.

# 未設定
- # HELP myteam_foos_uptime

# 設定時
+ # HELP myteam_foos_uptime Foo uptime

設定すると # HELP <メトリクス名> の後に設定した文字列が表示されるようになります。

commonLabelsの説明

resourcescommonLabelsと設定方法は同じ。
こちらは設定の範囲がメトリクス単位となる

labelsFromPathの説明

resourceslabelsFromPathと設定方法は同じ。
こちらは設定の範囲がメトリクス単位となる

errorLogVの説明

resourceserrorLogVと設定方法は同じ。
こちらは設定の範囲がメトリクス単位となる

eachの説明

メトリクスのtypeの選択し、固有の設定を指定する.
詳細は後述するtype毎の説明に記載。

spec.resources.metrics.each

メトリクスのTypeに関する設定

Name Require Description
type 必須 Gauge,Info,StateSet から1つのメトリクス typeを指定する
gauge 条件付き必須 Gaugeを選択した場合に固有の設定を指定する
info 条件付き必須 Infoを選択した場合に固有の設定を指定する
stateSet 条件付き必須 StateSetを選択した場合に固有の設定を指定する

ref https://github.com/kubernetes/kube-state-metrics/blob/v2.8.2/pkg/customresourcestate/config.go#L138-L154

OpenMetrics specificationでは以下のメトリクスの Type が規定されています。

  • unknown
  • gauge
  • counter
  • info
  • stateset
  • histogram
  • gaugehistogram
  • summary

v2.8.2 の時点では上記の内の以下の 3 つに関する設定が可能です。

  • gauge
  • info
  • stateset

使い方の詳細は後述するtype毎の説明に記載。

spec.resources.metrics.each.gauge

Name Require Description
path 必須 メトリクスの value になる値を指定する
labelsFromPath 任意 ラベルの追加。metricslabelsFromPathと設定方法は同じ。こちらはpathで指定した場所からの相対パスでの指定になる
valueFrom 任意 出力するメトリクスの条件の指定。path配下で数値を持つフィールドを指定することで出力するメトリクスを絞り込む
labelFromKey 任意 ラベルの追加。path配下のオブジェクトを指定した値をkey名としてラベルに追加する
nilIsZero 任意 指定した条件がnillの場合に、valueが0のメトリクスが出力される

ref https://github.com/kubernetes/kube-state-metrics/blob/v2.8.2/pkg/customresourcestate/config_metrics_types.go#L37-L48

  • 設定イメージ
- name: "ready_count"
  each:  
    type: Gauge 
    gauge:
      path: [status, uptime] 
      nilIsZero: true

- name: "ready_count"
  each:
    type: Gauge
    gauge:
      path: [status, sub]
      valueFrom: [ready]   
      labelsFromPath:
        active: [active] 
      labelFromKey: type
  labelsFromPath:
    name: [metadata, name]
pathの説明

メトリクスに出力する対象のCRのパスを設定します。
例えばCRの一部が以下のようなっていたとします。

status:
  uptime: 43.21

この時にpath: [status, uptime]を指定します。

each:  
type: Gauge 
gauge:
  path: [status, uptime] 

この時にstatus.uptimeに数値が存在するので、該当の値がメトリクスのvalueとして選択されて出力されます。

kube_customresource_uptime{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 43.21

これがGaugeの基本的な使い方になります。

path の指定方法については、配列の場合や、特定のkey/valueを指定したい場合などに合わせて以下のような指定も可能です。

# simple path lookup
[spec, replicas]                         # spec.replicas == 1

# indexing an array
[spec, order, "0", value]                # spec.order[0].value = true

# finding an element in a list by key=value  
[status, conditions, "[name=a]", value]  # status.conditions[0].value = 45

# if the value to be matched is a number or boolean, the value is compared as a number or boolean  
[status, conditions, "[value=66]", name]  # status.conditions[1].name = "b"

また、後述するspec.resources.metrics.each.gauge配下の設定についてはpathで指定した位置を起点に設定が反映されることにも注意してください。こちらの注意点については後述します。

valueFromの説明

出力するメトリクスの条件の指定になります。
path配下で数値を持つフィールドを指定することで出力するメトリクスを絞り込むことができます。

以下のようなCRがあるとします。

metadata:
  name: foo
status:
  sub:
    type-a:
      active: 1
      ready: 2     # メトリクスの value に出力される箇所
    type-b:
      active: 3
      ready: 4    # メトリクスの value に出力される箇所

valueFromを以下のように指定します。

- name: "ready_count"
  each:
    type: Gauge
    gauge:
      path: [status, sub]
      valueFrom: [ready]

上記の場合だとpathで指定したstatus.subの配下のreadyに合致するものがメトリクスとして出力される。
出力されるメトリクスは以下になります。

# `status.sub.type-a.ready=2` と `status.sub.type-b.ready=4`がメトリクスになる
kube_customresource_ready_count{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 2
kube_customresource_ready_count{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1"} 4

これだと、途中のpathがtype-a,type-bに依存せずに指定できるのが利点です。ただ、このままだと分かりにくいメトリクスを区別できないため、実際に利用する際には識別できるようにラベルも合わせて追加するのが良いと思います。

labelsFromPathの説明

metricslabelsFromPathと設定方法は同じ。
こちらはpathで指定した場所からの相対パスでの指定になる点が異なります。

以下のようなCRがあるとします。

metadata:
  name: foo  # メトリクスのラベルに追加される箇所
status:
  sub:
    type-a:
      active: 1  # メトリクスのラベルに追加される箇所
      ready: 2  
    type-b:
      active: 3  # メトリクスのラベルに追加される箇所
      ready: 4  

labelsFromPathを以下のように指定します。

- name: "ready_count"
  each:
    type: Gauge
    gauge:
      path: [status, sub]
      valueFrom: [ready]   
      labelsFromPath:
        active: [active]   # pathで指定した`status.sub` の位置からのpath指定になります
  labelsFromPath:
    name: [metadata, name]   # `.` の位置からのpath指定になります

出力されるメトリクスは以下になります。

# `status.sub.type-a.ready=2` と `status.sub.type-b.ready=4`がメトリクスになる
kube_customresource_ready_count{active="1",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",name="foo"} 2
kube_customresource_ready_count{active="3",customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",name="foo"} 4

name: [ metadata, name ].からの位置なので、metadata.namename="foo"のラベルが追加されます。

active: [active]はpathで指定したstatus.subからの位置なので、status.sub.type-a.active=1等のラベルが追加されます。

labelFromKeyの説明

ラベルの追加する機能です。
path配下のオブジェクトを指定した値をkey名としてラベルに追加します。

以下のようなCRがあるとします。

metadata:
  name: foo
status:
  sub:
    type-a: # メトリクスのラベルに追加される箇所
      active: 1
      ready: 2  
    type-b: # メトリクスのラベルに追加される箇所
      active: 3  
      ready: 4  

labelFromKeyを以下のように指定します。

- name: "ready_count"
  each:
    type: Gauge
    gauge:
      path: [status, sub]
      valueFrom: [ready]   
      labelFromKey: type  

pathで指定した配下に対して、labelFromKey指定した値をkey名としてラベルに追加します。
出力されるメトリクスは以下になります。

# labelFromKey の設定で追加されているラベルは `type="type-a"`と`type="type-b"`になります
kube_customresource_ready_count{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",type="type-a"} 2
kube_customresource_ready_count{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",type="type-b"} 4

pathで指定したstatus.subに対して、自分で指定した任意の値をkey名としてラベルに追加することができます。

nilIsZeroの説明

指定した条件に一致する値がnillの場合は、メトリクスが出力されませんが、valueが0のメトリクスで出力する機能になります。

指定する場合は以下のようにbooleanで指定します。

each:  
type: Gauge 
gauge:
  path: [status, uptime] 
  nilIsZero: true

spec.resources.metrics.each.info

Name Require Description
path 任意 labelsFromPathlabelFromKey の起点となる path を指定する。未指定時は . となる
labelsFromPath 条件付き必須 出力するメトリクスの条件の指定。gaugelabelsFromPath と設定方法は同じ。
条件に合致するものがある場合は value が 1 のメトリクスが出力される
labelFromKey 条件付き必須 出力するメトリクスの条件の指定。gaugelabelFromKey と設定方法は同じ。
条件に合致するものがある場合は value が 1 のメトリクスが出力される

ref https://github.com/kubernetes/kube-state-metrics/blob/v2.8.2/pkg/customresourcestate/config_metrics_types.go#L50-L56

  • 設定イメージ
- name: "info"
  help: "Foo version"
  each:
    type: Info
    info:
      labelsFromPath:
        version: [spec, version]

- name: "type_info"
  help: "Foo type"
  each:
    type: Info
    info:
      path: [status, active]
      labelFromKey: type
labelsFromPathの説明

gaugelabelsFromPathと設定方法は同じ。
条件に合致するものがある場合は value が1のメトリクスが出力されるようになる点が異なります。

以下のようなCRがあるとします。

spec:
  version: v1.2.3

labelsFromPathを以下のように指定します。

- name: "info"
  help: "Foo version"
  each:
    type: Info
    info:
      labelsFromPath:
        version: [spec, version]

CRの方にsepc.version="v1.2.3"が存在しており、labelsFromPathで指定した条件に合致しているので、以下のメトリクスが出力されます。

kube_customresource_info2{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",version="v1.2.3"} 1

ポイントは以下の2つです

  • valueが1であること
  • labelsFromPathで指定したラベルが追加されていること e.g. version="v1.2.3"

これがInfoの基本的な使い方になります。

pathの説明

gaugelabelsFromPathと設定方法は同じ。
gaugeの時はpathを使ってvalueを指定していましたが、こちらの場合は他の設定の起点の位置を変えるための補助的な役割になります。

以下のようなCRがあるとします。

spec:
  version: v1.2.3

labelsFromPathを以下のように指定します。

- name: "info"
  help: "Foo version"
  each:
    type: Info
    info:
      path: [spec]
      labelsFromPath:
        version: [version]

出力されるメトリクスはlabelsFromPathの例と同じになります。

kube_customresource_info2{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",version="v1.2.3"} 1
labelFromKeyの説明

以下のようなCRがあるとします。

status:
  active:
    type-a: 1
    type-b: 3

labelFromKeyを以下のように指定します。

- name: "type_info"
  help: "Foo type"
  each:
    type: Info
    info:
      path: [status, active]
      labelFromKey: type

出力されるメトリクスは以下になります。

kube_customresource_type_info{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",type="type-a"} 1
kube_customresource_type_info{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",type="type-b"} 1

pathで指定したstatus.activeの配下をkey名をlabelFromKeyで指定したtypeにしてラベルに追加します。Infoなのでその時のメトリクスのvalueは必ず1が入ります。

labelsFromPathlabelFromKeyで指定した条件に一致するものがある場合にvalueが1のメトリクスを出力するのがInfoの挙動になります。

spec.resources.metrics.each.stateSet

Name Require Description
path 任意 list でカウントする対象となる値の path を指定する
labelsFromPath 任意 ラベルの追加。gaugelabelsFromPath と設定方法は同じ
list 必須 出力するメトリクスの条件の指定。集計する対象となる値の一覧を指定する。pathで指定した場所からの相対パスでの指定になる
labelName 必須 ラベルの追加。listで指定した値をラベルに追加する際のkey名を指定する
valueFrom 任意 出力するメトリクスの条件の指定。gaugevalueFrom と設定方法は同じ

ref https://github.com/kubernetes/kube-state-metrics/blob/v2.8.2/pkg/customresourcestate/config_metrics_types.go#L58-L69

  • 設定イメージ
- name: "phase"
  each:
    type: StateSet
    stateSet:
      path: [status, phase]
      labelName: phase
      list: [Active, Running, Terminating, Pending]
      labelsFromPath:
        name: [name]
pathの説明

gaugeinfopathと設定方法は同じ。
infoの時と同じように他の設定の起点の位置を変えるための補助的な役割になります。

listlabelNameの説明

listとlabelNameは同時に使用します。

listで指定した値をカウントしたものがメトリクスのvalueになります。
出力されるメトリクスにはlabelNameで指定した値をkey名にlistで指定した値をvalueにしたラベルが追加されます。

以下のようなCRがあるとします。

status:
  phase: Pending

listとlabelNameを以下のように指定します。

- name: "phase"
  each:
    type: StateSet
    stateSet:
      path: [status, phase]
      labelName: phase
      list: [Active, Running, Terminating, Pending]

以下のメトリクスが追加されます。

kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Active"} 0
kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Pending"} 1
kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Running"} 0
kube_customresource_phase{customresource_group="myteam.io",customresource_kind="Foo",customresource_version="v1",phase="Terminating"} 0

pathで指定したstatus.phase配下でlistで指定した値に一致するものをカウントして

これがStateSetの基本的な使い方になります。

labelsFromPathの説明

gaugeinfolabelsFromPathと設定方法は同じ。
ラベルを指定する時に使います。

valueFromの説明

gaugevalueFromと設定方法は同じ。
出力するメトリクスの条件の指定するために使います。

参考

検証用に用意したCRDとCRを記載します。

  • CRD
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: foos.myteam.io
spec:
  group: myteam.io
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                version:
                  type: string
                order:
                  items:
                    properties:
                      id: 
                        type: integer
                      value: 
                        type: boolean
                    type: object
                  type: array
                replicas:
                  type: integer
            status:
              type: object
              properties:
                phase:
                  type: string
                active:
                  properties:
                    type-a:
                      type: integer
                    type-b:
                      type: integer
                  type: object
                conditions:
                  items:
                    properties:
                      name: 
                        type: string
                      value: 
                        type: integer
                    type: object
                  type: array
                sub:
                  properties:
                    type-a:
                      properties:
                        active:
                          type: integer
                        ready:
                          type: integer
                      type: object
                    type-b:
                      properties:
                        active:
                          type: integer
                        ready:
                          type: integer
                      type: object
                  type: object
                uptime:
                  type: number
  scope: Namespaced
  names:
    plural: foos
    singular: foo
    kind: Foo
    shortNames:
    - fo
  • CR
kind: Foo
apiVersion: myteam.io/v1
metadata:
  annotations:
    qux: quxx
    quxx: quux
  labels:
    foo: bar
    bar: baz
  name: foo
spec:
  version: v1.2.3
  order:
  - id: 1
    value: true
  - id: 3
    value: false
  replicas: 1
status:
  phase: Pending
  active:
    type-a: 1
    type-b: 3
  conditions:
  - name: a
    value: 45
  - name: b
    value: 66
  sub:
    type-a:
      active: 1
      ready: 2
    type-b:
      active: 3
      ready: 4
  uptime: 43.21

所感

Custom Resource State metricsがリリースされた当初は自分でGo言語で記述してbuildしないといけなかったので、これはフォークして開発するのと何が違うんだろうか?みたいな機能でしたが、設定ファイル書くだけで使えるようになったのでだいぶ良くなったのかなと思います。

ただ、公式のドキュメントの方が今はあまりいけていない感じになっています。間違いとドキュメントに記載されていない内容が結構あったので自分で一から検証して今回まとめてみました。

今後もそれなりに変更がある機能なので、Changelog確認しながらkube-state-metricsをアップデートしていく運用ができないと商用利用は少し厳しいと思いますが、--custom-resource-state-only=trueを有効化してカスタムリソース専用のkube-state-metricsにしておけば影響範囲を抑えられるので、それぐらいなら許容できるケースも結構あるのかなと思います。

自分たちでExporterを開発・運用していくコストと比較して、kube-state-metricsの変更点をキャッチアップしながらCustom Resource State metricsを利用するコストは比較できるラインに来たかなと思うで、今後の利用は進むと思います。

19
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
13