リソース競合の問題のトラブルシューティング

このページでは、Google Distributed Cloud 環境でのリソース競合の問題を特定してトラブルシューティングする方法について説明します。

さらにサポートを必要とされる場合は、Cloud カスタマーケアにお問い合わせください。

概要

Google Distributed Cloud ではリソース競合が発生し、コンテナの速度が低下したり、パフォーマンスが低下したり、終了したりする場合があります。これは、コンテナの CPU やメモリの使用量が多い場合に発生することがあります。

CPU とメモリ管理の仕組み

  • CPU:

    • Pod は、Pod 内のコンテナで指定された CPU リクエストに基づいてノードにスケジュールされます。
    • Pod のコンテナは、コンテナで指定された上限を超える CPU を使用できません
    • コンテナの CPU 使用率は CPU 上限でスロットリングされます。
    • CPU 使用率がノードレベルでスロットリングされると、コンテナにはリクエストに応じて CPU サイクルが自動的に割り当てられます。

    詳しくは、リソース リクエストを含む Pod のスケジュール設定に関するページをご覧ください。

  • メモリ:

    • Pod は、Pod 内のコンテナで指定されたメモリ リクエストに基づいて、ノードにスケジュールされます。
    • コンテナは、コンテナで指定された上限を超えるメモリを使用できません。
    • メモリ上限が指定されていない場合、コンテナはノードで使用可能なすべてのメモリを使用することがあります。その後、システムが OOM-Killer(Out Of Memory Killer)をトリガーし、優先度の低い Pod を強制排除することがあります。

詳細については、Kubernetes の CPU リソースの割り当てに関するページメモリリソースの割り当てに関するページGKE Enterprise の指標をご覧ください。

Issues

コンテナが遅くなる

CPU 競合の問題により、コンテナの処理速度が低下する可能性があります。次のような原因が考えられます。

コンテナの CPU 使用率が高い:

コンテナは、CPU リクエストに応じて CPU サイクルを確保できない場合や、コンテナに必要なものよりも低すぎる CPU リクエストを設定している場合に遅くなる可能性があります。コンテナの CPU 上限に対する CPU 使用率を確認します。

Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタから次のクエリを実行します。

  fetch k8s_container
  | metric 'kubernetes.io/anthos/container/cpu/limit_utilization'
  | group_by 1m, [value_limit_utilization_mean: mean(value.limit_utilization)]
  | filter resource.cluster_name == 'CLUSTER_NAME'
  | filter resource.container_name == 'CONTAINER_NAME'
  | filter resource.pod_name == 'POD_NAME'
  | filter resource.namespace_name == 'NAMESPACE_NAME'
  | every 1m

次に、以下のいずれかを行います。

ノードでの CPU 使用率が高い

Pod の個々のコンテナで CPU 上限に対する CPU 使用率が高くない場合は、ノードで実行されているコンテナのセットに割り当てる CPU サイクルがノードに不足している可能性があります。そのため、次の手順に沿って、ノード上の割り当て可能な CPU に対する実際の CPU 使用率を確認します。

  1. 動作が遅い Pod のノードを取得します。

    kubectl get pod –kubeconfig CLUSTER_KUBECONFIG --namespace NAMESPACE POD --output wide
    
  2. Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタから次のクエリを実行します。

    fetch k8s_node
    | metric 'kubernetes.io/anthos/node/cpu/allocatable_utilization'
    | group_by 1m,
        [value_allocatable_utilization_mean: mean(value.allocatable_utilization)]
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.node_name == 'NODE_NAME'
    | every 1m
    

    この比率が高い場合(>=0.8)、ノードに十分な CPU サイクルがなく、オーバーサブスクライブされていることを意味します。次の手順に沿って、そのノードの他のすべての Pod の CPU 使用率を確認し、より多くの CPU を使用している別のコンテナがあるかどうかを調べてください。

    1. ノード上のすべての Pod を取得します。
    kubectl get pods --all-namespaces -o wide --field-selector spec.nodeName=NODE_NAME
    
    1. 各コンテナの CPU 使用率を確認します。
    fetch k8s_container
    | metric 'kubernetes.io/anthos/container/cpu/limit_utilization'
    | group_by 1m, [value_limit_utilization_mean: mean(value.limit_utilization)]
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.container_name == 'CONTAINER_NAME'
    | filter resource.pod_name == 'POD_NAME'
    | filter resource.namespace_name == 'NAMESPACE_NAME'
    | every 1m
    

    ノードに CPU 使用率の高いコンテナが他にもある場合は、動作が遅いコンテナの CPU リクエストと上限を増やします。これにより、Pod が別のノードに再作成され、必要な CPU サイクルが得られます。

