Slide 1

Slide 1 text

AI/MLのマルチテナント基盤 を⽀えるコンテナ技術 Toru Komatsu(@utam0k) Preferred Networks, Inc. 2025年12月1日 ComSys 2025

Slide 2

Slide 2 text

小松 享 / @utam0k ● Preferred Networks, Inc. / エンジニア ○ 社内/社外の AI/ML 基盤の構築と運用 ○ 特にスケジューラやコンテナランタイム ○ エンジニアリングマネージャー ● OSS 活動 ○ youki(CNCF Project) の作者 ○ OCI Runtime Specification メンテナ ○ Kubernetes SIG-Scheduling Reviewer ○ containerd/runwasi Reviwer

Slide 3

Slide 3 text

AI/MLのマルチテナント基盤 を⽀えるコンテナ技術 Toru Komatsu(@utam0k) Preferred Networks, Inc. 2025年12月1日 ComSys 2025

Slide 4

Slide 4 text

4 AI/ML 基盤の台頭 🤖 国内の AI システムの市場規模は 2029 年には4兆1,873億円に達する と予測されている[1] 推論ワークロードのホスト 📈 推論需要の急激な増加 ● 学習ワークロードとは性質が異なる リソース効率 ⚡ 電⼒の問題 💸 経済性の問題 はじめに AI/ML 基盤に求められるもの [1]: IDC, “国内AI システム市場予測、2024 年~2029 年,” 2025 年 5 ⽉ https://openrouter.ai/rankings/marketing as of 2025/11/27 マルチテナンシによる 解決

Slide 5

Slide 5 text

5 1. はじめに ○ 題材となる PFN の AI/ML 基盤の紹介 2. コンテナ技術基礎 3. コンテナの脆弱性 ○ 2025年11⽉にあった脆弱性の話 4. 安全に root 権限を与える ○ コンテナ脆弱性への備え 5. 事業と OSS の関わり アジェンダ AI/ML 事業で⾼価なリソースを有効活⽤するための ⾼度なコンテナ技術の活⽤

Slide 6

Slide 6 text

6 PFN の AI/ML 基盤 PFNの事業: AI技術のバリューチェーンを垂直統合 AIソリューション・製品 計算基盤 AI半導体 生成AI基盤モデル 様々な産業向けのAIソリューション・製品 MN-Core MN-Core 2 GPUクラスタ MN-3 (MN-Coreクラスタ) 大規模言語モデル MN-Core 次世代 MN-Core 2を 計算資源とした クラウドサービス 物質のエネルギー計算モデル PFP 生成AI(推論)向け MN-Core L1000 (2027年提供予定) PFNは、半導体、計算基盤、生成AI基盤モデル、ソリューション・製品まで、AI技術のバリューチェーン を垂直統合し、ソフトウェアとハードウェアを高度に融合することで、競争力の高い技術の開発および産 業応用を進めています。

Slide 7

Slide 7 text

7 ● PFN が構築、運⽤する AI‧ML ワークロード向けのクラウドサービス ○ https://pfcomputing.com/ ○ ユーザガイド: https://docs.pfcomputing.com/ ● PFN のエンジニア‧リサーチャが使⽤する環境と同じものを提供 ○ これまで社内向けに計算基盤を開発運⽤してきた経験を元に開発 ● 強⼒な計算ボードと⾼速なネットワーク ○ 独⾃開発したアクセラレータ MN-Core™ シリーズ等を提供 ○ 深層学習に最適化された⾼速なネットワークで相互に接続 PFN の AI/ML 基盤 Preferred Computing Platform (PFCP)

Slide 8

Slide 8 text

8 ● 実験も学習も推論も ○ 実験環境としてマネージドな JupyterLab を提供 ○ 学習だけでなく、推論サーバの運⽤まで幅広いワークロードをサポート ● 直接の Pod の利⽤も可能 ● オープンソースを採⽤ ○ コンテナ実⾏環境にKubernetes を採⽤ (Linux Foundation / CNCF) ○ AI‧ML ワークロード向けに独⾃に拡張 ● リソース使⽤状況の可視化 ○ ワークロード状態を観測するためのモニタリングサービスも付随 PFN の AI/ML 基盤 Preferred Computing Platform (PFCP) 管理コンソール ワークロード・計算資源監視 対話型実験環境 分散学習・LLM 推論

Slide 9

Slide 9 text

9 機械学習ジョブはバッチスケジューラでいい感じに動く ● Kubernetes だと⾊々⼯夫が必要になる ユーザも Kubernetes や コンテナ に慣れる必要がある バッチスケジューラではなく、Kubernetes のいいところ ● 実験の再現が容易 ● 推論ワークロードを載せやすい ○ そもそもが Web サービス のために作られたので オートスケール、モニタリング、サービス間接続 しやすい! ○ (スパコンに Jupyter や サーバ を乗せるのは⼤変そう...) ● コミュニティが⼤きい ○ LLM以降、バッチ利⽤についても OSS が⾊々増えてきている PFN の AI/ML 基盤 わざわざ Kubernetes で頑張る理由

