freeeの開発情報ポータルサイト

KubeCon + CloudNativeCon Japan 2025 - 参加レポ Never Underestimate Memory Architecture/No More Disruption: PlayStation Network’s Approaches To Avoid Outages on Kubernetes Platform

KubeCon + CloudNativeCon Japan 2025 参加レポ 4 日目を担当する SRE の kamimuu と申します。 freee では新規マイクロサービスの構築支援やマルチ AWS アカウント環境の運用を担当しています。

本記事では私が興味を惹かれた以下 2 つのセッションを紹介します。

  • Never Underestimate Memory Architecture - Bryan Boreham, Grafana Labs
  • No More Disruption: PlayStation Network’s Approaches To Avoid Outages on Kubernetes Platform - Tomoyuki Ehira & Shuhei Nagata, Sony Interactive Entertainment

Never Underestimate Memory Architecture - Bryan Boreham, Grafana Labs

セッション資料

youtu.be

概要

Kubernetes (以降 K8s と表記) 環境下での NUMA との上手な付き合い方について、K8s の NUMA 対応状況を交えて紹介するセッションでした。 NUMA に関する設定を適切に施した場合の CPU に関するメトリクスのグラフを参照しながらお話が進んだため、 K8s での NUMA の有効性を肌で感じることができる学びの多い内容でした。

NUMA とは

昨今のクラウドサーバーは NUMA (Non-Uniform Memory Access) と SMT (Symmetric Multi-Threading, aka Hyperthreading) 上に構築されています。 NUMA アーキテクチャ環境下では CPU から遠い距離に配置されたメモリへのアクセスレイテンシーが高くなります。

下図中の左上の CPU コアについて考えてみます。左上の CPU コアは Hyperthreading が有効化されており、 2 スレッド (図中では赤色の四角形と緑色の四角形で表現) を持つと仮定します。左上の CPU コア内に存在するスレッド (赤色の四角形) から右上の CPU コアに接続されたメモリー (赤色の四角形で表現されている) にアクセスする場合がメモリアクセスのレイテンシーが高い状況になります。対して、左上の CPU コア内に存在するスレッド (緑色の四角形) から左上の CPU コアに接続されたメモリー (緑色の四角形で表現されている) にアクセスする場合はメモリアクセスのレイテンシーが低い状況になります。

NUMA (Non-Uniform Memory Access) と SMT (Symmetric Multi-Threading, aka Hyperthreading) の説明スライド (セッションスライド 15 ページより引用)。CPU の 1 つのコアは複数スレッドを持つ (これは SMT として知られている) 。また、昨今の CPU はマルチコア構成となっていることが多い。 CPU はコアごとに個別のローカルメモリーを持っており、 CPU コアに直結するローカルメモリーアクセス時のレイテンシーは最小になるように設計されている。このような設計の都合上、ある CPU コアから異なる CPU コアと直結するローカルメモリーへのアクセスはレイテンシーが高くなってしまう。このような特性は共有メモリ型マルチプロセッサコンピュータシステムと表現され、 NUMA と呼ばれる。
NUMA (Non-Uniform Memory Access) と SMT (Symmetric Multi-Threading, aka Hyperthreading) (セッションスライド 15 ページより引用)

クラウドサーバー利用者が意識することはほとんどありませんが、メモリアクセスのレイテンシーを意識したチューニングを行う際は NUMA アーキテクチャーに気を配って Linux カーネルパラメータ等を設定する必要があります。

NUMA の観点で調査する方法

利用しているクラウドサーバー (セッション中では AWS EC2 を例に挙げていました) を NUMA の観点で調査する方法もいくつか紹介されていました。

実稼働しているクラウドサーバーが NUMA の影響を受けているかどうかは Prometheus Metrics を使うと観察できます。

NUMA に関する Prometheus Metrics を示す説明スライド (セッションスライド 20 ページより引用)。 zoneinfo コレクターが有効化された node-exporter (Prometheus exporter の一種) から収集できるメトリクスの内、 node_zoneinfo_numa_other_totalvs と node_zoneinfo_numa_local_total が NUMA に関する Prometheus Metrics に相当する。
NUMA に関する Prometheus Metrics (セッションスライド 20 ページより引用)