システム Pod の動作が遅い場合は、Google サポートにお問い合わせください。

vSphere レベルの CPU オーバーサブスクリプション

ノードまたは Pod の CPU 使用率が高くなく、コンテナがまだ遅い場合は、VM が vSphere レベルでオーバーサブスクライブされている可能性があります。そのため、ノードは基盤となる仮想化から予想される CPU サイクルを得られません。

こちらの手順に沿って、VM がオーバーサブスクライブされているかどうかを確認します。オーバーサブスクリプションが検出された場合は、次の方法をお試しください。

  • 一部の VM を他のホストに移動する。
  • ホストの VM あたりの vCPU の数を評価して減らす。
  • GKE Enterprise VM に追加のリソースを割り当てる。
  • コンテナの CPU リクエストと上限を増やす。これにより、Pod が別のノードに再作成され、必要な CPU サイクルが得られます。

Pod で OOMkilled(Out of Memory-Killed)が発生する

Pod で、メモリリーク、またはコンテナのメモリ リクエストと上限の構成不良により OOMKilled が発生することがあります。次のような原因が考えられます。

コンテナのメモリ使用量が多い

Pod 内のコンテナが割り当てられた合計メモリを過剰に使用した場合、Pod で OOMkilled が発生する可能性があります。コンテナのメモリ上限に対するメモリ リクエストの比率を確認します。

Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタから次のクエリを実行します。

fetch k8s_container
| metric 'kubernetes.io/anthos/container/memory/limit_utilization'
| filter (metric.memory_type == 'non-evictable')
| group_by 1m, [value_limit_utilization_mean: mean(value.limit_utilization)]
| filter resource.cluster_name == 'CLUSTER_NAME'
| filter resource.container_name == 'CONTAINER_NAME'
| filter resource.pod_name == 'POD_NAME'
| filter resource.namespace_name == 'NAMESPACE_NAME'
| every 1m

次に、以下のいずれかを行います。

ノードのメモリ使用量が多い

ノードで実行中のすべての Pod のメモリ使用量が使用可能なメモリを超えると、Pod で OOMkilled が発生することがあります。そのため、ノードの MemoryPressure 条件が True であるかどうかを確認します。

  1. 次のコマンドを実行して、Conditions セクションを調べます。

    kubectl describe nodes --kubeconfig CLUSTER_KUBECONFIG NODE-NAME
    
  2. MemoryPressure 条件が True の場合、ノードのメモリ使用率を確認します。

    fetch k8s_node
    | metric 'kubernetes.io/anthos/node/memory/allocatable_utilization'
    | filter (metric.memory_type == 'non-evictable')
    | group_by 1m,
        [value_allocatable_utilization_mean: mean(value.allocatable_utilization)]
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.node_name = 'NODE_NAME'
    | every 1m
    

    この比率が高い場合(>= 0.8)、ノードには Pod に割り当てる十分なメモリがないことを意味します。これはおそらく一部のプロセスや他の Pod が多くのメモリを使用していることが原因です。

  3. Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタを使用して、次のクエリを実行し、ノード上のコンテナのメモリ使用量を確認します。

    fetch k8s_node
    | metric 'kubernetes.io/anthos/container_memory_usage_bytes'
    | filter resource.cluster_name == 'CLUSTER_NAME'
    | filter resource.node_name == 'NODE_NAME'
    | group_by 1m,
        [value_container_memory_usage_bytes_mean:
          mean(value.container_memory_usage_bytes)]
    | every 1m
    

    メモリ使用量の多いコンテナがある場合は、コンテナの機能を調べるか、必要に応じてコンテナのメモリ リクエストを増やします

