解決できる課題 事業紹介トップ 経営データ分析基盤 AI導入・業務改善 AI 業務アプリ 基幹システムのWeb化・段階移行 複雑な SaaS を専用 UI に Shopify Plus 移行・拡張 生成AI 活用(Multi AI) SEO / AIO / 広告運用 顧問・アドバイザリ インフラ構築 自社メディア投資・開発
AI導入 AI導入・業務改善 ChatGPTの社内導入 OpenAI Codex導入 AI運用・定着 Claude / MCP 総合 Claude Cowork Claude Code 導入支援 Claude Code 使いこなし支援 Claude Design MCP 開発・サーバー構築
EC構築・移行 Shopify Plus トップ EC-CUBE からの移行 大手カートからの移行 Shopify 通常プラン EC サイト構築
実績
業界ニュース 業界ニュース トップ AI ニュース └ Claude └ ChatGPT・Codex └ Gemini └ その他 Shopify ニュース SaaS ニュース お知らせ(自社発信)
会社情報 相談する
2026.10.02

kube-state-metrics で Deployment Sharding を採用した理由(Neco の事例)

記事のサマリー(TL;DR)

  • サイボウズのクラウド基盤 Neco では、kube-state-metrics(KSM)が扱うリソース数・メトリクス量の増加により取得時間が増え、必要な監視粒度を維持できなくなる懸念があったため、メトリクスを削除せずにシャーディング(分割)する方法を検討しました。
  • KSM の公式ドキュメントが示す「API サーバーから取得するリソースを絞り込む方法(DaemonSet Sharding)」と「取得したリソースのうちメトリクスに変換する対象を絞り込む方法(Horizontal Sharding:Deployment Sharding / Automated Sharding)」を比較しています。
  • 各方式にはそれぞれデメリットがあり、Neco では「更新・再起動中のメトリクス欠損を抑える」「ノード障害時も別ノードから状態を収集できる」ことを重視し、Deployment Sharding を採用しました。

詳細

kube-state-metricsとは

kube-state-metrics(以後、KSM)は、Kubernetes の API サーバーから Pod などのリソースを取得し、その情報をメトリクスへ変換するコンポーネントです。メトリクスは KSM Pod の /metrics にアクセスすることで取得できます。

例えば、以下のようなメトリクスが生成されます。

kube_pod_status_phase{namespace="argocd",pod="argocd-server-5f898b9cbc-4pbbx",...,phase="Running"} 1
kube_pod_info{namespace="argocd",pod="argocd-server-5f898b9cbc-4pbbx",...,pod_ip="10.244.1.7",node="kind-cluster-worker2",...} 1
kube_deployment_status_replicas{namespace="argocd",deployment="argocd-server"} 1
kube_deployment_status_replicas_ready{namespace="argocd",deployment="argocd-server"} 1

kube_pod_status_phase メトリクスからは Pod argocd-server-5f898b9cbc-4pbbx が Running 状態であることが分かります。また kube_pod_info メトリクスからは IP アドレスや稼働する Node などの情報が確認できます。kube_deployment_status_replicas と kube_deployment_status_replicas_ready メトリクスからは、argocd-server Deployment のレプリカ数が1であり、それが Ready であることが分かります。

このように KSM を利用することで、Pod や Deployment、Node など Kubernetes が扱うリソースの情報をメトリクスとして取得できます。

シャーディングを検討した背景

Neco では従来、1つの KSM ですべてのリソースのメトリクスを扱っていました。Neco の進化とともにクラスタ内のリソース数が増え、扱うメトリクス量も増加していました。メトリクス量が増えると取得にかかる時間も増加し、取得時間が長くなると短い間隔でのメトリクス収集が難しくなり、必要な監視粒度を維持できなくなる可能性がありました。

対応策として不要なメトリクスを削除することも考えられますが、Neco ではすでに多くの利用者が KSM のメトリクスを利用しており、削除候補の洗い出しや使用状況調査、安全な削減には大きなコストがかかる作業でした。そこで、利用者に提供するメトリクスは維持したまま、KSM Pod が扱うメトリクスをシャーディングして取得時間を短縮する方法を検討しました。

KSM の公式ドキュメントに記載されているシャーディングの方法は、大きく次の2つに分けられます。

  • 方法1:Kubernetes API サーバーから取得するリソースを絞り込む
  • 方法2:取得したリソースのうち、メトリクスに変換する対象を絞り込む

