Amazon EKS のメトリクスサーバーを使用して、コンテナ、ポッド、またはノードからメトリクスを収集できないのはなぜですか?

最終更新日: 2020 年 1 月 23 日

Amazon Elastic Kubernetes Service (Amazon EKS) クラスター内でメトリクスサーバーを持つコンテナ、ポッド、またはノードからメトリクスを収集できません。

簡単な説明

Amazon EKS では、メトリクスサーバーはデフォルトでインストールされません。クラスターを作成したばかりで、メトリクスサーバーを使用してコンテナ、ポッド、またはノードからメトリクスを収集できない場合は、メトリクスサーバーアプリケーションをクラスターにデプロイしたことを確認します。

それでもなお、メトリクスサーバーでメトリクスを収集できない場合は、以下のセクションのステップを実行します。

  • クラスターのノードとポッドからメトリクスを取得できるかどうかを確認します。
  • APIService が利用可能で、リクエストを処理できるかどうかを確認します。
  • GitHub で一般的な問題を確認します。
  • メトリクスが <unknown>と表示する場合は、Horizontal Pod Autoscaler (HPA) およびアプリケーションリソースリクエストを確認します。

注: メトリクスサーバーは、アプリケーションやクラスターのパフォーマンスを、長期間モニタリングすることを目的としていません。 長期モニタリングについては、Managing Resources for Containers を参照してください。

解決方法

クラスターのノードとポッドからメトリクスを取得できるかどうかを確認する

API サーバーと メトリクスサーバー 間でエラーが発生しているかを確認するには、次のコマンドを実行して、クラスターのノードとポッドからメトリクスをプルします。

$ kubectl top nodes
$ kubectl top pods

どちらのコマンドからもエラーが表示されない場合は、「APIService が利用可能で、リクエストを処理できるかどうかを確認する」セクションのステップを完了します。

何らかのエラーが出力された場合は、そのエラーの内容に従い、以下のいずれかのセクションでの手順を実行します。

  • サーバーエラー (Forbidden)
  • サーバーエラー (ServiceUnavailable)
  • ヘッダーの待機中に Client.Timeout を超えた
  • 接続拒否

サーバーエラー (Forbidden)

このエラーメッセージは、 RBAC 認証に問題があることを示しています。このエラーを解決するには、以下の点を確認します。

  • デプロイの際にServiceAccount が正しくアタッチされている。
  • ClusterRole/Role および ClusterRoleBinding/RoleBindings が、メトリクスサーバーに対し正しい RBAC アクセス許可を使用している。

aws-auth ConfigMap で定義されたロールを通じてクラスターにアクセスしている場合は、username フィールドとマッピングを設定していることを確認します。

1.    次のコマンドを実行し、aws-auth ConfigMap を記述します。

$ kubectl describe -n kube-system configmap aws-auth

2.    クラスターにアクセスするロールで username フィールドが設定されていることを確認します。次に例を示します。

Name:         aws-auth
Namespace:    kube-system
Labels:       <none>
Annotations:  <none>

Data
====
mapRoles:
----
...
-
  groups:
  - system:masters
  rolearn: arn:aws:iam::123456789123:role/kubernetes-devops
  username: devops:{{SessionName}}  # Ensure this has been specified.

サーバーエラー (ServiceUnavailable)

次のコマンドを実行し、クラスターの Metrics Server サービスアプリケーションの設定に問題がないか確認します。

$ kubectl describe apiservices v1beta1.metrics.k8s.io

この出力は次のようになります:

Name:         v1beta1.metrics.k8s.io
Namespace:
Labels:       app=metrics-server
...
API Version:  apiregistration.k8s.io/v1
Kind:         APIService
Spec:
  Group:                     metrics.k8s.io
  Group Priority Minimum:    100
  Insecure Skip TLS Verify:  true
  Service:
    Name:            metrics-server
    Namespace:       metrics
...
Status:
  Conditions:
    Last Transition Time:  2020-01-09T13:57:23Z
    Message:               all checks passed
    Reason:                Passed
    Status:                True
    Type:                  Available
Events:                    <none>

メトリクスサーバーサービスが利用可能で、これらのチェックに合格した場合は、StatusTrueに設定されます。

[Status] が True に設定されているにもかかわらず問題が解決されない場合は、「APIService が利用可能で、リクエストを処理できるかどうかを確認する」セクションのステップを完了します。

出力で StatusFalse に設定されている場合は、関連のある Reason コードと、人間が読み取れる形式で Conditions を説明している Message を見つけ出します。APIService が失敗する場合の例を次に示します。