メモリを大量に使用しているのがシステム Pod である場合は、Google サポートにお問い合わせください。

さらに、Google Distributed Cloud の自動スケーリング機能を有効にして、ワークロードの需要に基づいてノードプールのスケールアップとスケールダウンを自動的に行うことができます。

オートスケーラーを有効にする方法をご確認ください。

etcd に関する問題

etcd サーバーの問題により、Anthos clusters on VMware でコンテナの障害が発生することがあります。また、次のような問題が発生する可能性があります。

  • 次の形式の API サーバーログが繰り返される:

    etcdserver: request timed outetcdserver: leader changed

  • 次の形式の etcd ログが繰り返される:

    W | wal: sync duration of 2.466870869s, expected less than 1sW | etcdserver: read-only range request * took too long

次のような原因が考えられます。

CPU スロットリング

etcd サーバー Pod や、etcd サーバーが実行されているノードでの CPU スロットリングが原因で、etcd サーバーが遅くなることがあります。CPU の競合の問題を確認するには、コンテナが遅くなるの手順をご覧ください。

ectd サーバー Pod またはノードで CPU の競合を検出した場合は、ユーザー クラスタのコントロール プレーン ノードに CPU を追加します。gkectl update を使用して、ユーザー クラスタ構成ファイルの cpus フィールドを編集します。

etcd Pod の OOMkilled

リソース競合の問題により、etcd Pod で OOMkilled が発生することがあります。Pod で OOMkilled(メモリ不足)が発生するセクションの手順に沿って、etcd サーバー Pod や etcd サーバーが実行されているノードにメモリ競合の問題がないか確認します。

etcd Pod の OOMkill を検出した場合は、ユーザー クラスタのコントロール プレーン ノードで使用可能なメモリを増やします。gkectl update を使用して、ユーザー クラスタ構成ファイルの memoryMB フィールドを編集します。

ディスクの速度低下

etcd サーバー Pod やノードの CPU またはメモリ使用量に問題がない場合、基盤となるデータストアが低速であると、またはスロットリングされていると、etcd が遅くなる可能性があります。

次のような問題がないか確認します。

  • etcd サーバーで基盤となるディスクの読み書きに時間がかかりすぎているかどうかを確認するには:

    1. etcd のログを取得します。

      kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n ETCD_POD_NAMESPACE ETCD_POD
      
    2. etcd でディスクからの読み取りに時間がかかりすぎているかどうかを検出するには、次のパターンのエントリを探します。

      W | etcdserver: read-only range request "key:\"/registry/configmaps/default/clusterapi-vsphere-controller-manager-leader-election\" " with result "range_response_count:1 size:685" took too long (6.893127339s) to execute

    3. etcd でディスクへの書き込みに時間がかかりすぎているかどうかを検出するには、次のパターンのエントリを探します。

      W | wal: sync duration of 2.466870869s, expected less than 1s

    etcd ログで上記のログパターンのいずれかまたは両方が頻繁に表示される場合は、ディスクの速度が低下していることを示しています。次に、データストアとディスクのパフォーマンスを確認します。

  • etcd の指標を確認するには:

    1. etcd の WAL 同期レイテンシを取得します。

      Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタから次のクエリを実行します。

      fetch k8s_container::kubernetes.io/anthos/etcd_disk_wal_fsync_duration_seconds
      | every 1m
      | filter resource.cluster_name == 'CLUSTER_NAME'
      | filter resource.pod_name == 'POD_NAME'
      | filter resource.namespace_name == 'NAMESPACE_NAME'
      | percentile 99
      
    2. etcd の書き込みレイテンシを取得します。

      Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタから次のクエリを実行します。

      fetch k8s_container::kubernetes.io/anthos/etcd_disk_backend_commit_duration_seconds
      | every 1m
      | filter resource.cluster_name == 'CLUSTER_NAME'
      | filter resource.pod_name == 'POD_NAME'
      | filter resource.namespace_name == 'NAMESPACE_NAME'
      | percentile 99
      

    etcd_disk_wal_fsync_duration_secondsp99 が継続的に 10 ミリ秒を超える場合や、etcd_disk_backend_commit_duration_secondsp99 が継続的に 25 ミリ秒を超える場合は、ディスクの速度が低下していることを示しています。次に、データストアとディスクのパフォーマンスを確認します。