方法1:Kubernetes API サーバーから取得するリソースを絞り込む

KSM には収集対象のリソースを指定する --resources オプションがあり、デフォルトの収集対象は DefaultResources で定義されています。このオプションを利用すると、API サーバーから取得するリソースを絞り込めます。

さらに --resources オプションに Pod のみを指定した場合(Pod 以外を指定すると Validate メソッドで弾かれます)は --node オプションも利用でき、指定した Node 上で稼働する Pod に限定できます(この方法では Pod のメトリクスしかシャーディングできません)。

--resources オプションと --node オプションを活用したシャーディングは、KSM のドキュメントでは DaemonSet Sharding として紹介されています。設定は次のような Manifest です。

apiVersion: apps/v1
kind: DaemonSet
spec:
  template:
    spec:
      containers:
      - image: registry.k8s.io/kube-state-metrics/kube-state-metrics:IMAGE_TAG
        name: kube-state-metrics
        args:
        - --resources=pods
        - --node=$(NODE_NAME)
        env:
        - name: NODE_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName

--node と --resources オプションを利用した場合、以下は取得できないため、別途 KSM の設定が必要です。

  • Node が割り当てられていない Pod(スケジューラーが配置先を決める前の Pod)に関するメトリクス
  • Pod 以外のメトリクス

詳細な設定については公式の DaemonSet Sharding の Manifest を参照するよう案内されています。

また、各 Node の KSM がその Node に割り当てられた Pod のメトリクスを担当するため、Node が停止するとその Node 上の Pod とメトリクスを公開する KSM が同時に停止する点にも注意が必要です。そのため、停止した Node に割り当てられた Pod のメトリクスを収集できなくなります。

例えば、ノード障害を Kubernetes のコントロールプレーンが検知すると、その Node に割り当てられた Pod の Ready Condition は False に更新され、次のような kube_pod_status_ready メトリクスで表現されます。

kube_pod_status_ready{pod="foo",...,condition="true"} 0
kube_pod_status_ready{pod="foo",...,condition="false"} 1

しかし、その Node 上の KSM も一緒に停止してしまうと、更新後の Pod の状態をメトリクスとして公開できません。その結果、メトリクスを参照して動作する監視システムから状態変化を観測できなくなる可能性があります。そのため、この構成を採用する場合は、Node 障害時に Pod の異常を示すメトリクスが欠落する可能性を考慮する必要があります。

方法2:取得したリソースのうち、メトリクスに変換する対象を絞り込む

この方法は、KSM のドキュメントでは Horizontal Sharding として紹介されています。仕組みは共通ですが、設定方法には次の2種類があります。

  • Deployment Sharding:各シャードを個別の Deployment として管理する
  • Automated Sharding:複数のシャードを1つの StatefulSet で管理する(現時点では実験的な機能)

Horizontal Sharding の仕組み

Horizontal Sharding は、API サーバーから取得するリソースをいくつかのシャードに分割し、KSM が特定のシャードに所属するリソースをメトリクスとして公開するものです。これにより各 KSM が保持するリソースや /metrics で公開するメトリクス量が分割されるため、メモリ使用量やメトリクス生成処理の負荷は減ります。

各 KSM には次の情報を設定する必要があります。

  • --total-shards:シャードの総数
  • --shard:KSM が担当するシャード番号

KSM は API サーバーから取得したリソースの UID をもとにリソースのシャードを決定し(実際の計算は keep メソッドで行われます)、リソースのシャード番号と KSM が担当するシャード番号が一致した場合にそのリソースを保持しメトリクスとして公開します。

重要な点として、各 KSM が担当するリソースだけを API サーバーから取得するわけではありません。そのため、シャード数を増やしても KSM の1シャードあたりの API サーバーとの通信量が「1 / シャード数」になるわけではありません。

Deployment Sharding

Deployment Sharding では、各シャードを個別の Deployment として配置します。Deployment にすることで新しい Pod を起動してから古い Pod を停止する RollingUpdate を利用できるため、更新中にメトリクスが欠けるリスクを抑えやすいというメリットがあります。

設定方法は、それぞれの KSM Deployment に担当するシャード番号とシャードの総数を明示的に設定します。