...
Status:
  Conditions:
    Last Transition Time:  2020-01-09T14:40:28Z
    Message:               no response from https://10.0.35.231:443: Get https://10.0.35.231:443: dial tcp 10.0.35.231:443: connect: connection refused
    Reason:                FailedDiscoveryCheck
    Status:                False
    Type:                  Available

ReasonFailedDiscoveryCheck と記述されていない場合は、「APIServer 条件で失敗するその他の理由」セクションのステップを完了します。

この Reason コードが FailedDiscoveryCheck とされていれば、メトリクスサーバーサービスは利用可能で、ポッドは実行中です。Kubernetes APIServer では、メトリクスサーバーのエンドポイントに接続しようとするとエラーを返します。

APIServer 条件メッセージの中に「Client.Timeout exceeded while awaiting headers」と記述されている場合は、「Client.Timeout exceeded while awaiting headers エラーを解決する」の手順を完了します。

APIServer 条件メッセージに「connection refused」が含まれている場合は、「connection refused エラーを解決する」セクションの手順を完了します。

「Client.Timeout exceeded while awaiting headers」エラーを解決する

APIService によるこのエラーメッセージは、セキュリティグループまたはネットワークアクセスコントロールリスト (ACL) が正しく設定されていないため、 metrics-server ポッドにアクセスできないことを示します。次に例を示します。

no response from https://10.0.35.231:443: Get https://10.0.35.231:443: net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

このエラーを解決するには、セキュリティグループが Amazon EKS の 最小トラフィック要件に準拠していることを確認します。

「connection refused」エラーを解決する

このエラーが APIServer メッセージに記述される場合、コンテナが間違ったポートで受信待機していることを示します。次に例を示します。

no response from https://10.0.35.231:443: Get https://10.0.35.231:443: dial tcp 10.0.35.231:443: connect: connection refused

このエラーを解決するには次のコマンドを実行して、metrics-server のデプロイ時に PortsImage、および Command の値が正く設定されているかを確認します。

$ kubectl describe deployment metrics-server -n metrics

この出力は次のようになります:

Name:                   metrics-server
Namespace:              metrics
CreationTimestamp:      Wed, 08 Jan 2020 11:48:45 +0200
Labels:                 app=metrics-server
...
  Containers:
   metrics-server:
    Image:      gcr.io/google_containers/metrics-server-amd64:v0.3.6
    Port:       443/TCP
    Command:
    - /metrics-server
    - --logtostderr
    - --secure-port=443
...

注 : Command および Image の値は、メトリクスサーバーのデプロイ方法とイメージの保存場所によって異なります。Command の中に -secure-port パラメータが含まれている場合、ポッドが表示する Port (前の例では 443/TCP) は、このパラメータと一致します。Command-secure-port パラメータが含まれていない場合、ポートはデフォルト値の 443に設定されます。

APIServer 条件で失敗するその他の理由

次に示す APIService に関する理由コードのいずれかが表示される場合は、該当するエラーメッセージに基づいたアクションを実行します。ServiceNotFound、ServiceAccessError、ServicePortError、EndpointsNotFound、EndpointsAccessError、MissingEndpoints。

1.    次のコマンドを実行し、エラーのあるサービスに関する情報を取得します。

$ kubectl get service

この出力から、Kubernetes サービスの名前と名前空間が APIService.Spec.Service で定義されているものと同じであることを確認し、ポートが 443/TCPに設定されていることを確認します。次に例を示します。

NAME                             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
metrics-server                   ClusterIP   172.20.172.133   <none>        443/TCP    65m

2.    次のコマンドを実行し、エンドポイントを一覧表示します。

$ kubectl get endpoints metrics-server

この出力により、metrics-server サービスのエンドポイントが少なくとも 1 つあることを確認します。

NAME             ENDPOINTS         AGE
metrics-server   10.0.35.231:443   76m

3.    次のコマンドを実行し、デプロイが存在することと、そのラベルが metrics-server サービスのものと一致することを確認します。

$ kubectl describe deploy metrics-server -n metrics

この出力から、デプロイに少なくとも 1 つのレプリカがあることを確認します。

Name:                   metrics-server
Namespace:              metrics
CreationTimestamp:      Wed, 08 Jan 2020 11:48:45 +0200
Labels:                 app=metrics-server
                        release=metrics-server
...
Selector:               app=metrics-server,release=metrics-server
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
...
Pod Template:
  Labels:           app=metrics-server
                    release=metrics-server
  Service Account:  metrics-server
  Containers:
   metrics-server:
    Image:      gcr.io/google_containers/metrics-server-amd64:v0.3.6