Slide 10

Slide 10 text

10 専有ノード: テナント専⽤ノード (+) ノードに他テナントのコンテナがいないため、セキュリティ的に安⼼ (-) ノードごとの⽉額単位で課⾦ 共有ノード: 複数のテナントが共有するノード (-) ノードに他テナントのコンテナがいるため、セキュリティが懸念 ● コンテナを抜けられてホストに潜⼊できるとまずい (+) 利⽤に合わせて分単位で課⾦ (+) クラスタ全体の利⽤効率が⾼くなる PFN の AI/ML 基盤 PFCP のノードの種類 コンテナによる隔離の強化がより重要

Slide 11

Slide 11 text

11 Kata Container ● GPU を1枚しかサポートできていない ○ 私の認識だと実装コストの都合 firecracker-microvm/firecracker/discussions/4845 ● MN-Core のドライバ側の追加対応、検証が必要 gVisor ● MN-Core のドライバ(proxy)側の追加対応、検証がかなり必要 KubeVirt ● Pod ではなくなるのであらゆるものを再考しないといけなく、 つらい PFN の AI/ML 基盤 Kubernetes でコンテナ以外の選択肢

Slide 12

Slide 12 text

12 コンテナ技術基礎

Slide 13

Slide 13 text

13 コンテナ技術基礎
 コンテナができるまで Kubernetes Container Container Runtime High-Level Low-Level OCI Runtime Spec Container Runtime I nterface

Slide 14

Slide 14 text

14 コンテナ技術基礎 コンテナ? 
 ● プロセス ≒ コンテナ
 ○ 様々なリソースが隔離されたプロセス
 Processes Files Processes Files Processes
 Files OS 🐧
 Icon pack by Icons8 - https://icons8.com

Slide 15

Slide 15 text

15 コンテナ技術基礎
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capabilities Icon pack by Icons8 - https://icons8.com

Slide 16

Slide 16 text

16 コンテナ技術基礎
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capabilities Icon pack by Icons8 - https://icons8.com 今⽇簡単に説明する

Slide 17

Slide 17 text

17 コンテナ技術基礎
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capabilities Icon pack by Icons8 - https://icons8.com

Slide 18

Slide 18 text

18 コンテナ技術基礎
 capabilities(7)
 root 権限の細分化
 ● CAP_CHOWN ● CAP_NET_ADMIN ● CAP_SYS_ADMIN ● CAP_BPF ● などなど 
 e.g. eBPF
 マップの作成 = CAP_BPF 
 ネットワーク関連のプログラムのロード = CAP_BPF + CAP_NET_ADMIN

Slide 19

Slide 19 text

19 コンテナ技術基礎
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capability

Slide 20

Slide 20 text

20 コンテナ技術基礎
 namespaces(7)
 様々なリソースを隔離
 ○ PID namespace: プロセス群の隔離
 ○ Mount namespace: マウントポイントリストの隔離
 ○ UTS namespace: ホスト名などの隔離
 ○ などなど


Slide 21

Slide 21 text

21 コンテナ技術基礎 namespaces(7) - PID Namespace $ sleep 12345 & [1] 2476249 $ ps PID TTY TIME CMD 324304 pts/11 00:00:02 zsh 2476249 pts/11 00:00:00 sleep 2476331 pts/11 00:00:00 ps

Slide 22

Slide 22 text

22 コンテナ技術基礎 namespaces(7) - PID Namespace $ sleep 12345 & [1] 2476249 $ ps PID TTY TIME CMD 324304 pts/11 00:00:02 zsh 2476249 pts/11 00:00:00 sleep 2476331 pts/11 00:00:00 ps $ sudo unshare --pid --fork --mount-proc

Slide 23

Slide 23 text

23 コンテナ技術基礎 namespaces(7) - PID Namespace $ sleep 12345 & [1] 2476249 $ ps PID TTY TIME CMD 324304 pts/11 00:00:02 zsh 2476249 pts/11 00:00:00 sleep 2476331 pts/11 00:00:00 ps $ sudo unshare --pid --fork --mount-proc $ ps PID TTY TIME CMD 1 pts/6 00:00:00 zsh 3 pts/6 00:00:00 ps

Slide 24

Slide 24 text

24 コンテナ技術基礎 namespaces(7) - PID Namespace $ sleep 12345 & [1] 2476249 $ ps PID TTY TIME CMD 324304 pts/11 00:00:02 zsh 2476249 pts/11 00:00:00 sleep 2476331 pts/11 00:00:00 ps $ sudo unshare --pid --fork --mount-proc $ ps PID TTY TIME CMD 1 pts/6 00:00:00 zsh 3 pts/6 00:00:00 ps

Slide 25

Slide 25 text

25 コンテナ技術基礎
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capabilities Icon pack by Icons8 - https://icons8.com

Slide 26

