ブログ

Kubernetes API Serverを監視する方法

Google Cloudとコンテナの継続的なセキュリティ

本文の内容は、2019年12月18日にSysdigのCarlos Arillaが投稿したブログ(https://sysdig.com/blog/monitor-kubernetes-api-server/)を元に日本語に翻訳・再構成した内容となっております。

Kubernetes APIサーバーを監視する方法を学ぶことは、Kubernetesを運用環境で実行する際に非常に重要です。kube-apiserverを監視すると、待ち時間、エラーの検出およびトラブルシューティングを行い、期待どおりにサービスが実行されることを検証できます。kube-apiserverから最も重要なメトリクスを収集し、それらを使用してこのサービスを監視する方法を学ぶために是非ご一読いただければと思います。

Kubernetes APIサーバーは、Kubernetesコントロールプレーンの基本コンポーネントです。クラスター内で実行されているすべてのサービスは、このインターフェースを使用して相互に通信します。ユーザーインタラクション全体もAPIを介して処理されます。kubectlはAPIにリクエストを送信するラッパーです。kubectlはHTTPを使用してAPIサーバーに接続しますが、残りのコントロールプレーンコンポーネントはgRPCを使用します。 実は、両方のチャネルを監視する準備はすでに整っています。

20200214-31.png

他のマイクロサービスと同様に、Kubernetes APIサーバーの健全性とパフォーマンスを監視するためにゴールデンシグナルアプローチを採用します。

  • レイテンシー
  • リクエストレート
  • エラー
  • サチュレイション(飽和)

では、それぞれの意味を説明する前に、これらの指標を取得する方法を見ていきましょう。

kube-apiserverを監視するためのメトリクスの取得

APIサーバーはデフォルトでPrometheusメトリクスをは装備・公開しています。レイテンシ、リクエスト、エラー、etcdキャッシュステータスなどのモニタリングメトリクスを提供しています。このエンドポイントは簡単にスクレイピングでき、追加のスクリプトやエクスポーターを必要とせずに有用な情報を取得できます。

APIサーバーでは、/metricsエンドポイントへの要求を行うために認証が必要なので、そのための特権を持つ認証情報を取得する必要があります。クラスター内でPrometheusを実行している場合、ClusterRoleにバインドされたサービスアカウントを使用して認証し、GETリクエストを/metricsエンドポイントに許可します。

これは、Prometheusが使用するClusterRoleに1つのルールを追加することで実行できます。

apiVersion: rbac.authorization.k8s.io/v1
	kind: ClusterRole
	metadata:
	  labels:
	    app: monitor
	    component: server
	  name: monitor
	rules:
	- nonResourceURLs:
	  - /metrics
	  verbs:
	  - get

このように、ポッド内の/var/run/secrets/kubernetes.io/serviceaccountにあるサービスアカウントからbearerトークンを使用して/metricsエンドポイントにアクセスできます。

Prometheusポッド内からこのシェルコマンドを実行して、認証をテストできます。

#curl  https://kubernetes.default.svc/metrics -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" -vvv --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt

Prometheusメトリクスの長いリストが返されます(ここでは省略されています)。

# TYPE APIServiceOpenAPIAggregationControllerQueue1_adds counter
APIServiceOpenAPIAggregationControllerQueue1_adds 108089
# HELP APIServiceOpenAPIAggregationControllerQueue1_depth Current depth of workqueue: APIServiceOpenAPIAggregationControllerQueue1
# TYPE APIServiceOpenAPIAggregationControllerQueue1_depth gauge
APIServiceOpenAPIAggregationControllerQueue1_depth 0
# HELP APIServiceOpenAPIAggregationControllerQueue1_queue_latency How long an item stays in workqueueAPIServiceOpenAPIAggregationControllerQueue1 before being requested.
# TYPE APIServiceOpenAPIAggregationControllerQueue1_queue_latency summary
APIServiceOpenAPIAggregationControllerQueue1_queue_latency{quantile="0.5"} 15
...

Kubernetes APIサーバーエンドポイントをスクレイプするようにPrometheusを構成するには、ターゲットに1つのジョブを追加します。

- job_name: 'kubernetes-apiservers'
	    kubernetes_sd_configs:
	      - role: endpoints
	    scheme: https 
	    tls_config:
	      ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
	    bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
	    relabel_configs:
	      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
	        action: keep
	        regex: default;kubernetes;https

Kubernetes APIサーバーの監視:何を見るべきでしょうか?

ゴールデンシグナルを使用してKubernetes APIサーバーを監視できます。ゴールデンシグナルは、消費者(ここではkubectlユーザーと内部クラスターコンポーネント)に対するサービスのパフォーマンスに関する洞察を提供する多数のメトリクスを通じてサービスを監視するために使用される手法です。これらのメトリクスは、レイテンシー、リクエスト、エラー、およびサチュレイション(サーバーが現在のリソースで最大容量に向かってどれだけビジーであるか)です。

免責事項:APIサーバーのメトリクスはKubernetesのバージョンによって異なる場合があります。 ここでは、Kubernetes 1.15を使用しました。Kubernetesリポジトリ(1.15.3バージョンのリンク)で、ご使用のバージョンで利用可能なメトリクスを確認できます。

レイテンシー:レイテンシーは、apiserver_request_duration_secondsヒストグラムバケットから抽出できます。

# TYPE apiserver_request_latencies histogram
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="125000"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="250000"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="500000"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="1e+06"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="2e+06"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="4e+06"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="8e+06"} 2
apiserver_request_duration_seconds{resource="adapters",scope="cluster",subresource="",verb="LIST",le="+Inf"} 2
apiserver_request_duration_seconds_sum{resource="adapters",scope="cluster",subresource="",verb="LIST"} 50270
apiserver_request_duration_seconds_count{resource="adapters",scope="cluster",subresource="",verb="LIST"} 2