利用しているクラウドサーバーの NUMA の特徴を知る方法 (lscpu) も紹介されていました。

クラウドサーバー上での lscpu 実行例を示す説明スライド (セッションスライド 23 ページより引用)。 lscpu コマンドを EC2 等のクラウドサーバー上で実行すると、 CPU に対して設定された NUMA に関する情報を取得することができる。
クラウドサーバー上での lscpu 実行例 (セッションスライド 23 ページより引用)

利用しているクラウドサーバーが Intel CPU の場合は、 Intel が提供している Profiler を使って調査することもできます。 Intel CPU を採用している AWS EC2 インスタンスタイプごとに利用できる Profiler についての情報は Intel® VTune™ Profiler Functionality on AWS* Instances にて公開されています。

また、本セッションでは述べられていませんが、 AWS EC2 インスタンスに対して NUMA 関連の調査を行う際に参考になるページを著者の方でいくつか見つけましたので、こちらもご紹介します。

K8s の NUMA 対応

NUMA の観点では低いスペックのノード (NUMA node が少なく CPU とメモリ間のデータ転送が容易) を並べる方が良いですが、 K8s という観点では利用するノード数を多くすると Kubelet 等に起因するオーバーヘッドが発生します。 NUMA を意識した Pod のスケジューリングを行うために、 --cpu-manager-policy Kubelet フラグと --topology-manager-policy Kubelet フラグが 利用できます。

CPU Manager で利用できる NUMA に関するオプションを示す説明スライド (セッションスライド 37 ページより引用)。 Kubelet 起動時に CPU 割り当てを NUMA 境界で調整するための --cpu-manager-policy フラグを指定することができる。
CPU Manager で利用できる NUMA に関するオプション (セッションスライド 37 ページより引用)

Topology Manager で利用できる NUMA に関するオプションを示す説明スライド (セッションスライド 38 ページより引用)。Kubelet 起動時に指定できる --topology-manager-policy フラグに scope=pod と policy=single-numa-node を与えることで NUMA に関するオプションを有効化できる。
Topology Manager で利用できる NUMA に関するオプション (セッションスライド 38 ページより引用)

Kubelet は Pod 配置の際はデフォルトでは CFS quota を参照します。これを変更するために --cpu-manager-policy フラグが利用されます。 K8s の NUMA 対応の改良は進んでおり、 uncore (CPU の L3 cache 等) に起因するレイテンシーを避けるためのオプションとして prefer-align-cpus-by-uncorecache (alpha, hidden by default) (1.32 or higher) が用意されています。ただしこのオプションは --cpu-manager-policy=static を Kubelet フラグとして指定した場合にのみ利用可能です。

K8s v1.32 にて alpha status で追加される CPU Manager の uncore オプションを示す説明スライド (セッションスライド 42 ページより引用)
K8s v1.32 にて alpha status で追加される CPU Manager の uncore オプション (セッションスライド 42 ページより引用)

また、Q&A にて、アプリレベルで CPU に関する設定の重要さも触れられていました。例として Go 1.25 で導入される Container-aware GOMAXPROCS が挙げられていました。

本レポート記載の際に参照した資料

No More Disruption: PlayStation Network’s Approaches To Avoid Outages on Kubernetes Platform - Tomoyuki Ehira & Shuhei Nagata, Sony Interactive Entertainment

セッション資料

youtu.be

概要

PlayStation Network にて 99.995% の uptime を維持するために構築した内製コンテナプラットフォームの沿革ついて紹介するセッションでした。内製コンテナプラットフォームの構築に際して施した工夫を K8s とチーム体制の観点から説明がありました。

Sony Interactive Entertainment 社におけるコンテナプラットフォームを示す説明スライド (セッションスライド 7 ページより引用)。 AWS EKS を利用し、ノード管理には Karpenter を採用している。また、ノード管理に際して論理的な多層構造を設けている。一番下から Policy / Security 層、 Observability / Logging 層、 Other Addons 層、アプリケーションや Core Addons を管理する層の順に並んだ 4 層構造を設けてノード管理対象をグルーピングしている。
Sony Interactive Entertainment 社におけるコンテナプラットフォーム (セッションスライド 7 ページより引用)