Slide 26 text

26 コンテナの脆弱性

Slide 27

Slide 27 text

27 専有ノード: テナント専⽤ノード (+) ノードに他テナントのコンテナがいないため、セキュリティ的に安⼼ (-) ノードごとの⽉額単位で課⾦ 共有ノード: 複数のテナントが共有するノード (-) ノードに他テナントのコンテナがいるため、セキュリティが懸念 ● コンテナを抜けられてホストに潜⼊できるとまずい (+) 利⽤に合わせて分単位で課⾦ (+) クラスタ全体の利⽤効率が⾼くなる PFN の AI/ML 基盤 PFCP のノードの種類 コンテナによる隔離の強化がより重要

Slide 28

Slide 28 text

小松 享 / @utam0k ● Preferred Networks, Inc. / エンジニア ○ 社内/社外の AI/ML 基盤の構築と運用 ○ 特にスケジューラやコンテナランタイム ● エンジニアリングマネージャー ● OSS 活動 ○ youki の作者 ○ OCI Runtime Specification メンテナ ○ Kubernetes SIG-Scheduling Reviewer ○ containerd/runwasi Reviwer

Slide 29

Slide 29 text

29 コンテナの脆弱性 2025年11⽉7⽇ CVE-2025-31133 / 7.3 High(CVSS v4) ● maskedPaths 実装における競合状態 CVE-2025-52565 / 7.3 High(CVSS v4) ● /dev/console のマウント初期化時の競合 CVE-2025-52881 / 7.3 High(CVSS v4) ● 共有マウントを利⽤した /proc への書き込みリダイレクトと LSM 回避

Slide 30

Slide 30 text

30 コンテナの脆弱性 2025年11⽉7⽇ CVE-2025-31133 / 7.3 High(CVSS v4) ● maskedPaths 実装における競合状態 CVE-2025-52565 / 7.3 High(CVSS v4) ● /dev/console のマウント初期化時の競合 CVE-2025-52881 / 7.3 High(CVSS v4) ● 共有マウントを利⽤した /proc への書き込みリダイレクトと LSM 回避

Slide 31

Slide 31 text

31 コンテナの脆弱性 - CVE-2025-31133 maskedPaths maskedPaths: コンテナ内で⾒せたくないパスをマスクする

Slide 32

Slide 32 text

32 コンテナの脆弱性 - CVE-2025-31133 実際の runc のコード https://github.com/opencontainers/runc/blob/v1.3.2/libcontainer/rootfs_linux.go

Slide 33

Slide 33 text

33 コンテナの脆弱性 - CVE-2025-31133 /dev/null を⽤いた maskedPaths の実装 /dev/null デバイスを⽤いたファイルのマスク → 読み込み: EOF / 書き込み: 破棄

Slide 34

Slide 34 text

34 コンテナの脆弱性 - CVE-2025-31133 /dev/null の安全 /dev/null デバイスを⽤いたファイルのマスク → 読み込み: EOF / 書き込み: 破棄 本当に安全?

Slide 35

Slide 35 text

35 コンテナの脆弱性 - CVE-2025-31133 /dev/null の安全 /dev/null デバイスを⽤いたファイルのマスク → 読み込み: EOF / 書き込み: 破棄 本当に期待している /dev/null?

Slide 36

Slide 36 text

36 コンテナの脆弱性 - CVE-2025-31133 /dev/null の検証

Slide 37

Slide 37 text

37 コンテナの脆弱性 - CVE-2025-31133 /dev/null の安全 本当にこのときに期待 している/dev/null?

Slide 38

Slide 38 text

38 コンテナの脆弱性 - CVE-2025-31133 /dev/null の安全

Slide 39

Slide 39 text

39 コンテナの脆弱性 - CVE-2025-31133 TOCTOU 😈 検証後に差し込まれる

Slide 40

Slide 40 text

40 コンテナの脆弱性 - CVE-2025-31133 実際の runc のコード https://github.com/opencontainers/runc/blob/v1.3.2/libcontainer/rootfs_linux.go

Slide 41

Slide 41 text

41 コンテナの脆弱性 - CVE-2025-31133 実際の runc のコード https://github.com/opencontainers/runc/blob/v1.3.2/libcontainer/rootfs_linux.go 本当に /dev/null ? どこの /dev/null ?

Slide 42

Slide 42 text

42 コンテナの脆弱性 - CVE-2025-31133 実際の runc のコード https://github.com/opencontainers/runc/blob/v1.3.2/libcontainer/rootfs_linux.go コンテナ内の /dev/null いろいろ仕掛け が可能そう

Slide 43

Slide 43 text

43 コンテナの脆弱性 - CVE-2025-31133 TOCTOU 😈

Slide 44

Slide 44 text

