Kubernetes 1.24: Metrics Changes と SIG Instrumentation の変更内容

- [Kubernetes 1.22 SIG Instrumentation の変更内容](https://qiita.com/watawuwu/items/c177d1bc8a4b9a1d3a91)
- [Kubernetes 1.23 SIG Instrumentation の変更内容](https://qiita.com/watawuwu/items/0a0496f415b818edcb4d)

## はじめに

ここでは、Kubernetes 1.24 の [CHANGELOG](https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.24.md) から Metrics の変更と SIG Instrumentation の取り組みについてまとめています。

今回 Kubernetes v1.24 で SIG Instrumentation が扱う主要なテーマと注目したいテーマについて紹介します。では確認していきます。

## Contextual Logging

原文では次のように紹介されています。

> Kubernetes 1.24 has introduced contextual logging that enables the caller of a function to control all aspects of logging (output formatting, verbosity, additional values, and names).  
> Kubernetes 1.24 では関数の呼び出し元でロギングの設定（出力フォーマット、Verbosity、追加値、名前）を制御できる Contextual Logging が導入されました。

このテーマの KEP はこちらになります。

- [KEP-3077: contextual logging](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/3077-contextual-logging)
  - Feature Gate: ContextualLogging
  - Stage: alpha

この KEP では現在利用しているグローバルロガーを置き換え、呼び出し元でコンテキスト情報を含んだインスタンスを生成し、呼び出し先でそのロガーインスタンスを利用する計画となっています。
この機能により klog ログ実装への強い依存を排除したり、トレース情報やコンポーネント名などのメタ情報を一元化できるなどのメリットがあります。個人的にはロガーを Dependency Injection(DI) できる点が嬉しい気がします。呼び出し先はロガーのインタフェースのみの依存となるため、テスト時のみログ出力の実装を変えるなどの対応が簡単になります。もちろん DI でも話題になりやすいコンテキストやロガーインスタンスの引き回しが発生するため、コードリーディングの観点から好みが分かれやすいトピックでもあるかなと思います。

v1.24 では開発者向けに Contextual Logging の関数が用意され利用できるようになっています。[利用方法についてはこちらにサンプル](https://github.com/kubernetes/kubernetes/tree/v1.24.0/staging/src/k8s.io/component-base/logs/example)があります。

```logger.go
func NewLoggerCommand() *cobra.Command {
...
			// Initialize contextual logging.
			logger := klog.Background().WithName("example").WithValues("foo", "bar")
			ctx := klog.NewContext(context.Background(), logger)

			runLogger(ctx)
...
}

func runLogger(ctx context.Context) {
...
	logger := klog.FromContext(ctx)
	logger.Info("another runtime", "duration", time.Hour, "duration", time.Minute)
...
}
```

上記のコードを Feature Gate 有り無しで実行すると次のような結果となります。

```shell
 ❯❯ $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/component-base/logs/example/cmd/

# feature-gates なし
 ❯❯ go run .
...
I0512 16:05:26.791599   29789 logger.go:95] "another runtime" duration="1m0s"

# feature-gates あり
 ❯❯ go run . --feature-gates ContextualLogging=true
...
I0512 16:07:17.208820   30008 logger.go:95] "example: another runtime" foo="bar" duration="1m0s"
```

呼び出し元で設定された名前やキーペアがログに出力されていることが確認できました :tada:。

Kubernetes のコンポーネントはまだ Contextual Logging に移行していないようで、計画では一部の kube-schduler フレームワークやプラグインから徐々に移行する予定のようです。

構造化ロギングと合わせて、[公式から Contextual Logging のブログが出る予定](https://github.com/kubernetes/website/blob/a1c2aa1b06264c3c0063e59a7440a24fb7dcff8c/content/en/blog/_posts/2022-TBD-contextual-logging/index.md)です。公開されたら是非確認してみてください。また、こちらの[移行ガイド](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/migration-to-structured-logging.md)には構造化ロギングに加え、Contextual Logging も追加されています。

その他にも KEP の追加やステージ変更があります。

- Add: [KEP-2831: Kubelet Tracing](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/2831-kubelet-tracing)
  - Feature Gate: KubeletTracing
  - Stage: alpha
  - APIServer Tracing に加え、kubelet にも Tracing が入るようです。
- Update: [KEP-2845: Deprecate klog specific flags in Kubernetes Compnents](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/2845-deprecate-klog-specific-flags-in-k8s-components)
  - [Kubernetes 1.23 SIG Instrumentation の変更内容](https://qiita.com/watawuwu/items/0a0496f415b818edcb4d)
  - 今のところ 1.26 で GA となり、そのタイミングでフラグが削除される予定です。
  - Stage: beta
- Update: [KEP-647: APIServer Tracing](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/647-apiserver-tracing)
  - FEATURE GATES: APIServerTracing
  - Stage: beta
- Update: [KEP-1753: Kubernetes system components logs sanitization](https://github.com/kubernetes/enhancements/tree/master/keps/sig-instrumentation/1753-logs-sanitization)
  - Stage: 非推奨となり機能が削除されました。
  - 今後は [KEP-1933: Defend Against Logging Secrets via Static Analysis](https://github.com/kubernetes/enhancements/tree/master/keps/sig-security/1933-secret-logging-static-analysis)の静的解析のアプローチを試みます。


それでは `Metrics Changes` について説明していきます。
`メトリクスの変更` は、私が全ての変更点からメトリクスの変更に関連するものを抜粋した内容となります。

## メトリクスの変更（Metrics Changes）

### 追加

#### kube-apiserver

<!-- - Apiextensions_openapi_v3_regeneration_count metric (alpha) will be emitted for OpenAPI V3. ([#109128](https://github.com/kubernetes/kubernetes/pull/109128), [@&#xFFF0;Jefftree](https://github.com/Jefftree)) [sig/api-machinery,sig/instrumentation] -->
- OpenAPI V3 で利用されるメトリクスが追加されました([#109128](https://github.com/kubernetes/kubernetes/pull/109128), [@&#xFFF0;Jefftree](https://github.com/Jefftree))
  - Counter: `apiextensions_openapi_v3_regeneration_count`
    - Help: Counter of OpenAPI v3 spec regeneration count broken down by group, version, causing CRD and reason.
    - Labels: {"group", "version", "crd", "reason"}

<!-- - A new Priority and Fairness metric 'apiserver_flowcontrol_work_estimate_seats_samples' has been added that tracks the estimated seats associated with a request. ([#106628](https://github.com/kubernetes/kubernetes/pull/106628), [@&#xFFF0;tkashem](https://github.com/tkashem)) [sig/api-machinery,sig/instrumentation] -->
- API リクエストに関連する Estimated Seats の数を記録するための API Priority and Fairness のメトリクスが追加されました([#106628](https://github.com/kubernetes/kubernetes/pull/106628), [@&#xFFF0;tkashem](https://github.com/tkashem))
  - Histogram: `apiserver_flowcontrol_work_estimate_seats_samples`
    - Help: Number of estimated seats (maximum of initial and final seats) associated with requests in API Priority and Fairness

<!-- - Added a new Priority and Fairness metric `apiserver_flowcontrol_request_dispatch_no_accommodation_total` to track the number of times a request dispatch attempt results in a no-accommodation status due to lack of available seats. ([#106629](https://github.com/kubernetes/kubernetes/pull/106629), [@&#xFFF0;tkashem](https://github.com/tkashem)) [sig/api-machinery,sig/instrumentation] -->
- API リクエストのディスパッチを試みた結果、利用可能な空きがないために no-accommodation な状態となった回数を記録する API Priority and Fairness のメトリクスが追加されました([#106629](https://github.com/kubernetes/kubernetes/pull/106629), [@&#xFFF0;tkashem](https://github.com/tkashem))。
  - Counter: `apiserver_flowcontrol_request_dispatch_no_accommodation_total`
    - Help: Number of times a dispatch attempt resulted in a non accommodation due to lack of available seats
    - Labels: {"priority_level", "flow_schema"}

<!-- - New "field_validation_request_duration_seconds" metric, measures how long requests take, indicating the value of the fieldValidation query parameter and whether or not server-side field validation is enabled on the apiserver ([#109120](https://github.com/kubernetes/kubernetes/pull/109120), [@&#xFFF0;kevindelgado](https://github.com/kevindelgado)) [sig/api-machinery,sig/instrumentation] -->
- fieldValidation クエリーパラメータ値とサーバーサイド検証の有効無効をラベル値に持つ、バリデーションの時間を計測するメトリクスが追加されました([#109120](https://github.com/kubernetes/kubernetes/pull/109120), [@&#xFFF0;kevindelgado](https://github.com/kevindelgado))
  - Histogram: `field_validation_request_duration_seconds`
    - Help: Response latency distribution in seconds for each field validation value and whether field validation is enabled or not
    - Labels: {"field_validation", "enabled"}

<!-- - Added a new metric `webhook_fail_open_count` to monitor webhooks that fail to open. ([#107171](https://github.com/kubernetes/kubernetes/pull/107171), [@&#xFFF0;ltagliamonte-dd](https://github.com/ltagliamonte-dd)) [sig/api-machinery,sig/instrumentation] -->
- Admission webhooks の呼び出しに失敗した数を記録します([#107171](https://github.com/kubernetes/kubernetes/pull/107171), [@&#xFFF0;ltagliamonte-dd](https://github.com/ltagliamonte-dd))
  - Counter: `apiserver_admission_webhook_fail_open_count`
    - Help: Admission webhook fail open count, identified by name and broken out for each admission type (validating or mutating).
    - Labels: {"name", "type"}

#### kubelet

<!-- - Add the metric `container_oom_events_total` to kubelet's cAdvisor metric endpoint. ([#108004](https://github.com/kubernetes/kubernetes/pull/108004), [@&#xFFF0;jonkerj](https://github.com/jonkerj)) [sig/node] -->
- コンテナの Out Of Memory(OOM) を記録するメトリクスが追加されました([#108004](https://github.com/kubernetes/kubernetes/pull/108004), [@&#xFFF0;jonkerj](https://github.com/jonkerj))
  - Counter: `container_oom_events_total`
    - Help: Count of out of memory events observed for the container
    - Labels: {"container", "id", "image", "name", "namespace", "pod"}
  - cAdvisor(since 0.40.0) には入っていましたが、1.24 で kubelet から利用できるように対応しています。


<!-- - Added a metric for measuring end-to-end volume mount timing. ([#107006](https://github.com/kubernetes/kubernetes/pull/107006), [@&#xFFF0;gnufied](https://github.com/gnufied)) [sig/storage,sig/node] -->
- エンドツーエンドのボリュームマウントのタイミングを記録する、operation_name ラベル値に `overall_volume_mount` を持つメトリクスを追加しました([#107006](https://github.com/kubernetes/kubernetes/pull/107006), [@&#xFFF0;gnufied](https://github.com/gnufied))。
  - Histogram: `volume_operation_total_seconds`
    - Labels: {"plugin_name", "operation_name"}
<!-- - Kubelet: add `kubelet_volume_metric_collection_duration_seconds` metrics for volume disk usage calculation duration ([#107201](https://github.com/kubernetes/kubernetes/pull/107201), [@&#xFFF0;pacoxu](https://github.com/pacoxu)) [sig/storage,sig/node,sig/instrumentation] -->
- ボリュームディスク統計の計算を行う時間を記録するメトリクスが追加されました([#107201](https://github.com/kubernetes/kubernetes/pull/107201), [@&#xFFF0;pacoxu](https://github.com/pacoxu))
  - Histogram: `kubelet_volume_metric_collection_duration_seconds`
    - Help: Duration in seconds to calculate volume stats
    - Labels: {"metric_source"}

<!-- - Add one metrics(`kubelet_volume_stats_health_abnormal`) of volume health state to kubelet ([#108758](https://github.com/kubernetes/kubernetes/pull/108758), [@&#xFFF0;fengzixu](https://github.com/fengzixu)) [sig/storage,sig/node,sig/instrumentation,sig/testing] -->
- ボリュームのヘルス状態を記録するメトリクスが追加されました([#108758](https://github.com/kubernetes/kubernetes/pull/108758), [@&#xFFF0;fengzixu](https://github.com/fengzixu))
  - Gauge: `kubelet_volume_stats_health_abnormal`
    - Help: Abnormal volume health status. The count is either 1 or 0. 1 indicates the volume is unhealthy, 0 indicates volume is healthy
    - Labels: {"namespace", "persistentvolumeclaim"}

#### kube-proxy

<!-- - Introduction of a new "sync_proxy_rules_no_local_endpoints_total" proxy metric. This metric represents the number of services with no internal endpoints. The "traffic_policy" label will contain both "internal" or "external". ([#108930](https://github.com/kubernetes/kubernetes/pull/108930), [@&#xFFF0;MaxRenaud](https://github.com/MaxRenaud)) [sig/network,sig/scheduling,sig/storage,sig/node,sig/api-machinery,sig/autoscaling,sig/auth,sig/apps,sig/windows,sig/cli,sig/instrumentation,sig/testing,sig/release,sig/architecture] -->
- インターナルエンドポイントを持たないサービス数を記録するメトリクスが追加されました。traffic_policy ラベル値には `internal` または `external` が記録されます([#108930](https://github.com/kubernetes/kubernetes/pull/108930), [@&#xFFF0;MaxRenaud](https://github.com/MaxRenaud))
  - Gauge: `sync_proxy_rules_no_local_endpoints_total`
    - Help: Number of services with a Local traffic policy and no endpoints
    - Labels: {"traffic_policy"}

#### その他

<!-- - Client-go: add new histogram metric to record the size of the requests and responses. ([#108296](https://github.com/kubernetes/kubernetes/pull/108296), [@&#xFFF0;aojea](https://github.com/aojea)) [sig/api-machinery,sig/instrumentation,sig/architecture] -->
- client-go にリクエストとレスポンスのボディサイズを記録するメトリクスが追加されました([#108296](https://github.com/kubernetes/kubernetes/pull/108296), [@&#xFFF0;aojea](https://github.com/aojea))
  - Histogram: `rest_client_request_size_bytes`
    - Help: Request size in bytes. Broken down by verb and host.
    - Labels: {"verb", "host"}
  - Histogram: `rest_client_response_size_bytes`
    - Help: Response size in bytes. Broken down by verb and host.
    - Labels: {"verb", "host"}

### 変更

#### kube-apiserver

<!-- - Added a new label `type` to `apiserver_flowcontrol_request_execution_seconds` metric - it has the following values: - 'regular': indicates that it is a non long running request - 'watch': indicates that it is a watch request. ([#105517](https://github.com/kubernetes/kubernetes/pull/105517), [@&#xFFF0;tkashem](https://github.com/tkashem)) [sig/api-machinery,sig/instrumentation] -->
- 次のメトリクスに `type` ラベルが追加されました。`type` ラベル値には、ロングランでないリクエストの `regular` とウォッチリクエストの `watch` が記録されます([#105517](https://github.com/kubernetes/kubernetes/pull/105517), [@&#xFFF0;tkashem](https://github.com/tkashem))
  - Histogram: `apiserver_flowcontrol_request_execution_seconds`
    - Labels: {"priority_level", "flow_schema", "type"}

#### kube-controller-manager

<!-- - Renamed metrics `evictions_number` to `evictions_total` and mark it as stable. The original `evictions_number` metrics name is marked as "Deprecated" and has been removed in kubernetes 1.23 . ([#106366](https://github.com/kubernetes/kubernetes/pull/106366), [@&#xFFF0;cyclinder](https://github.com/cyclinder)) [sig/network,sig/scalability,sig/scheduling,sig/storage,sig/node,sig/api-machinery,sig/cluster-lifecycle,sig/auth,sig/apps,sig/windows,sig/cli,sig/instrumentation,sig/testing,sig/release,sig/architecture] -->
- 次のメトリクスがリネームされ StabilityLevel が Stable になりました。元のメトリクスは引き続き利用できますが、非推奨となりました([#106366](https://github.com/kubernetes/kubernetes/pull/106366), [@&#xFFF0;cyclinder](https://github.com/cyclinder))
  - Counter: `node_collector_evictions_number` => `node_collector_evictions_total`

#### その他

- client-go: 次のメトリクスのバケットが変更となりました([#106911](https://github.com/kubernetes/kubernetes/pull/106911), [@&#xFFF0;aojea](https://github.com/aojea))
  - `rest_client_request_duration_seconds` 、`rest_client_rate_limiter_duration_seconds`
    - [0.001, 0.002, 0.004, 0.008, 0.016, 0.032, 0.064, 0.128, 0.256, 0.512] => [0.005, 0.025, 0.1, 0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 15.0, 30.0, 60.0]


### 非推奨
#### kube-apiserver

- 次のメトリクスが非推奨となりました([#109018](https://github.com/kubernetes/kubernetes/pull/109018), [@&#xFFF0;wojtek-t](https://github.com/wojtek-t))
  - `apiserver_dropped_requests_total`
  - 代わりに `apiserver_request_terminations_total` メトリクスを利用してください。

### 削除
- 削除されたメトリクスは見当たりませんでした。

### 修正
#### kube-apiserver

<!-- - Record requests rejected with 429 in the apiserver_request_total metric ([#108927](https://github.com/kubernetes/kubernetes/pull/108927), [@&#xFFF0;wojtek-t](https://github.com/wojtek-t)) -->
- HTTP ステータスコード 429 でリジェクトされたリクエストも記録されるように修正されました([#108927](https://github.com/kubernetes/kubernetes/pull/108927), [@&#xFFF0;wojtek-t](https://github.com/wojtek-t))
  - Counter: `apiserver_request_total`

#### その他

<!-- - Replace the url label of `rest_client_request_duration_seconds` and `rest_client_rate_limiter_duration_seconds` metrics with a host label to prevent cardinality explosions and keep only the useful information. This is a breaking change required for security reasons. ([#106539](https://github.com/kubernetes/kubernetes/pull/106539), [@&#xFFF0;dgrisonnet](https://github.com/dgrisonnet)) -->
- メトリクスの増大を防ぐため、url ラベルを host ラベルに置き換えました。これは、セキュリティ上の理由から必要な変更です([#106539](https://github.com/kubernetes/kubernetes/pull/106539), [@&#xFFF0;dgrisonnet](https://github.com/dgrisonnet))
  - `rest_client_request_duration_seconds`
  - `rest_client_rate_limiter_duration_seconds`

## アップグレード前の注意事項 (Urgent Upgrade Notes)

<!-- - The experimental dynamic log sanitization feature has been deprecated and removed in the 1.24 release. The feature is no longer available for use. ([#107207](https://github.com/kubernetes/kubernetes/pull/107207), [@&#xFFF0;ehashman](https://github.com/ehashman)) [sig/scheduling,sig/instrumentation,sig/security] -->
- [Kubernetes 1.20: Metrics Changes と SIG Instrumentation の変更内容](https://qiita.com/watawuwu/items/ab5a0f11210d15cc6a86)で紹介した logs-sanitization が削除されました([#107207](https://github.com/kubernetes/kubernetes/pull/107207), [@&#xFFF0;ehashman](https://github.com/ehashman))
  - 今後は [KEP-1933: Defend Against Logging Secrets via Static Analysis](https://github.com/kubernetes/enhancements/tree/master/keps/sig-security/1933-secret-logging-static-analysis)の静的解析のアプローチを試みます。

## 種類別の変更点(Changes by Kind)

<!-- - The infrastructure for contextual logging is complete (feature gate implemented, JSON backend ready). ([#108995](https://github.com/kubernetes/kubernetes/pull/108995), [@&#xFFF0;pohly](https://github.com/pohly)) -->
- Contextual Logging のインフラが完成（フィーチャーゲートの実装と JSON バックエンドの準備が完了）([#108995](https://github.com/kubernetes/kubernetes/pull/108995), [@&#xFFF0;pohly](https://github.com/pohly))

### 機能追加(Feature)

<!-- - In text format, log messages that previously used quoting to prevent multi-line output (for example, text="some "quotation", anline break") will now be printed with more readable multi-line output without the escape sequences. ([#107103](https://github.com/kubernetes/kubernetes/pull/107103), [@&#xFFF0;pohly](https://github.com/pohly)) -->
- klog が v2.30.0 から v2.40.1 に更新されました。これにより Verbose.InfoSDepth 関数の追加や複数行の出力方法が変わりました([#107103](https://github.com/kubernetes/kubernetes/pull/107103), [@&#xFFF0;pohly](https://github.com/pohly))
  - [Scheduler logged config prints without line breaks · Issue #104868 · kubernetes/kubernetes](https://github.com/kubernetes/kubernetes/issues/104868)
  - [structured logging: support values with line breaks by pohly · Pull Request #273 · kubernetes/klog](https://github.com/kubernetes/klog/pull/273)
  - 複数行の場合、エスケープされずに表示し、行頭にタブを入れることで表現しているようです。

### 不具合の修正(Bug or Regression)

<!-- - Fixed performance regression in JSON logging caused by syncing stdout every time error was logged. ([#107035](https://github.com/kubernetes/kubernetes/pull/107035), [@&#xFFF0;serathius](https://github.com/serathius)) -->
- ログの出力フォーマットが JSON の場合、都度標準出力にシンクしていたため修正し性能を改善しました([#107035](https://github.com/kubernetes/kubernetes/pull/107035), [@&#xFFF0;serathius](https://github.com/serathius))

<!-- - Modified log messages that were logged with `"v":0` in JSON output although they were debug messages with a higher verbosity. ([#106978](https://github.com/kubernetes/kubernetes/pull/106978), [@&#xFFF0;pohly](https://github.com/pohly)) -->
- 高いレベルのデバッグメッセージだが、JSON 出力で `"v":0` と記録されていたログメッセージを修正しました([#106978](https://github.com/kubernetes/kubernetes/pull/106978), [@&#xFFF0;pohly](https://github.com/pohly))

<!-- - Publishing kube-proxy metrics for Windows kernel-mode ([#106581](https://github.com/kubernetes/kubernetes/pull/106581), [@&#xFFF0;knabben](https://github.com/knabben)) -->
- Windows のカーネルモードでも kube-proxy のメトリクスが公開されるように修正しました([#106581](https://github.com/kubernetes/kubernetes/pull/106581), [@&#xFFF0;knabben](https://github.com/knabben))  

<!-- - Metrics Server image bumped to v0.5.2 ([#106492](https://github.com/kubernetes/kubernetes/pull/106492), [@&#xFFF0;serathius](https://github.com/serathius)) -->
- Metrics Server が v0.5.2 にアップデートされました([#106492](https://github.com/kubernetes/kubernetes/pull/106492), [@&#xFFF0;serathius](https://github.com/serathius))

### その他(Cleanup or Flake)

<!-- Migrate statefulset files to structured logging ([#106109](https://github.com/kubernetes/kubernetes/pull/106109), [@&#xFFF0;h4ghhh](https://github.com/h4ghhh)) -->
- StatefulSet のコントローラーは構造化ロギングに移行しました([#106109](https://github.com/kubernetes/kubernetes/pull/106109), [@&#xFFF0;h4ghhh](https://github.com/h4ghhh))