階層型ワークロードの監視

Hierarchy Controller は、クラスタの階層名前空間と抽象名前空間の両方を使用して、ワークロードのオブザーバビリティを高めます。これを実現するには、クラスタのツリーラベルを Pod に伝達して、次のような Kubernetes ラベルを取り込めるシステムで使用できるようにします。

たとえば、サンプル リポジトリからの名前空間で実行されているワークロードについて考えてみましょう。

Hierarchy Controller を使用すると、shipping-app-backendonline などの抽象名前空間の子孫である任意ワークロードによって生成された Pod、ログ、使用状況測定を選択できます。これには、Git リポジトリにある名前空間(shipping-prod など)だけでなく、それらの名前空間の子孫として作成する Hierarchy Controller の子名前空間のワークロードも含まれます。

階層型オブザーバビリティの有効化

階層型オブザーバビリティは、Hierarchy Controller によって提供されます。階層型の可観測性を有効にするには:

  1. Hierarchy Controller をインストールする

  2. Config Sync Operator の構成ファイルの spec.hierarchyController オブジェクトで enablePodTreeLabels の値を true に設定します。

    # config-management.yaml
    
    apiVersion: configmanagement.gke.io/v1
    kind: ConfigManagement
    metadata:
      name: config-management
    spec:
      hierarchyController:
        enabled: true
        # Set to true to enable hierarchical observability:
        enablePodTreeLabels: true
      # ...other fields...
    
  3. 構成を適用します。

    kubectl apply -f config-management.yaml
    

    約 1 分後に、Hierarchy Controller と階層型オブザーバビリティがクラスタで使用可能になります。

階層型オブザーバビリティが有効になっている場合、Hierarchy Controller は変更用アドミッション Webhook をインストールして、ツリーラベルを Pod に追加します。この Webhook が正しく動作していることを確認するには:

  1. 次のような任意の名前空間でワークロードを開始します。

    kubectl run websvr --image=nginx --namespace default --generator=run-pod/v1
    
  2. Pod を調べて、default.tree.hnc.x-k8s.io/depth ラベルが含まれていることを確認します。

    kubectl describe pod --namespace default websvr
    

    出力:

    Name:         websvr
    Namespace:    default
    # ...other fields...
    Labels:       default.tree.hnc.x-k8s.io/depth=0 # This is the Pod tree label
                  # ...other labels...
    # ...other fields...
    
  3. ワークロードをクリーンアップします。

    kubectl delete pod --namespace default websvr
    

既存の Pod は Pod ツリーラベルを受信しません。Pod ツリーラベルは新しい Pod にのみ追加されます。詳細については、このドキュメントで後述する制限事項をご覧ください。

階層型ワークロード オブザーバビリティの使用

Pod のツリーラベルが有効になると、クラスタ内と他の Google Cloud プロダクト内の両方で階層型ワークロードのオブザーバビリティが向上します。

階層別の Pod のクエリ

Pod のツリーラベルのクエリに、ラベルセレクタを含む Kubernetes オペレーションを使用できます。たとえば、default 名前空間の子孫で実行されているすべての名前空間の Pod をすべて表示するには、次のクエリを使用します。

kubectl get pods --all-namespaces -l default.tree.hnc.x-k8s.io/depth

インストールを確認するために作成したサンプル ワークロードに基づく出力。

NAMESPACE   NAME     READY   STATUS    RESTARTS   AGE
default     websvr   1/1     Running   0          70s

階層別の Cloud Logging のクエリ

Cloud Logging では、Kubernetes とは少し異なる形式のラベルがサポートされています。たとえば、Kubernetes ラベル default.tree.hnc.x-k8s.io/depth ではなく default 名前空間の子孫で実行されているワークロードを検索するには、Cloud Logging は、Google Cloud Console の次のクエリに類似したクエリを想定します。

resource.type="k8s_container" labels.k8s-pod/default_tree_hnc_x-k8s_io/depth!=""

gcloud コマンドライン ツールで同様のフィルタを使用することもできます。

gcloud logging read "resource.type=k8s_container AND labels.k8s-pod/default_tree_hnc_x-k8s_io/depth!=''"

階層別の GKE 使用状況測定のクエリ