44 コンテナの脆弱性 - CVE-2025-31133 パッチ 根本的な問題 ● コンテナの起動プロセスの権限が root である ● mount(2) に検証済みの fd を渡すことができない 解決策 ● move_mount(2) の利⽤ ○ linux カーネル 5.3 から利⽤可能 ● /proc/thread-self/fd/N を利⽤ ○ 古いカーネル⽤ https://github.com/opencontainers/runc/blob/v1.3.2/libcontainer/rootfs_linux.go 3つの CVE のパッチ

Slide 45

Slide 45 text

45 コンテナの脆弱性 他にも過去の脆弱性の話 CVE-2024-21626: Leaky Vessels, 8.6 High (CVSS v3.1) ● runc の初期化中にホスト側の重要な FD がコンテナにリーク CVE-2019-5736: runcバイナリ上書き, 8.6 High (CVSS v3.1) ● /proc/self/exe を経由してホスト上の runc バイナリ⾃体を悪意のある コードで上書きしてしまう脆弱性 コンテナがホストの root で動いてしまうのがつらい

Slide 46

Slide 46 text

46 安全に root 権限を与える

Slide 47

Slide 47 text

47 安全に root 権限を与える PFCP のノードの種類 専有ノード: テナント専⽤ノード (+) ノードに他テナントのコンテナがいないため、セキュリティ的に安⼼ (-) ノードごとの⽉額単位で課⾦ 共有ノード: 複数のテナントが共有するノード (-) ノードに他テナントのコンテナがいるため、セキュリティが懸念 ● コンテナを抜けられてホストに潜⼊できるとまずい (+) 利⽤に合わせて分単位で課⾦ (+) クラスタ全体の利⽤効率が⾼くなる

Slide 48

Slide 48 text

48 root ユーザー禁⽌ (+) コンテナを抜けられてもすぐに root ユーザーにはなれない (-) root ユーザーが使えないため apt install などできない root ユーザー許容 (-) コンテナを抜けられたときにホストの root ユーザーとなる ○ 他テナントのコンテナに潜⼊されるリスク (+) apt install など可能に 安全に root 権限を与える コンテナセキュリティ強化と利便性 root を許可しつつ、安全にしたい

Slide 49

Slide 49 text

49 ● kubernetes/enhancements#127(Beta), Oct 11, 2016 ~ ● コンテナ内で安全に UID: 0(≒ root) を使える 安全に root 権限を与える KEP-127: Support User Namespaces

Slide 50

Slide 50 text

50 安全に root 権限を与える User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx securityContext: runAsUser: 1000

Slide 51

Slide 51 text

51 安全に root 権限を与える User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx securityContext: runAsUser: 1000 => mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

Slide 52

Slide 52 text

52 安全に root 権限を与える User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: nginx spec: containers: - name: nginx image: nginx $ crictl inspect $cid | grep pid "pid": 55770, $ ps -o uid,comm -p 55770 UID COMMAND 0 nginx Node Manifest

Slide 53

Slide 53 text

53 安全に root 権限を与える User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: cndw2024 spec: hostUsers: false containers: - name: shell command: ["sleep", "infinity"] image: debian

Slide 54

Slide 54 text

54 安全に root 権限を与える User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: nginx spec: hostUsers: false containers: - name: nginx image: nginx $ crictl inspect $cid | grep pid "pid": 56560, $ ps -o uid,comm -p 56560 UID COMMAND 631373824 nginx Node Manifest

Slide 55

Slide 55 text

55 安全に root 権限を与える / User Namespace User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: nginx spec: hostUsers: false containers: - name: nginx image: nginx $ crictl inspect $cid | grep pid "pid": 56560, $ ps -o uid,comm -p 56560 UID COMMAND 631373824 nginx Node Manifest 高度に発達したコンテナは 魔術と見分けがつかない Any sufficiently advanced container is indistinguishable from magic

Slide 56

Slide 56 text

56 From user_namespaces(7): 安全に root 権限を与える / User Namespace User Namespace とは? User namespaces isolate security-related identifiers and attributes, in particular, user IDs and group IDs, the root directory, keys, and capabilities. A process's user and group IDs can be different inside and outside a user namespace. In particular, a process can have a normal unprivileged user ID outside a user namespace while at the same time having a user ID of 0 inside the namespace; in other words, the process has full privileges for operations inside the user namespace, but is unprivileged for operations outside the namespace.

Slide 57

Slide 57 text

57 From user_namespaces(7): 安全に root 権限を与える / User Namespace User Namespace とは? User namespaces isolate security-related identifiers and attributes, in particular, user IDs and group IDs, the root directory, keys, and capabilities. A process's user and group IDs can be different inside and outside a user namespace. In particular, a process can have a normal unprivileged user ID outside a user namespace while at the same time having a user ID of 0 inside the namespace; in other words, the process has full privileges for operations inside the user namespace, but is unprivileged for operations outside the namespace. 🤔

Slide 58

Slide 58 text

58 ● Linux Namespaces の 1種類 ○ ⾮特権ユーザーから分離できる ● 特に UID/GID をホストの User NS から分離する ○ ホストの User NS からマッピングが可能 安全に root 権限を与える / User Namespace User Namespace とは?