containers:
- name: kube-state-metrics
  image: registry.k8s.io/kube-state-metrics/kube-state-metrics:IMAGE_TAG
  args:
  - --shard=0
  - --total-shards=3

各シャードを個別の Deployment として配置する必要があるため、--total-shards=3 の場合、次の3つの設定の Deployment が必要になります。

  • --shard=0 --total-shards=3
  • --shard=1 --total-shards=3
  • --shard=2 --total-shards=3

すべての Deployment で --total-shards を同じ値にし、0 から total-shards - 1 までのシャードを漏れなく設定する必要があります。設定に不整合があると、一部のメトリクスが欠ける可能性があります(シャードに関する設定は kube_state_metrics_shard_ordinal や kube_state_metrics_total_shards などのメトリクスとして公開されているため、これをもとに構成が正しいか確認する仕組みがあると良いとされています)。

Automated Sharding

Automated Sharding は、Deployment Sharding で手動設定していたシャード番号とシャード総数を自動的に決定する方法です(現時点では実験的な機能)。KSM を StatefulSet として配置し、Pod 名と Namespace を --pod と --pod-namespace で渡します。

KSM は StatefulSet から以下の情報を導出します(具体的な処理は shardingSettingsFromStatefulSet メソッドを参照するよう案内されています)。

  • シャードの総数:StatefulSet の replicas
  • シャード番号:Pod 名の末尾にある ordinal

例えば、レプリカ数が3の場合、各 Pod には次のシャードが割り当てられます。

  • kube-state-metrics-0:Shard 0
  • kube-state-metrics-1:Shard 1
  • kube-state-metrics-2:Shard 2

この方法のメリットは、複数のシャードを1つの StatefulSet で管理できる点です。StatefulSet のレプリカ数を変更するだけで、シャードの総数とシャード番号の整合性がとれた構成に自動で更新されるため、Deployment Sharding より構成を管理しやすくなるとされています。

ただし、StatefulSet の RollingUpdate では既存の Pod を削除してから、同じ ordinal を持つ Pod を作り直します。そのため、更新中は特定のシャードを担当する Pod が一時的に存在しなくなります。このタイミングでメトリクスの取得が行われると、そのシャードが担当するメトリクスを取得できず、メトリクスの欠損につながります。

結局どうしたのか

Neco では Deployment Sharding を選択しました。どの方式を選んでもデメリットがあり、各方式のデメリットを比較すると次のようになります。

  • 方法1:Kubernetes API サーバーから取得するリソースを絞り込む
    • DaemonSet Sharding:KSM と収集対象の Pod が同じノードに配置されるため、ノード障害時に Pod の状態変化を収集できない可能性がある
  • 方法2:取得したリソースのうち、メトリクスに変換する対象を絞り込む
    • Deployment Sharding:複数の Deployment 間で、シャード構成の整合性を保つ必要がある
    • Automated Sharding:ローリングアップデート時に、特定のシャードを担当する Pod が一時的に不在となり、メトリクスが欠損する可能性がある

Neco では次の点を重視して Deployment Sharding を採用しました。

  • KSM の更新や再起動中も、メトリクスの欠損をできるだけ防ぐ
  • ノード障害時も、別のノードから Pod の状態を収集できるようにする

Neco では KSM のマニフェストを Jsonnet から生成しており、抽象化された設定からシャード番号とシャード総数を一元的に定義できます。そのため、複数の Deployment 間で設定の整合性を保つことは許容できる範囲であると判断しました。

まとめ

この記事では、KSM が提供する3つのシャーディング方式を比較し、Neco で Deployment Sharding を採用した理由を紹介しました。シャーディング方式を選ぶ際は、単に負荷を分散できるかだけでなく、Node 障害や KSM の更新時にも監視を継続できるか、既存の構成管理へ無理なく組み込めるかを考慮する必要があるとされています。

どの方式にもメリットとデメリットがあり、一概に最適な方式は決められないのが難しい点だったとしています。方式が決まった後は、既存の監視を継続しながらどのように新しい構成へ切り替えるかが次の課題になるとのことで、既存の監視を継続したまま Deployment Sharding へ移行するために検討したことや実際の手順については、機会があれば別の記事で紹介したいとしています。

なお、この記事は CYBOZU SUMMER BLOG FES ’26 の記事であり、AI Influence Level(AIL)は Level 1 と記載されています。