VM ディスクに対する読み取り / 書き込みレイテンシ

VM 仮想ディスクに対する読み取り / 書き込みレイテンシを確認する手順は次のとおりです。

  1. 低速の etcd Pod のノードを特定します。

    kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG get pods -n ETCD_POD_NAMESPACE ETCD_POD -owide
    
  2. vSphere にログインし、前の手順で特定した VM を選択します。vSphere で、[Monitor] > [Performance] > [Advanced] に移動し、[View] セクションの [Virtual Disk] を選択して、仮想ディスクの読み取りと書き込みのレイテンシを特定します。

    仮想ディスクの読み取り / 書き込みレイテンシが高い場合:

    • データストアで実行されている他の VM を調べて、1 秒あたりの入出力オペレーション(IOPS)の多いものがないか確認します。IOPS の急増を示す VM がある場合は、その VM の機能を検証します。
    • ラボやインフラチームに連絡して、読み取りと書き込みの帯域幅がどの段階でもスロットリングまたは制限されていないことを確認してください。
    • ラボやインフラチームに連絡して、ディスク パフォーマンスストレージ パフォーマンスの問題(存在する場合)を特定します。

詳しくは、リソースのスケーリングに関するおすすめの方法をご覧ください。

API サーバーの問題

API サーバーとの通信中に Google Distributed Cloud のコンテナでレイテンシが発生した場合、または Kubectl コマンドが失敗するか、応答に時間がかかりすぎる場合は、API サーバーに問題があることを示している可能性があります。

次のような原因が考えられます。

大量の API リクエスト

API サーバーへのリクエストの頻度と量が過大な場合、API サーバーの応答が遅くなることがあります。API サーバーがリクエストのスロットリングを開始した後も、応答時間が遅いままである場合があります。このため、API サーバーに対する API リクエストのレートを確認します。

Google Cloud コンソール > [モニタリング] > [Metrics Explorer] で、MQL エディタから次のクエリを実行します。

fetch k8s_container::kubernetes.io/anthos/apiserver_request_total
| filter resource.cluster_name == 'CLUSTER_NAME'
| filter resource.pod_name == 'APISERVER_POD_NAME'
| filter resource.namespace_name == 'NAMESPACE_NAME'
| align rate(1m)
| every 1m
| group_by [metric.verb]

API リクエストが予期せず増加した場合は、Cloud Audit Logging を使用して、API サーバーに頻繁にクエリを実行している可能性のある Pod を特定します。

  • システム Pod の場合は、Google サポートにお問い合わせください。
  • ユーザー Pod の場合は、さらに調査して、API リクエストが想定どおりかどうかを判断します。

CPU スロットリング

API サーバーに対するリクエスト率が高いと、CPU スロットリングが発生する可能性があります。この場合、API サーバー Pod やノードでの CPU の競合が原因で、API サーバーが遅くなることがあります。

コンテナが遅くなるセクションを参照して、Pod やノードに CPU 競合の問題がないか確認します。

API サーバー Pod の OOMkilled

リソース競合の問題により、API サーバー Pod で OOMkilled が発生することがあります。Pod で OOMkilled(Out of Memory-Killed)が発生するセクションの手順に沿って、Pod やノードにメモリ競合の問題がないか確認します。

etcd のレスポンスが遅い

API サーバーは etcd クラスタとの通信を利用して、クライアントへの読み取り / 書き込みリクエストを処理します。etcd が遅いか応答がない場合、API サーバーも遅くなります。

API サーバーのログを取得して、etcd の問題が原因で API サーバーが遅くなっているのかどうかを確認します。

kubectl –kubeconfig ADMIN_CLUSTER_KUBECONFIG logs -n APISERVER_NAMESPACE APISERVER_POD_NAME

繰り返し発生するログ(etcdserver: request timedoutetcdserver: leader changed など)が見られる場合は、etcd に関する問題の手順に沿ってディスク関連の問題を解決してください。

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。