Slide 59

Slide 59 text

59 安全に root 権限を与える / User Namespace UID のマッピング Init User NS 0 … 999 1000 … 1999 2000 … 2999 3000 … 3999 Container 1 User NS 0 … 999 Container 2 User NS 0 … 999 1000 …. 1999 Host Init User NS 0 … 999 1000 … 1999 2000 … 2999 3000 … 3999 Init User NS 0 … 999 Init User NS 0 … 999 1000 …. 1999 Host User Namespace なしのUIDs User Namespace ありの UIDs コンテナ1 コンテナ2

Slide 60

Slide 60 text

60 安全に root 権限を与える / User Namespace コマンド $ whoami utam0k $ id uid=1000(utam0k) gid=1000(utam0k) groups=1000(utam0k) $ unshare --user

Slide 61

Slide 61 text

61 安全に root 権限を与える / User Namespace コマンド $ whoami utam0k $ id uid=1000(utam0k) gid=1000(utam0k) groups=1000(utam0k) $ unshare --user $ whoami nobody $ id uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup) Init User NS Container User NS

Slide 62

Slide 62 text

62 User Namespace とは? UID / GID Mapping 0
 0
1
 1000
 65536
 100000
 165535
 Host UIDs Container UIDs $ cat /proc/37/uid_map 0 1000   1 1 100000  65536 #  ID-child-ns  ID-parent-ns length

Slide 63

Slide 63 text

63 newuidmap: User NS の UID のマッピングを⾏ってくれる 4つの引数 ○ pid ターゲットのプロセスID ○ uid ⼦の UserNS のスタートのUID ○ loweruid 親の UserNS のスタートのUID ○ count マッピングする UID の⻑さ 安全に root 権限を与える / User Namespace UID / GID Mapping $ newuidmap 37 0 1000 1 $ echo $? 0

Slide 64

Slide 64 text

64 安全に root 権限を与える / User Namespace UID / GID Mapping $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37 $ newuidmap 37 0 1000 1 $ ps -o uid,comm -p 37 UID COMMAND 1000 zsh $ cat /proc/$$/uid_map 0 1000 1 $ id -u 0 Container NS Init User NS ① ② ③

Slide 65

Slide 65 text

65 安全に root 権限を与える / User Namespace UID / GID Mapping Container NS Init User NS ① $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37

Slide 66

Slide 66 text

66 安全に root 権限を与える / User Namespace UID / GID Mapping Container NS Init User NS ① ② $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37 $ newuidmap 37 0 1000 1 $ ps -o uid,comm -p 37 UID COMMAND 1000 zsh

Slide 67

Slide 67 text

67 安全に root 権限を与える / User Namespace UID / GID Mapping $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37 $ cat /proc/$$/uid_map 0 1000 1 $ id -u 0 Container NS Init User NS ① ② ③ $ newuidmap 37 0 1000 1 $ ps -o uid,comm -p 37 UID COMMAND 1000 zsh

Slide 68

Slide 68 text

68 安全に root 権限を与える / User Namespace UID / GID Mapping - Podman を使った例 $ podman run --name userns -it --rm --userns="" docker.io/library/busybox / # id uid=0(root) gid=0(root) groups=10(wheel) $ PID=$(podman inspect userns | jq .[0].State.Pid) $ cat /proc/$PID/uid_map 0 1000 1 1 100000 65536 Init User NS Podman NS ① ②

Slide 69

Slide 69 text

69 Point: コンテナの隔離が抜けられてもホストでは⼀般ユーザー CVE-2025-31133: maskedPaths 実装における競合状態 CVE-2019-5736: ホストの runc バイナリをコンテナ側から書き換え可能 ✔ コンテナ側の uid: 0 はホストの uid: 0 ではないので権限不⾜となる 安全に root 権限を与える / User Namespace CVEの事例紹介と有効な理由 From: https://kubernetes.io/blog/2019/02/11/runc-and-cve-2019-5736/

Slide 70

Slide 70 text

70 真の root = init_user_ns の UID: 0 カーネル側では適宜真の root かチェックしている 安全に root 権限を与える / User Namespace なぜ安全なのかもう少し深掘り https://elixir.bootlin.com/linux/v6.12/source/kernel/capability.c#L424-L437 /** * capable - Determine if the current task has a superior capability in effect * @cap: The capability to be tested for … */ bool capable(int cap) { return ns_capable(&init_user_ns, cap); }

Slide 71

Slide 71 text

71 User NS の UID/GID のマッピングはあくまでもプロセスのおはなし ○ ファイルは...? 安全に root 権限を与える / User Namespace ファイルの所有者 Processes Files Processes Files Processes
 Files OS 🐧
 ここはおっけー Icon pack by Icons8 - https://icons8.com

Slide 72

Slide 72 text

