DevOps & Platform Eng

Kubernetes 1.36:Podリソースマネージャー登場(アルファ版)

Kubernetes v1.36は、新しいアルファ機能であるPod-Level Resource Managersにより、リソース管理に大きな変革をもたらす。この変更は、Kubernetesをコンテナ中心の割り当てから、より柔軟でPod中心のアプローチへと移行させるものだ。

{# Always render the hero — falls back to the theme OG image when article.image_url is empty (e.g. after the audit's repair_hero_images cleared a blocked Unsplash hot-link). Without this fallback, evergreens with cleared image_url render no hero at all → the JSON-LD ImageObject loses its visual counterpart and LCP attrs go missing. #}
Kubernetes v1.36:Pod単位でリソース制御が賢くなる — DevTools Feed

Key Takeaways

  • Kubernetes v1.36は、Pod中心のリソース割り当てを可能にするアルファ機能としてPod-Level Resource Managersを導入した。
  • この機能により、特定のコンテナに排他的なNUMAアライメントリソースを割り当てつつ、他のコンテナがPodレベルのプールを共有するハイブリッドリソースモデルが可能になる。
  • 新しいマネージャーは、MLトレーニングや低遅延データベースのような要求の厳しいワークロードのリソース効率とパフォーマンス予測可能性を向上させることを目指している。

そもそもKubernetesというのは、巨大なシステムだ。そして、その巨大なシステムを管理すること、特にMLトレーニングファーム、超低遅延トレードシステム、あるいは文字通り呼吸しているようなデータベースといった、パフォーマンスがクリティカルなワークロードの話になると、常に繊細なダンスを強いられてきた。予測可能なパフォーマンスが欲しい。そのためには、メインイベントのために排他的で、NUMAアライメントされたリソースを切り出す必要がある。しかし、Podはもはや孤独な単一コンテナではない。それらはエコシステムなのだ。ロギング、モニタリング、サービスメッシュ、データインジェストのためのサイドカー――あらゆるものが揃っている。

歴史的に、プライマリーアプリケーションのためにそれらの純粋で排他的なリソースを確保するには、すべてを捧げる必要があった。Pod内のすべてのコンテナが、専用の整数CPUスライスを割り当てられていた。無駄か?Absolutely。特にCPUをほとんど消費しない小さなメトリクスエクスポーターにとっては。もしその厳格な割り当てをスキップすれば、Podの貴重なGuaranteed Quality of Service (QoS) クラスを放棄することになり、それと同時に、一貫したトップクラスのパフォーマンスの希望も失うことになった。要求の厳しいアプリケーションを実行する者にとっては、まさにソフィーの選択だった。

新たな希望:Podレベルマネージャーの登場

しかし、Kubernetes v1.36は、Pod-Level Resource Managersのアルファ版導入によって、状況を動かしている。これは単なる微調整ではない。kubeletのTopology Manager, CPU Manager, Memory Managerの機能を拡張する、根本的なアーキテクチャシフトなのだ。ビッグニュースは?これらが.spec.resourcesでPodレベルのリソース仕様をサポートするようになったことだ。我々は、厳格なコンテナごとの割り当てモデルから、明らかにPod中心のモデルへと移行している。

これらの新しいフィーチャーゲート(PodLevelResourceManagersPodLevelResources)を有効にすることで、kubeletはハイブリッドリソース割り当てモデルをオーケストレーションできるようになる。これにより、要求の少ないコンパニオンにCPUコアを浪費することなく、スターパフォーマーのためにNUMAアライメントと排他的リソース割り当てを実現できる。柔軟性と効率性が、ついに融合したのだ。

実世界のシナリオ:ゴムがNUMAに当たる場所

この新しいアプローチの美しさは、実用的なユースケースで輝く。それはTopology Managerのスコープ設定に大きく依存する。レイテンシに敏感なデータベースPodを考えてみよう。メインコンテナ、ローカルメトリクスエクスポーター、バックアップエージェントサイドカーがすべて含まれている。

Topology Managerをpodスコープで設定した場合、kubeletはPod全体の |リソース予算に基づいて単一のNUMAアライメントを実行する。クリティカルなデータベースコンテナは、その特定のNUMAノードから排他的なCPUおよびメモリのスライスを掴む。残りは?それはpod共有プールを形成する。ここにメトリクスエクスポーターとバックアップエージェントが配置される。それらは互いにリソースを共有するが、決定的なのは、それらがデータベース専用スライスやノードの他の部分から分離されていることだ。これは大きい。補助コンテナを同じNUMAノードに配置しながら、専用コアを無駄にすることがないのだ。

pod Topology Managerスコープで設定した場合、kubeletはPod全体の |予算に基づいて単一のNUMAアライメントを実行する。データベースコンテナは、そのNUMAノードから排他的なCPUおよびメモリのスライスを取得する。Podの |予算からの残りのリソースが、新しいpod共有プールを形成する。

YAMLでの表示は次のようになるだろう:

apiVersion: v1
kind: Pod
metadata:
  name: tightly-coupled-database
spec:
  # Podレベルのリソースが、全体的な |予算とNUMAアライメントサイズを確立する。
  resources:
    requests:
      cpu: "8"
      memory: "16Gi"
    limits:
      cpu: "8"
      memory: "16Gi"
  initContainers:
  - name: metrics-exporter
    image: metrics-exporter:v1
    restartPolicy: Always
  - name: backup-agent
    image: backup-agent:v1
    restartPolicy: Always
  containers:
  - name: database
    image: database:v1
    # このGuaranteedコンテナは、Podの |予算から排他的な6CPUスライスを取得する。
    # 残りの2CPUと4Giメモリは、サイドカーのためのpod共有プールを形成する。
    resources:
      requests:
        cpu: "6"
        memory: "12Gi"
      limits:
        cpu: "6"
        memory: "12Gi"

あるいは、インフラストラクチャサイドカーを持つMLワークロードを考えてみよう。ここでは、おそらくcontainer Topology Managerスコープを重視するだろう。kubeletは各コンテナを個別に評価する。最大パフォーマンスを求めるMLトレーニングコンテナは、排他的でNUMAアライメントされたCPUとメモリを受け取る。サービスメッシュサイドカーは?特別な扱いは必要ない。ノード全体の共有プールで問題なく動作する。 |リソース消費の総量は依然としてPod全体の |制限によって |制限されるが、排他的でNUMAアライメントされたリソースは、本当に必要な場所にのみ、賢く適用されている。

apiVersion: v1
kind: Pod
metadata:
  name: ml-workload
spec:
  # Podレベルのリソースが、全体的な |予算の制約を確立する。
  resources:
    requests:
      cpu: "4"
      memory: "8Gi"
    limits:
      cpu: "4"
      memory: "8Gi"
  initContainers:
  - name: service-mesh-sidecar
    image: service-mesh:v1
    restartPolicy: Always
  containers:
  - name: ml-training
    image: ml-training:v1
    # 'container'スコープの下では、このGuaranteedコンテナは排他的な
    # NUMAアライメントされたリソースを取得し、サイドカーはノードの共有プールで実行される。
    resources:
      requests:
        cpu: "3"
        memory: "6Gi"
      limits:
        cpu: "3"
        memory: "6Gi"

CPUクォータと分離の技術

分離が鍵であり、これらの混合ワークロードでは異なって処理される。排他的なCPUスライスを取得するコンテナの場合、CPU CFSクォータ強制はコンテナレベルで無効になる。これは、カーネルのCompletely Fair Scheduler (CFS) によって通常課されるスロットリングなしで動作することを意味し、無制限にバーストおよびパフォーマンスを発揮できることを保証する。

排他的なCPUスライスを取得しないコンテナは、Podレベルの共有プールまたはノード全体共有プールのいずれかに属する共有プールの一部となる。これらのコンテナにはCFSクォータ強制が有効になる。それらはCFSスケジューリングポリシーに従ってリソースを共有する。これは、暴走プロセスが必須プロセスを飢えさせないように設計された微妙なシステムでありながら、ハイリスクなアプリケーションに専用レーンを提供している。

根本的なシフト:コンテナからPodへ

Podレベルのリソース管理へのこの移行は、単なる最適化以上のものである。これはKubernetes内の哲学的なシフトだ。長年、スケジューリングとリソース割り当ての基本単位はコンテナだった。この新しい機能は、現代のアプリケーションがしばしばPod内で分散されており、それらの分散コンポーネントを統一されたユニットとして管理することが、パフォーマンスと効率性のために重要であることを認識している。それは、Podを独立したプロセスの集まりとしてではなく、単一の、しかし複雑なアプリケーションインスタンスとして扱うことなのだ。

これは、高性能アプリケーションの設計とデプロイ方法に魅力的な可能性を開く。個々のコンテナのリソースニーズを綿密に計算し、QoSへの影響と格闘する代わりに、Pod全体の |リソースフットプリントを定義し、その |予算内でインテリジェントに委任できるようになる。運用が合理化され、さらに重要なことに、パフォーマンスのペナルティなしで、よりタイトな |リソース利用が可能になる。これはFinOpsチームと、それらの捉えどころのないパフォーマンスメトリクスを追いかけるエンジニアにとっての勝利だ。

開発者とオペレーターにとっての意味

開発者にとっては、複雑なPodのリソース要件を指定するための、より直感的な方法を意味する。パフォーマンスがクリティカルなコンポーネントとそのサポートキャストを明確に区別できる。オペレーターにとっては、ノードの利用効率の向上と、潜在的なコスト削減につながる。なぜなら、メインアプリケーションのQoSを維持するためだけに、サイドカーのためにリソースを過剰にプロビジョニングする必要がなくなるからだ。これは、Kubernetesを最も要求の厳しいワークロードにとって、より実行可能なプラットフォームにするための重要な一歩だ。

もちろん、これはアルファ版だ。荒削りな部分、変更、そして当然ながら、成熟するにつれてさらなる掘り下げた質問が予想される。しかし、方向性は明確だ。Kubernetesは、基盤となるハードウェアの有限なリソースをどのように割り当てるかについて、より賢くなっている。そして、それは注目に値する進歩だ。


🧬 関連インサイト

Jordan Kim
Written by

Cloud and infrastructure correspondent. Covers Kubernetes, DevOps tooling, and platform engineering.

Worth sharing?

Get the best Developer Tools stories of the week in your inbox — no noise, no spam.

Originally reported by Kubernetes Blog