遭遇した課題とその解決方法

内製コンテナプラットフォーム構築に際して遭遇した課題とその解決方法を 4 つに分けて紹介していました。個人的に学びが多い内容だったので、述べられていた課題と解決方法について箇条書きで以下に記します。

  • Pod の可用性
    • Disruption を避ける方法
      • 基本的には PDB (Pod Disruption Budget) と PTSC (Pod Topology Spread Constraints) を用いる
      • PTSC を利用していても稼働している Pod が特定ノードに偏るケースはあるので、 Descheduler も利用している
    • 低速なノードの起動により生じるパフォーマンス低下の対策
      • コストが許す範囲で余剰ノードを確保しておき、 Pod の配置を高速化する (Overprovisioning)
      • Karpenter によるノード作成時間の高速化
    • K8s ノードに配布される CoreDNS Pod のチューニング
      • CoreDNS Pod が全ノードにデプロイされるように anti-afiinity を活用
      • CPU スロットリングを避けるために CoreDNS Pod に対する CPU 制限を撤廃
      • デプロイされる CoreDNS Pod 数を固定値にする
        • CoreDNS のオートスケールがうまく働いてくれない状況であるため
          • 改善案がいくつかあるため検討中、とのこと
  • K8s クラスターの運用性
    • アドオンアップグレードを自動化し、クラスターあたりの作業所要時間を 300 分 → 50 分に短縮
    • ノードのアップグレードを安全で予測可能なものにし、オペミスを最小化
      • インタフェースやガードレールの提供
        • サービスチームのマニフェスト設定ミスを防ぐために Helm チャートで標準インタフェースを提供
        • Kyverno ポリシーで不正なマニフェストを混入させるオペミスを防ぐ
      • ノードの再作成に伴うダウンタイムを防ぐために Karpenter を利用
    • クラスターアップグレードがスムーズにできるようにしている
      • Helm チャートの自動更新を通じたクラスターの健全性を維持
        • サービスチームが Helm チャートを利用している設定ファイルに対して PR を自動で作成
        • K8s バージョンアップに伴って廃止された API の利用箇所の排除をプラットフォームが制御できるようになった
  • アーキテクチャ (K8s クラスターに関するリソースの隔離性)
    • 重要な Pod をノード単位で分離する
      • 重要な Pod (Kyverno、 Argo CD、KEDA、Prometheus 等) は占有ノードを利用している。サービス Pod とは分離している。
      • 複雑性の低減や影響範囲の最小化のためにクラスターを分離する
        • PCI コンプライアンス等の特別な要件を持つアプリケーションを分離する
        • Agones のような運用が複雑なアプリケーションは占有クラスターを用意する
          • Agones は API サーバーに負荷をかけるため、他のアプリケーションへ影響を及ぼし得る
          • Agones は特殊なアップグレード戦略を必要とする
  • 組織運営
    • Follow the Sun 体制 (8 時間ごとにアメリカ、日本、インドの 3 チームで運用作業をできる体制) を構築した
    • 複数タイムゾーンでの体制構築のために以下も行った
      • ナレッジ共有セッションを用意した
      • Kyverno ポリシーで意図しない運用作業を防いだ
      • ドキュメントの拡充
        • ADR (Architecture Decision Record)、 Runbook、 FMEA (Failure Mode and Effects Analysis)

最後に

筆者は KubeCon に初めて参加しましたが、 K8s を利用する立場や K8s 仕様を策定する立場を問わずに多くの属性の方々が参加しており非常に面白く感じました。K8s 仕様に関するセッションでは内容を熟知している参加者も多く、セッションの最後の Q&A の時間では発表内容から更に踏み込んだ展望を問うハイレベルな質問が交わされていました。

また、 Platform Engineering 等の文脈で実組織における運用知見を共有することも K8s のエコシステムにおいて重要視されており、 Day 2 オペレーションに関するセッションも多く見られました。 Keynote で KubeCon はオープンソースに関するカンファレンスであることが強く強調されていましたが、オープンソースを活用する企業の利用事例も K8s エコシステムへの貢献としてみなされているように感じられるセッションも多々ありました。個人的にはオープンソースに対する貢献を指す活動の多様性を再認識できる良い機会でした。