72 User NS の UID/GID のマッピングはあくまでもプロセスのおはなし ○ ファイルは...? 安全に root 権限を与える / User Namespace ファイルの所有者 Processes Files Processes Files Processes
 Files OS 🐧
 コンテナのイメージは様々なユーザー が所有しているファイルなどある Icon pack by Icons8 - https://icons8.com

Slide 73

Slide 73 text

73 安全に root 権限を与える / User Namespace Permission Denied $ ls -l drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt utam0k: 1000 pfn: 1001

Slide 74

Slide 74 text

74 安全に root 権限を与える / User Namespace Permission Denied $ ls -l drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt $ unshare --user --map-root-user $ cat /proc/$$/uid_map 0 1000 1 utam0k: 1000 pfn: 1001 コンテナの 0 をホスト 1000 に 長さ 1 でマッピングされている utam0k(ホスト) ↔ root(コンテナ) 実行ユーザー(utam0k) を root ユーザーにマッピング

Slide 75

Slide 75 text

75 安全に root 権限を与える / User Namespace Permission Denied $ ls -l drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt $ unshare --user --map-root-user $ cat /proc/$$/uid_map 0 1000 1 $ ls -l drwxrwxr-x 2 nobody nogroup 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 root root 10 Nov 9 11:45 utam0k.txt utam0k: 1000 pfn: 1001

Slide 76

Slide 76 text

76 安全に root 権限を与える / User Namespace Permission Denied $ ls -l drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt $ unshare --user --map-root-user $ cat /proc/$$/uid_map 0 1000 1 $ ls -l drwxrwxr-x 2 nobody nogroup 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 root root 10 Nov 9 11:45 utam0k.txt $ echo "test" | tee -a pfn/pfn.txt tee: pfn/pfn.txt: Permission denied test $ echo "test" | tee -a utam0k.txt test utam0k: 1000 pfn: 1001

Slide 77

Slide 77 text

77 安全に root 権限を与える / id-mapped mount id-mapped mount とは? Init User NS Container User NS UID/GID のマッピング by FS UID 0 UID 1000 UID 1000 UID 2000 ・・・ ・・・ Icon pack by Icons8 - https://icons8.com

Slide 78

Slide 78 text

78 安全に root 権限を与える / id-mapped mount コマンド $ ls -l drwxrwxr-x 2 pfn pfn 4096 Nov 27 08:26 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt $ sudo mount -m --bind --map-users 1001:1000:1 $(pwd)/pfn $(pwd)/mnt utam0k: 1000 pfn: 1001 1001(pfn) を 1000(utam0k) に 長さ 1 でマッピング 1001(pfn) → 1000(utam0k)

Slide 79

Slide 79 text

79 安全に root 権限を与える / id-mapped mount コマンド $ ls -l drwxrwxr-x 2 pfn pfn 4096 Nov 27 08:26 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt $ sudo mount -m --bind --map-users 1001:1000:1 $(pwd)/pfn $(pwd)/mnt $ ls -l drwxrwxr-x 2 utam0k nogroup 4096 Nov 10 12:03 mnt/ drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt utam0k: 1000 pfn: 1001

Slide 80

Slide 80 text

80 安全に root 権限を与える / id-mapped mount コマンド - User Namespace と組み合わせる $ sudo mount -m --bind --map-users 1001:1000:1 $(pwd)/pfn $(pwd)/mnt $ ls -l drwxrwxr-x 2 utam0k nogroup 4096 Nov 10 12:03 mnt/ drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt utam0k: 1000 pfn: 1001

Slide 81

Slide 81 text

81 安全に root 権限を与える / id-mapped mount コマンド - User Namespace と組み合わせる $ sudo mount -m --bind --map-users 1001:1000:1 $(pwd)/pfn $(pwd)/mnt $ ls -l drwxrwxr-x 2 utam0k nogroup 4096 Nov 10 12:03 mnt/ drwxrwxr-x 2 pfn pfn 4096 Nov 10 11:43 pfn/ -rw-rw-r-- 1 utam0k utam0k 10 Nov 9 11:45 utam0k.txt $ unshare --user --map-root-user $ echo "test" | tee -a mnt/pfn.txt test $ cat pfn/pfn.txt pfn test utam0k: 1000 pfn: 1001

Slide 82

Slide 82 text

82 ✓ User Namespace プロセスの UID/GID の変換を担当 ✓ id-mapped mount ファイルシステムレイヤでの UID/GID の変換を担当 安全に root 権限を与える 安全にコンテナに root を与える要素技術まとめ Processes Files Processes Files Processes
 Files OS 🐧
 User Namespace id-mapped mount Icon pack by Icons8 - https://icons8.com

Slide 83

Slide 83 text

83 安全に root 権限を与える / Kubernetes からの利⽤ コンテナ側からの視点 $ kubectl apply -f https://k8s.io/examples/pods/user-namespaces-stateless.yaml pod/userns created

Slide 84

Slide 84 text