...

ここまでの手順を行ってもメトリクスサーバーを使用したメトリクスの収集ができない場合は、「APIService が利用可能で、リクエストを処理できるかどうかを確認する」セクションのステップを実行します。

APIService が利用可能で、リクエストを処理できるかどうかを確認する

次のコマンドを実行し、メトリクスサーバーポッドからログを抽出します。

$ kubectl logs -n <namespace> -l app=metrics-server

例として、metrics-server でのエラーログは Eで始まります。

E0610 23:13:28.247604       1 reststorage.go:98] unable to fetch pod metrics for pod default/php-apache-b5f58cc5f-nv8sz: no metrics known for pod "default/php-apache-b5f58cc5f-nv8sz"
E0610 23:13:43.260069       1 reststorage.go:98] unable to fetch pod metrics for pod default/php-apache-b5f58cc5f-nv8sz: no metrics known for pod "default/php-apache-b5f58cc5f-nv8sz"
E0610 23:16:13.346070       1 reststorage.go:98] unable to fetch pod metrics for pod default/php-apache-b5f58cc5f-cj67b: no metrics known for pod "default/php-apache-b5f58cc5f-cj67b"
E0610 23:16:13.346087       1 reststorage.go:98] unable to fetch pod metrics for pod default/php-apache-b5f58cc5f-sqc6l: no metrics known for pod "default/php-apache-b5f58cc5f-sqc6l"
E0610 23:16:13.346091       1 reststorage.go:98] unable to fetch pod metrics for pod default/php-apache-b5f58cc5f-4cpwk: no metrics known for pod "default/php-apache-b5f58cc5f-4cpwk"

メトリクスサーバーが送信するエラーログでは、メトリクスサーバーデプロイコマンドに設定上の問題がある、もしくは、メトリクスサーバーコンテナ自体にバグがあることを示します。明確なエラーメッセージが見つからなかったり、バグがありそうだと考えられ、依然としてメトリクスサーバーでメトリクスを収集できない場合は、「GitHub で一般的な問題をチェックする」セクションの手順を実行します。

GitHub で一般的な問題を確認する

ここまでを実行しても、コンテナ、ポッド、またはノードからメトリクスを収集できない場合は、GitHub でメトリクスサーバーに関する一般的な問題を確認します

不明なメトリクスに対する HPA とアプリケーションリソースリクエストを確認する

1.    次のコマンドを実行し、HPA 定義を確認します。

$ kubectl get hpa -n namespace 2048-deployment

注: namespace2048-deployment を、ご自身のアプリケーションの HPA 設定値に置き換えます。

出力の Targets 列に <unknown> と表示される場合があります。次に例を示します。

NAME              REFERENCE                    TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
2048-deployment   Deployment/2048-deployment   <unknown>/80%   1         2         2          10s

2.    数分待ってから、ステップ 1 のコマンドを繰り返します。

<unknown> エラーが引き続き表示される場合は、次のコマンドを実行します。

$ kubectl describe hpa -n <namespace> 2048-deployment

次に、出力の [Events] セクションで詳細な内容を確認します。

Name:                                                  2048-deployment
Namespace:                                             2048-game
...
Metrics:                                               ( current / target )
  resource cpu on pods  (as a percentage of request):  <unknown> / 80%
Min replicas:                                          1
Max replicas:                                          2
Deployment pods:                                       2 current / 2 desired
Conditions:
  Type           Status  Reason                   Message
  ----           ------  ------                   -------
  AbleToScale    True    SucceededGetScale        the HPA controller was able to get the target's current scale
  ScalingActive  False   FailedGetResourceMetric  the HPA was unable to compute the replica count: missing request for cpu
Events:
  Type     Reason                   Age                     From                       Message
  ----     ------                   ----                    ----                       -------
  Warning  FailedGetResourceMetric  3m29s (x4333 over 19h)  horizontal-pod-autoscaler  missing request for cpu

[Message] 列に missing request for [x] と表示される場合は、 Deployment または ReplicaSet が仕様に合ったリソースリクエストを宣言していない可能性があります。ポッド内のすべてのコンテナにリクエストが宣言されていることを確認します。

リクエストが 1 つでも宣言されていないと、HPA のメトリクスが <unknown> レスポンスを返す可能性があります。詳細については Managing Resources for Containers を参照してください。


この記事はお役に立ちましたか?


請求に関するサポートまたは技術的なサポートが必要ですか?