Pod ツリーラベルを使用すると、GKE 使用状況測定のリクエストと使用状況を名前空間ツリーに起因すると考えることができます。階層的な使用状況測定を有効にするには:

  1. クラスタで定期的な GKE 使用状況測定を有効にします

  2. データが BigQuery に取り込まれていることを確認します。Cloud Console で BigQuery に移動します。

    BigQuery に移動

  3. gke_cluster_resource_consumption の検出結果について確認します。

  4. GKE 使用状況測定の可視化を有効にするには、GKE クラスタ使用状況測定の有効化の前提条件セクションをご覧ください。

  5. Google データポータルを開いて [Blank Report] をクリックし、データソースとして [BigQuery] を選択します。

  6. [Custom query] を選択して、プロジェクト ID を検索します。右側のテキスト ボックスに、カスタマイズされたクエリを入力します。カスタムクエリの例については、次のセクションをご覧ください。

例: すべてのサブツリーの合計使用量

次のクエリによって、クラスタ内のすべての正規名前空間、抽象名前空間、階層名前空間、およびそのすべての子孫の使用量が返されます。

SELECT
  REGEXP_EXTRACT(label.key, r"^[a-zA-Z0-9\-]+") as subtree,
  resource_name,
  usage.unit,
  SUM(usage.amount) AS usage_amount
FROM
  `PROJECT_NAME.DATASET_NAME.TABLE_NAME`,
  UNNEST(labels) AS label
WHERE
  regexp_contains(label.key, "tree.hnc.x-k8s.io/depth")
GROUP BY
  subtree,
  resource_name,
  usage.unit
ORDER BY
  resource_name ASC,
  subtree ASC

部分的な出力例:

サブツリー リソース名 unit 使用量
a CPU 0.09
a1 CPU 0.09
a2 CPU 0
a メモリ バイト秒 6,315,303,690,240
a1 メモリ バイト秒 1,355,268,587,520
a2 メモリ バイト秒 4,960,035,102,720

この例では、名前空間 a に起因する使用量にはその子孫の名前空間 a1a2 の使用量が含まれています(これらも表示されています)。

例: 1 つのサブツリーの使用量

次のクエリによって、名前空間 a とその子孫のすべての名前空間の合計使用量が表示されます。

SELECT
  resource_name,
  usage.unit,
  SUM(usage.amount) AS usage_amount
FROM
  `PROJECT_NAME.DATASET_NAME.TABLE_NAME`,
  UNNEST(labels) AS label
WHERE
  label.key="SUBTREE_NAME.tree.hnc.x-k8s.io/depth"
GROUP BY
  resource_name,
  usage.unit

名前空間 a の出力例:

リソース名 unit 使用量
CPU 0.09
メモリ バイト秒 6,315,303,690,240

例: サブツリー内のすべての名前空間の使用量

次のクエリは、特定のサブツリー内のすべての名前空間の個別の使用量を表示します。

SELECT
  namespace,
  resource_name,
  SUM(usage.amount) AS usage_amount
FROM
  `PROJECT_NAME.DATASET_NAME.TABLE_NAME`,
  UNNEST(labels) AS label
WHERE
  label.key="SUBTREE_NAME.tree.hnc.x-k8s.io/depth"
GROUP BY
  namespace,
  resource_name

名前空間 a の出力例:

名前空間 リソース名 使用量
a2 メモリ 4,960,035,102,720
a1 メモリ 1,355,268,587,520
a2 CPU 0
a1 CPU 0.09

名前空間 a 自体には使用量はないため、このクエリの結果には表示されません。

階層型モニタリングの制限事項

階層型モニタリングには以下の制約があります。

階層への変更は無視される

Pod ツリーラベルは、Pod の作成時に追加されます。Pod の実行後には変更されません。つまり、階層型モニタリングが有効になる前に開始された Pod は、Pod のツリーラベルを受信しません。

さらに、起動後に階層が変更された Pod(Hierarchy Controller を使用して名前空間の親を変更した場合)のラベルは更新されません。通常、階層への変更は非常にまれですが、変更によって問題が発生した場合は、階層の変更後に影響を受けた Pod をすべて再起動します。

ラベルを適用できなくても Pod が作成される

階層型モニタリングは、kube-systemhnc-system などの主要なシステム名前空間で実行されている Pod には適用されません。ただし、Webhook の構成自体には、これらの名前空間を除外する方法はありません。したがって、Hierarchy Controller で問題が発生した場合、すべての名前空間で Pod の作成に影響が及ぶ可能性があります。

そのため、Hierarchy Controller が 2 秒以内に Pod を処理できない場合、Webhook はクラスタ全体が停止するリスクを回避するため失敗し、Pod がラベルなしで作成されます。このような Webhook の失敗はpodlabel.hierarchycontroller.configmanagement.gke.io 変更用アドミッション Webhook の失敗の有無を探すことで、Kubernetes API サーバーを介してモニタリングできます。

次のステップ