84 安全に root 権限を与える / Kubernetes からの利⽤ コンテナ側からの視点 $ kubectl apply -f https://k8s.io/examples/pods/user-namespaces-stateless.yaml pod/userns created $ kubectl exec userns -- lsfd -p 1 | head -n 2 COMMAND PID USER ASSOC MODE TYPE SOURCE MNTID INODE NAME sleep 1 root exe --- REG overlay 0 8393115 /usr/bin/sleep $ kubectl exec userns -- id uid=0(root) gid=0(root) groups=0(root)

Slide 85

Slide 85 text

85 安全に root 権限を与える / Kubernetes からの利⽤ コンテナ側からの視点 $ kubectl apply -f https://k8s.io/examples/pods/user-namespaces-stateless.yaml pod/userns created $ kubectl exec userns -- lsfd -p 1 | head -n 2 COMMAND PID USER ASSOC MODE TYPE SOURCE MNTID INODE NAME sleep 1 root exe --- REG overlay 0 8393115 /usr/bin/sleep $ kubectl exec userns -- id uid=0(root) gid=0(root) groups=0(root) $ kubectl exec userns -- cat /proc/self/uid_map 0 700448768 65536 #  ID-child-ns  ID-parent-ns length

Slide 86

Slide 86 text

86 安全に root 権限を与える / Kubernetes からの利⽤ ノード側からの視点 $ minikube ssh $ sudo crictl ps | grep userns 464c62f753d43 63ba939a68fde 5 seconds ago Running ... $ sudo crictl inspect 464c62f753d43 | grep pid "pid": 3574,

Slide 87

Slide 87 text

87 安全に root 権限を与える / Kubernetes からの利⽤ ノード側からの視点 $ minikube ssh $ sudo crictl ps | grep userns 464c62f753d43 63ba939a68fde 5 seconds ago Running ... $ sudo crictl inspect 464c62f753d43 | grep pid "pid": 3574, $ ps -o uid,comm -p 3574 UID COMMAND 700448768 sleep

Slide 88

Slide 88 text

88 id-mapped mount が⾮対応なファイルシステムがある man の mount_setattr(2) の Notes セクションに対応済み⼀覧がある ✓ xfs(5) (since Linux 5.12) ✓ ext4(5) (since Linux 5.12) ✓ btrfs(5) (since Linux 5.15) ✓ overlayfs (ID-mapped lower and upper layers supported since Linux 5.19) ✓ cephfs (since Linux 6.7) NFS が⾮対応 で困った... 😭 → RWX なストレージを提供できていない 安全に root 権限を与える 直⾯した課題

Slide 89

Slide 89 text

89 ➔ NFS が id-mapped mount ⾮対応 ○ NFS を必要とするコンテナの起動に失敗する ➔ id-mapped mount がないとどうなるか? ○ 起動は成功する ○ NFS で UID/GID がおかしくなり、消えないファイルが誕⽣する ➔ そもそも PFCP の NFS の UID/GID は必要? ○ PFCP では各テナントは Kubernetes の Namespace で区切られ ているので UID/GID での制御は不要 ➔ 誰が書き込んでいるかは考えなくよい(all_squash) 安全に root 権限を与える / 直⾯した課題 問題を整理

Slide 90

Slide 90 text

90 安全に root 権限を与える / 直⾯した課題 id-mapped mount をスキップさせる Kubernetes Container Container Runtime High-Level Low-Level OCI Runtime Spec Container Runtime I nterface

Slide 91

Slide 91 text

91 安全に root 権限を与える / 直⾯した課題 id-mapped mount をスキップさせる

Slide 92

Slide 92 text

92 安全に root 権限を与える / 直⾯した課題 id-mapped mount をスキップさせる ここでファイルシステムの種類ごとに id-mapped mount のスキップの制御はできない😢

Slide 93

Slide 93 text

93 安全に root 権限を与える / 直⾯した課題 id-mapped mount をスキップさせる NEW

Slide 94

Slide 94 text

94 安全に root 権限を与える / NRI NRI(Node Resource Interface) Low-Level に渡る情報を加⼯、検証できる Kubernetes Container Container Runtime High-Level Low-Level OCI Runtime Spec Container Runtime I nterface

Slide 95

Slide 95 text

95 ● containerd/nri ● Kubecon + CNC 2025 でもいくつか発表 ● Pod とコンテナのライフサイクルに合わせて プラグインがフックされる ○ e.g., 作成、消去、停⽌ ● プラグインでは検証やコンテナの加⼯が可能 ○ 加⼯できるフィールド例: ■ Linux namespaces ■ memory の swap limit ■ CPU の quota や period ● Protobuf ベースの NRI Plugin プロトコルでコ ンテナランタイム側とやりとり 安全に root 権限を与える / NRI NRI(Node Resource Interface) https://github.com/containerd/nri

Slide 96

Slide 96 text

96 安全に root 権限を与える / NRI NRI Plugin の実装例

Slide 97

Slide 97 text

