Upgrade to Pro — share decks privately, control downloads, hide ads and more …

NUMA環境とコンテナランタイム ― youki における Linux Memory Poli...

Avatar for n4mlz n4mlz
November 19, 2025

NUMA環境とコンテナランタイム ― youki における Linux Memory Policy 実装

OCI Runtime Specに新規追加されたLinux Memory Policy機能を、Rust製コンテナランタイムyoukiに実装した事例を紹介します。NUMA環境でのメモリ配置制御の仕組み、実装上の課題、runcとの整合性、そして初めてのOSSコントリビュート経験から得た知見を共有します。

Avatar for n4mlz

n4mlz

November 19, 2025
Tweet

More Decks by n4mlz

Other Decks in Programming

Transcript

  1. contents はじめに 01 02 03 Linux Memory Policy とは youki

    への実装 youki のテスト環境と Memory Policy 特有の悩み 04 05 おわりに 目次
  2. はじめに 01 話すこと 先日、OCI Runtime Spec に新たに Linux Memory Policy

    に関する仕様が追加された 追加された新しい仕様を Rust 製コンテナランタイム youki に実装した経験を共有したい 実は人生初の OSS コントリビュート (注: まだマージされていないです) PR: https://github.com/youki-dev/youki/pull/3230
  3. はじめに 01 この発表で得られること NUMA / UMA のかんたんな概要 仕様の決定から実際にランタイムに実装するまでの過程 実装する上で感じた Memory

    Policy 特有の大変さ 人生初の OSS コントリビュート経験を、これから OSS に関わっていく方への一例として提供
  4. NUMA: Non-uniform Memory Access 「CPU+ローカルメモリ」 を持つ複数のノードによって構成されるアーキテクチャ メモリアドレス空間は同一なので他のノードのメモリにも同様にアクセスできる しかし 「遠いノードのメモリにアクセスするとレイテンシが伸びる」 という特徴

    データセンターおよびエンタープライズ環境など 大規模データベースやHPC等 (普通の PC は基本的に UMA) Linux Memory Policy とは 02 UMA と NUMA https://www.designworldonline.com/what-is-non-uniform-memory-access-in-industrial-controls/
  5. Linux Memory Policy とは 02 Memory Policy とは? プロセスに対し「どのノードからメモリを割り当てるか」を OS

    に指示する仕組み set_mempolicy() システムコールにより設定する NUMA 環境では、どのノードからメモリを割り当てるかによって性能が大きく変わる OCI Spec で規定される Memory Policy OCI Runtime Spec に新たに追加された linux.memory_policy フィールド コンテナのプロセスがどのような Memory Policy を使用するかを指定する 基本的には、 linux.memory_policy に書かれた内容を使って適切なタイミングで set_mempolicy() を呼べばよい
  6. youki への実装 03 パーサーでの Memory Policy サポート OCI Runtime Spec

    には Go の構造体定義がある runc (Go) はこれをそのまま利用している youki (Rust) では oci_spec_rs という OCI Spec パーサーを別リポジトリで用意 まずはここに新しい Memory Policy の構造体定義を追加した https://github.com/youki-dev/oci-spec-rs/pull/290 https://github.com/youki-dev/oci-spec-rs/pull/292
  7. youki への実装 03 set_mempolicy() を呼ぶ パースした Memory Policy の情報をもとに コンテナ起動時に

    set_mempolicy() を呼び出す ここまではそんなに難しくない このへんで set_mempolicy() を呼ぶ 引用: https://github.com/youki-dev/youki
  8. モードとフラグが多すぎる モード, フラグ: set_mempolicy() の引数のひとつ モードの例: MPOL_DEFAULT, MPOL_BIND, MPOL_INTERLEAVE, MPOL_WEIGHTED_INTERLEAVE,

    MPOL_PREFERRED, MPOL_PREFERRED_MANY, MPOL_LOCAL フラグの例: MPOL_F_STATIC_NODES, MPOL_F_RELATIVE_NODES, MPOL_F_NUMA_BALANCING 本当に大変だったもの: テスト 04 オプション多すぎ問題 https://man7.org/linux/man-pages/man2/set_mempolicy.2.html
  9. 指定するノードの集合 (nodemask) が必須 / 任意 / 空でないといけない など 排他的なフラグ 一部の

    mode でのみ有効なフラグ フラグの指定によって同じ引数でも解釈方法が変わる エラーとして落とす例: MPOL_DEFAULT なのに nodemask が空でない、 MPOL_BIND または MPOL_INTERLEAVE なのに nodemask が空 MPOL_F_STATIC_NODES と MPOL_F_RELATIVE_NODES を同時指定 (これらは排他的) MPOL_F_NUMA_BALANCING を MPOL_BIND 以外のモードで指定 等々... 本当に大変だったもの: テスト 04 他の引数との組み合わせ・制約が複雑 テスト項目が本当に多い
  10. youki のテスト環境とMemory Policy 特有の悩み 04 CI 環境で NUMA に関するテストはどうする? NUMA

    環境でしかテストできないケースがあるのに CI は UMA UMA 環境では Memory Policy の効果が確認できない 確認できるテストに限りがある どこまでテストで確認するか、runc がどうしているのか比較 runc の CI Test は UMA のもののみであった CI のテストは割り切って runc と同様 UMA のみ検証しつつ、NUMA のテストも用意する テストは UMA 用/NUMA 用両方用意し、CI では NUMA 用をスキップ
  11. おわりに 05 この体験を通して得られたこと syscall 一つ呼ぶだけじゃん! と思っていたが、思ったより規模が大きく大変だった 仕様を読むだけでは見えない地雷が実装時に大量に出てくる テストの粒度と実装量のトレードオフ、他の実装 (runc) との比較など

    OSS ならではの悩み OSS コントリビュートのすすめ 新しい仕様の追加は「最初の実装者」になれるチャンス コードの品質や設計に関して多くのフィードバックをいただき、非常に勉強になった