レイテンシの広がりを理解するには、パーセンタイルを使用することをお勧めします。

histogram_quantile(0.99, sum(rate(apiserver_request_latencies_count{job=\"kubernetes-apiservers\"}[5m])) by (verb, le))

リクエストレート:メトリクスapiserver_request_totalを使用して、サービスへの要求を、要求元、サービス、アクション、および成功したかどうかを監視できます。

# TYPE apiserver_request_count counter
apiserver_request_total{client="Go-http-client/1.1",code="0",contentType="",resource="pods",scope="namespace",subresource="portforward",verb="CONNECT"} 4
apiserver_request_total{client="Go-http-client/2.0",code="200",contentType="application/json",resource="alertmanagers",scope="cluster",subresource="",verb="LIST"} 1
apiserver_request_total{client="Go-http-client/2.0",code="200",contentType="application/json",resource="alertmanagers",scope="cluster",subresource="",verb="WATCH"} 72082
apiserver_request_total{client="Go-http-client/2.0",code="200",contentType="application/json",resource="clusterinformations",scope="cluster",subresource="",verb="LIST"} 1

たとえば、次のようにサービス全体で成功したすべてのリクエストを取得できます。

sum(rate(apiserver_request_total{job=\"kubernetes-apiservers\",code=~\"2..\"}[5m]))

エラー:リクエストレートに使用したものと同じクエリを使用できますが、400および500のエラーコードをフィルタリングできます。

sum(rate(apiserver_request_total{job=\"kubernetes-apiservers\",code=~\"[45]..\"}[5m]))

サチュレーション:このサービスのCPU、メモリ、ネットワークI/Oなどのシステムリソース使用メトリクスによってサチュレーションを監視できます。

APIサーバー関連のメトリクスに加えて、他の関連するメトリクスにアクセスできます。 APIサーバーが提供するもの:

controller-managerから:

  • ワークキューの追加率:コントローラーが実行する新しいアクションをスケジュールする速度。これらのアクションには、クラスター内のリソース(ワークロード、configmap、service...)の追加、削除、および変更を含めることができます。
  • ワークキューの待ち時間:コントローラーマネージャーがこれらのアクションを実行する速度はどれくらいですか?
  • ワークキューの深さ:実行を待機しているアクションの数。

etcdから:

  • etcdキャッシュエントリ:いくつのクエリ結果がキャッシュされましたか?
  • etcdキャッシュのヒット/ミス率:キャッシュは有用ですか?
  • etcdキャッシュ期間:キャッシュ結果はどのくらいの期間保存されますか?

課題例

APIへのリクエストでレイテンシーの増加を検出します。

これは通常、APIサーバーの過負荷の兆候です。 おそらく、クラスターには多くの負荷がかかり、APIサーバーをスケールアウトする必要があります。

リクエストのタイプ、リソース、またはverbごとにメトリクスをセグメント化できます。これにより、問題の場所を検出できます。 たぶん、etcdの読み取りまたは書き込みに問題があり、修正する必要があります。

作業キューの深さと待ち時間の増加を検出します。

アクションのスケジューリングに問題があります。スケジューラが機能していることを確認する必要があります。一部のノードが過負荷になっていて、クラスターをスケールアウトする必要がある場合があります。 おそらく、1つのノードに問題があり、それを交換する必要があるかも知れません。

Sysdig MonitorでのKubernetes APIサーバーメトリクスの監視

Sysdig Monitorを使用してKubernetes APIサーバーにおけるPrometheusメトリクスを監視する場合は、Sysdigエージェントのyaml設定ファイルにいくつかのセクションを追加するだけです。

#Enable prometheus metrics
	metrics_filter:
	 # beginning of kube-apiserver
	    - include: "apiserver_request_total"
	    - include: "apiserver_request_duration_seconds*"
	    - include: "workqueue_adds_total"
	    - include: "workqueue_depth"
	    - include: "workqueue_queue_duration_seconds*"
	    - include: "etcd_helper_cache_entry_total"
	    - include: "etcd_helper_cache_hit_total"
	    - include: "etcd_helper_cache_miss_total"
	    - include: "etcd_request_cache_get_duration_seconds*"
	    - include: "etcd_request_cache_add_duration_seconds*"
	    - include: "go_goroutines"
	    # end of kube-apiserver
	prometheus:
	    enabled: true
	    histograms: true
	    max_metrics: 3000
	    max_metrics_per_process: 3000
	    process_filter:
	      - include:
	          kubernetes.pod.label.k8s-app: kube-apiserver
	          port: 8080
	          conf:
	            tags:
	              kubernetes.component.name: kube-apiserver
	            host: 127.0.0.1
	            port: 8080
	            use_https: false
	            auth_token_path: "/var/run/secrets/kubernetes.io/serviceaccount/token"

metrics_filter部分を使用すると、メトリクスの制限に達した場合にこれらのメトリクスが破棄されないようにできます。次のように、このリストにないAPIサーバーが提供する他のメトリクスを追加できます。

metrics_filter:
    - include: "apiserver_request_total"
    ...
    - include: "go_goroutines"

次に、Sysdigエージェントがメトリクスをスクレイピングする方法を構成し、ラベルkube-apiserverを持つKubernetesポッドを検索し、ポート8080を介してlocalhostでスクレイピングします。Sysdigエージェントは、ネットワークコンテキストを切り替えて、そのままポッドに接続できるため ローカルホストでは、httpsを使用する必要はありません。また、メトリクスエンドポイントにアクセスするためにエージェントが使用する認証トークンを指定する必要があります。

prometheus:
    enabled: true
    ...
    process_filter:
      - include:
          kubernetes.pod.label.k8s-app: kube-apiserver
          port: 8080
          conf:
            tags:
              kubernetes.component.name: kube-apiserver
            host: 127.0.0.1
            port: 8080
            use_https: false
            auth_token_path: "/var/run/secrets/kubernetes.io/serviceaccount/token"

その後、これらのメトリクスを使用してカスタムダッシュボードを構築できます。 興味をお持ちの場合は、事前に作成したダッシュボードを共有できます。

20200214-32.png

まとめ

Kubernetes APIサーバーの監視は、クラスター操作の重要な部分であるため、基本です。 クラスターコンポーネント間のすべての通信は、kube-apiserverを介して行われます。

APIサーバーの問題を検出することは、Kubernetesクラスターの問題を修正するための重要な要素となります。コントロールプレーンコンポーネントで何が行われているかを認識し、問題が発生した場合にそれを活用する方法を学ぶ必要があります。

すべてのKubernetesコンポーネントを適切に監視することは、クラスター内で実行されているワークロードとアプリケーションを監視することと同じくらい重要です。コントロールプレーンを監視することを忘れないでください!

Sysdigに関するお問い合わせはこちらから

最近の投稿

カテゴリー

アーカイブ

ご質問・お問い合わせはこちら

top