97 安全に root 権限を与える / NRI id-mapped mount をスキップさせる コンテナの加工をプラグインの ようにできるコンテナランタイ ムの新機能 NFS の時だけ id-mapped mount をスキップ NEW

Slide 98

Slide 98 text

98 ここがすごい! ● 標準化されているのでコンテナランタイムへの依存がない ● プラグインで差し込めるので簡単にコンテナランタイムに機能追加可能 ○ 最先端の機能もお試しでプラグインとしてすぐに取り込める ● NRI のプラグインでは Pod のアノテーション情報も⾒える ● WebAssembly サポートがある ここが注意! ● まだまだ新しい機能で情報は少ない ● 加⼯できない OCI Runtime のフィールドもある いままではどうしていたのか? ● OCI Runtime の Hooks を使って差し込む ● Low-Level コンテナランタイムをラップする 安全に root 権限を与える / NRI id-mapped mount をスキップさせる

Slide 99

Slide 99 text

99 ❗やりたいこと ● (コンテナ内では) root だが、(ホストでは) root ではない 🛡 コンテナ内で安全に root を与える ● User Namespace ● id-mapped mount ⚠ 制限 ● id-mapped mount の制約により NFS が利⽤できない 💡 解決⽅法 ● NRIを⽤いたコンテナランタイムの拡張 安全に root 権限を与える 過去の多くのコンテナ脆弱性を防ぐ

Slide 100

Slide 100 text

100 産業と OSS の関わり

Slide 101

Slide 101 text

101 産業と OSS の関わり コンテナでの新しい技術の⽣まれ⽅ Kubernetes Container Container Runtime High-Level Low-Level OCI Runtime Spec Container Runtime I nterface

Slide 102

Slide 102 text

102 産業と OSS の関わり コンテナでの新しい技術の⽣まれ⽅ User Namespace の機能が⽣まれるには? 1. Kubernetes 側で話を進める 2. OCI Runtime Spec 側で話を進める 3. Low Level コンテナランタイム 側で実装 4. High Level コンテナランタイム側で実装 5. Kubernetes で実装

Slide 103

Slide 103 text

103 産業と OSS の関わり コンテナでの新しい技術の⽣まれ⽅ Kubernetes Container Container Runtime High-Level Low-Level OCI Runtime Spec Container Runtime I nterface

Slide 104

Slide 104 text

104 産業と OSS の関わり 仕様策定のメンテナであること ✓ 技術が⽣まれるところへ参加できる ○ ⾃分たちで使いたいケースも仕様策定段階で話ができる ■ 実装フェーズでひっくり返すのは⼤変 ✓ 機能をいち早く社会に届ける⼿助けができる ○ ⾃分もマージやリリースを⾏う権限を持つ責任 ✓ 持続可能な OSS の構築 ○ 活発な OSS にすることでアカデミアからの注⽬を獲得し、新 しい技術が作られる ✓ F2F での会話への参加機会の増加 ○ オフラインで会うことの重要性は増している

Slide 105

Slide 105 text

105 産業と OSS の関わり 参考: オープンソースソフトウェアへの解像度 https://wakate.org/2025/08/18/58th-general/

Slide 106

Slide 106 text

106 xz バックドア事件(2024) ● メンテナがバックドアを仕掛ける ● おそらく OSS 界隈での氷⼭の⼀⾓ 背景 ● メンテナは 2 年もの歳⽉を費やして信頼を構築 ○ ⾝元が明らかでない中、メンテナ権限が付与された ● xz の開発が停滞していた 産業と OSS の関わり OSS のセキュリティリスク

Slide 107

Slide 107 text

107 メンテナとして関わる ✓ ガバナンスへの参加 ✓ 信頼できる開発者として OSS に参加し、監視する ○ ⾃分の⾝は⾃分で守る ✓ 狙われるリスクのトレンドを知る ○ Closed なセキュリティ関連のやりとりから学ぶ ■ 攻撃者、守る側の両⽅の視点をもつ ■ トレンドを知ることで有効な対策もわかる 産業と OSS の関わり OSS のセキュリティリスク

Slide 108

Slide 108 text

108 産業と OSS の関わり 参考: なぜオープンソースソフトウェアにコントリビュートすべきなのか https://wakate.org/2024/08/13/57th-general/

Slide 109

Slide 109 text

109 まとめ 🤖 AI/ML 基盤に求められるもの ○ ⾼価な計算資源の有効活⽤ → マルチテナンシ 📦 コンテナ脆弱性 ○ CVE-2025-31133: maskedPaths 実装における競合状態 ○ コンテナがホストの root で動いてしまうのがつらい 🔐 安全に root 権限を与える ○ User Namespace: プロセスの UID/GID のマッピング ○ id-mapped monut: ファイルの UID/GID のマッピング ○ NRI(Node Resource Interface): コンテナランタイムの拡張 🤝 産業と OSS の関わり ○ 技術が⽣まれるところに⼊る ○ OSS のセキュリティリスク

Slide 110

Slide 110 text

Making the real world computable