Slide 1

Slide 1 text

次のコンテナセキュリティの時代 User Namespace With a Pod Toru Komatsu(@utam0k) Preferred Networks, Inc.

Slide 2

Slide 2 text

2 Preferred Networks, Inc. オンプレML基盤の開発‧運⽤ OSS Activities Maintainer opencontainers/runtime-spec containers/youki Reviwer containerd/runwasi Member kubernetes org(sig-scheduling/node) Community CNA, CNCJ @utam0k Toru Komatsu

Slide 3

Slide 3 text

3 User Namespace With a Pod とは?

Slide 4

Slide 4 text

4 ● kubernetes/enhancements#127(Beta), Oct 11, 2016 ~ ● コンテナ内で安全に UID: 0(≒ root) を使える User Namespace With a Pod とは? KEP-127: Support User Namespaces

Slide 5

Slide 5 text

5 minikube を⽤いた User Namespace With a Pod 環境セット https://github.com/utam0k/minikube/tree/cndw2024 User Namespace With a Pod とは? 検証環境 $ kubectl get nodes -o json | jq .items[0].status.nodeInfo { "architecture": "amd64", "bootID": "554e2aa9-19f8-48e1-9b4e-b8931da0191a", "containerRuntimeVersion": "containerd://2.0.0+unknown", "kernelVersion": "6.5.13", "kubeProxyVersion": "v1.30.0", "kubeletVersion": "v1.30.0", "machineID": "5afad69dc2a84258b8f7e0745a2bba37", "operatingSystem": "linux", "osImage": "Buildroot 2024.02", "systemUUID": "5afad69d-c2a8-4258-b8f7-e0745a2bba37" }

Slide 6

Slide 6 text

6 User Namespace With a Pod とは? User Namespace With a Pod apiVersion: v1 kind: Pod metadata: name: cndw2024 spec: hostUsers: false containers: - name: shell command: ["sleep", "infinity"] image: debian

Slide 7

Slide 7 text

7 User Namespace With a Pod とは? 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 8

Slide 8 text

8 User Namespace With a Pod とは? 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 9

Slide 9 text

9 User Namespace With a Pod とは? 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 10

Slide 10 text

10 User Namespace With a Pod とは? 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 11

Slide 11 text

11 コンテナについて学ぼう

Slide 12

Slide 12 text

12 コンテナについて学ぼう
 コンテナ? 
 ● プロセス ≒ コンテナ
 ○ 様々なリソースが隔離されたプロセス
 Processes Files Processes Files Processes
 Files OS 🐧
 Icon pack by Icons8 - https://icons8.com

Slide 13

Slide 13 text

13 コンテナについて学ぼう
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capabilities Icon pack by Icons8 - https://icons8.com

Slide 14

Slide 14 text

14 コンテナについて学ぼう
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capabilities 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 コンテナについて学ぼう
 capabilities(7)
 root 権限の細分化
 ● CAP_CHOWN ● CAP_NET_ADMIN ● CAP_SYS_ADMIN ● CAP_BPF ● and more 
 e.g. eBPF
 マップの作成 = CAP_BPF 
 ネットワーク関連のプログラムのロード = CAP_BPF + CAP_NET_ADMIN

Slide 17

Slide 17 text

17 コンテナについて学ぼう
 コンテナを支えるカーネル技術 / cgroups namespaces pivot_root capability

Slide 18

Slide 18 text

18 コンテナについて学ぼう
 namespaces(7)
 様々なリソースを隔離
 ○ PID namespace: プロセス群の隔離
 ○ Mount namespace: マウントポイントリストの隔離
 ○ UTS namespace: ホスト名などの隔離
 ○ and more


Slide 19

Slide 19 text

19 コンテナについて学ぼう 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 20

Slide 20 text

20 コンテナについて学ぼう 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 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 $ 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 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 $ ps PID TTY TIME CMD 1 pts/6 00:00:00 zsh 3 pts/6 00:00:00 ps

Slide 23

Slide 23 text

23 User Namespace とは?

Slide 24

Slide 24 text

24 From user_namespaces(7): 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 25

Slide 25 text

25 From user_namespaces(7): 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 26

Slide 26 text

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

Slide 27

Slide 27 text

27 User Namespace とは? User Namespace Init User NS 0 … 1000 1001 … 2000 2001 … 4000 4001 … 5000 Container 1 User NS 0 … 1000 Container 2 User NS 0 … 1000 1001 …. 2000 Nested User NS 0 … 1000

Slide 28

Slide 28 text

28 User Namespace とは? User Namespace $ whoami utam0k $ id uid=1000(utam0k) gid=1000(utam0k) groups=1000(utam0k) $ unshare --user

Slide 29

Slide 29 text

29 User Namespace とは? 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)

Slide 30

Slide 30 text

30 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 31

Slide 31 text

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

Slide 32

Slide 32 text

32 User Namespace とは? UID / GID Mapping $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37 $ newuidmap 37 0 1000 1 $ cat /proc/$$/uid_map 0 1000 1 $ id -u 0 Container NS Init User NS ① ② ③

Slide 33

Slide 33 text

33 User Namespace とは? UID / GID Mapping Container NS Init User NS ① $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37

Slide 34

Slide 34 text

34 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

Slide 35

Slide 35 text

35 User Namespace とは? UID / GID Mapping $ unshare --user $ id -u 65534 $ cat /proc/$$/uid_map $ echo $$ 37 $ newuidmap 37 0 1000 1 $ cat /proc/$$/uid_map 0 1000 1 $ id -u 0 Container NS Init User NS ① ② ③

Slide 36

Slide 36 text

36 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 37

Slide 37 text

37 ⾃分以外のマッピングを⾏おうとするには当然NG User Namespace とは? UID / GID Mapping - subuid $ id uid=1000(utam0k) gid=1000(utam0k) groups=1000(utam0k) # OK $ newuidmap $container_pid 0 1000 1 $ echo $? 0 # NG $ newuidmap $container_pid 0 1000 2 newuidmap: uid range [0-2) -> [1000-1002) not allowed

Slide 38

Slide 38 text

38 各ユーザーが割り当てることができる UID の範囲は決まっている ⚠ 実際に存在する UID は割り当てができない /etc/subuid に各ユーザーがどの UID を割り当てられるか設定されている User Namespace とは? UID / GID Mapping - subuid $ cat /etc/subuid utam0k:100000:65536 $ newuidmap $container_pid 1 100000 65536 $ echo $? 0 $ newuidmap $container_pid 1 165536 65536 newuidmap: uid range [1-65537) -> [165536-231072) not allowed

Slide 39

Slide 39 text

39 Point: コンテナの隔離が抜けられても真のrootへはまだもう1階層ある CVE-2019-5736: ホストの runc バイナリをコンテナ側から書き換え可能 ✔ コンテナ側の uid: 0 はホストの uid: 0 ではないので権限不⾜となる User Namespace とは? CVEの事例紹介と有効な理由 From: https://kubernetes.io/blog/2019/02/11/runc-and-cve-2019-5736/

Slide 40

Slide 40 text

40 “真”の root = init_user_ns の UID: 0 カーネル側では適宜 “真” の 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 41

Slide 41 text

41 User Namespace とは? なぜ安全なのかもう少し深掘り Init User NS 0 … 1000 1001 … 2000 2001 … 4000 4001 … 5000 Container 1 User NS 0 … 1000 Container 2 User NS 0 … 1000 1001 …. 2000 Nested User NS 0 … 1000

Slide 42

Slide 42 text

42 User NS の UID/GID のマッピングはあくまでもプロセスのおはなし ○ ファイルは...? id-mapped mount とは? ファイルの所有者 Processes Files Processes Files Processes
 Files OS 🐧
 ここはおっけー Icon pack by Icons8 - https://icons8.com

Slide 43

Slide 43 text

43 User NS の UID/GID のマッピングはあくまでもプロセスのおはなし ○ ファイルは...? id-mapped mount とは? ファイルの所有者 Processes Files Processes Files Processes
 Files OS 🐧
 コンテナのイメージは様々なユーザー が所有しているファイルなどある Icon pack by Icons8 - https://icons8.com

Slide 44

Slide 44 text

44 User NS の UID/GID のマッピングはあくまでもプロセスのおはなし ○ ファイルは...? id-mapped mount とは? ファイルの所有者 Processes Files Processes Files Processes
 Files OS 🐧
 コンテナのイメージは様々なユーザー が所有しているファイルなどある !Σ(・Д・;) Icon pack by Icons8 - https://icons8.com

Slide 45

Slide 45 text

45 id-mapped mount とは? 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 46

Slide 46 text

46 id-mapped mount とは? 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

Slide 47

Slide 47 text

47 id-mapped mount とは? 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 48

Slide 48 text

48 id-mapped mount とは? 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 49

Slide 49 text

49 id-mapped mount とは? id-mapped mount Init User NS User NS UID/GID の変換 by FS UID 0 UID 1000 UID 1000 UID 2000 ・・・ ・・・ Icon pack by Icons8 - https://icons8.com

Slide 50

Slide 50 text

50 id-mapped mount とは? id-mapped mount $ sudo mount --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 51

Slide 51 text

51 id-mapped mount とは? id-mapped mount $ sudo mount --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 52

Slide 52 text

52 ✓ User Namespace プロセスの UID/GID の変換を担当 ✓ id-mapped mount ファイルシステムレイヤでの UID/GID の変換を担当 User Namespace / id-mapped mount とは? まとめ Processes Files Processes Files Processes
 Files OS 🐧
 User Namespace id-mapped mount Icon pack by Icons8 - https://icons8.com

Slide 53

Slide 53 text

53 User Namespace With a Pod の実装

Slide 54

Slide 54 text

54 Kubelet
 Linux など
 Container Runtime High-Level Low-Level OCI Runtime Spec Container Runtime I nterface User Namespace With a Pod の実装 Pod 作成の流れ

Slide 55

Slide 55 text

55 Kubelet
 Container High-Level OC Runti Spe Container Runtime I nterface User Namespace With a Pod の実装 Kubelet → High-Level Container Runtime apiVersion: v1 kind: Pod metadata: name: cndw2024 spec: hostUsers: false containers: - name: shell command: ["sleep", "infinity"] image: debian

Slide 56

Slide 56 text

56 Kubelet
 Container High-Level OC Runti Spe Container Runtime I nterface CRI を通じて UID の mapping を リクエスト message IDMapping { // host_id is the id on the host. uint32 host_id = 1; // container_id is the id in the container. uint32 container_id = 2; // length is the size of the range to map. uint32 length = 3; } User Namespace With a Pod の実装 Kubelet → High-Level Container Runtime

Slide 57

Slide 57 text

57 Container Runtime High-Level Low-Level OCI Runtime Spec Low-Level CR の features コマン ドを使って id-mapped mount の サポートを確認 $ runc features | jq .linux.mountExtensions { "idmap": { "enabled": true } } User Namespace With a Pod の実装 High-Level → Low-Level - features コマンド

Slide 58

Slide 58 text

58 Container Runtime High-Level Low-Level OCI Runtime Spec OCI Runtime Spec で定義されて いる JSON に従って uid / gid mapping を渡す "uidMappings": [ { "containerID": 0, "hostID": 1000, "size": 32000 } ], "gidMappings": [ User Namespace With a Pod の実装 High-Level → Low-Level - UID/GID Mapping

Slide 59

Slide 59 text

59 Container Runtime High-Level Low-Level OCI Runtime Spec id-mapped mount の情報を渡す "mounts": [ { "containerPath": "/path", "gidMappings": [{ "containerId": 0, "hostId": 1000, "length": 65536 }], … User Namespace With a Pod の実装 High-Level → Low-Level - id-mapped mount

Slide 60

Slide 60 text

60 Linux など
 Low-Level 2つの linux カーネルの機能を⽤いる ✓ User Namespace ✓ id-mapped mount User Namespace With a Pod の実装 Low-Level → Linux

Slide 61

Slide 61 text

61 実際に動かしてみた

Slide 62

Slide 62 text

62 PFNの事業: AI技術のバリューチェーンを垂直統合 ソリューション・製品 計算基盤 AIチップ PFNは、チップ、計算基盤、⽣成AI基盤モデル、ソリューション‧製品まで、AI技術のバリュー チェーンを垂直統合し、ソフトウェアとハードウェアを⾼度に融合することで、競争⼒の⾼い技術の 開発および産業応⽤を進めています。 生成AI基盤モデル 様々な産業‧消費者向けのソリューション‧製品 MN-Core™ MN-Core™ 2 GPUクラスタ MN-3 (MN-Core™ クラスタ) PLaMo Prime(今秋提供予定のLLM) PLaMo Lite(エッジ向けSLM) MN-Core 第三世代 MN-Core™ 2を 計算資源とした クラウドサービス 物質のエネルギー計算モデル PFP LLM向け 推論チップ (2026年提供予定)

Slide 63

Slide 63 text

実際に動かしてみた PFCP / AI ワークロード向けのクラウドサービス (1/2) 63 ● PFN が構築、運⽤する深層学習‧AIワークロード向けのクラウドサービス ○ https://pfcomputing.com/ (2024年10⽉に利⽤受付を開始) ● PFN のエンジニア‧リサーチャが使⽤する環境と同じものを提供 ○ これまで社内向けに計算基盤を開発運⽤してきた経験を元に開発 ● マルチテナント ○ 1つのクラスタを複数のテナントで利⽤可能 ● 実験も学習も推論も ○ 学習だけでなく、推論サーバの運⽤まで幅広いワークロードをサポート 対話型実験環境 分散学習・LLM 推論など

Slide 64

Slide 64 text

実際に動かしてみた PFCP / AI ワークロード向けのクラウドサービス (2/2) 64 ● リソース使⽤状況の可視化 ○ ワークロード状態を観測するためのモニタリングサービスも付随 ● もちろん Kubernetes がベース ○ 深層学習‧AI ワークロード向けにカスタマイズ ■ 2018年から機械学習向けの計算基盤としてKubernetes を 利⽤してきた知⾒を活かして ● 1ノードに複数のテナントを⼊れて利⽤効率を⾼めたい(未提供、検証中) ワークロード‧計算資源監視 管理コンソール UserNamespace With a Pod の出 番

Slide 65

Slide 65 text

65 ✓ High-Level: containerd ≧ 2.0, CRI-O ≧ 1.25 ✓ Low-Level: runc ≧ 1.2.0, crun ≧ 1.9 ✓ OCI Runtime Spec ≧ 1.2.0 ✓ OS: linux kernel ≧ 6.3 🎉containerd v2, Nov 6, 2024 🎉runc 1.2, Oct 22, 2024 実際に動かしてみた 動作の必要要件

Slide 66

Slide 66 text

66 minikube を使った検証環境セット https://github.com/utam0k/minikube/tree/cndw2024 実際に動かしてみた 検証 $ kubectl get nodes -o json | jq .items[0].status.nodeInfo { "architecture": "amd64", "bootID": "554e2aa9-19f8-48e1-9b4e-b8931da0191a", "containerRuntimeVersion": "containerd://2.0.0+unknown", "kernelVersion": "6.5.13", "kubeProxyVersion": "v1.30.0", "kubeletVersion": "v1.30.0", "machineID": "5afad69dc2a84258b8f7e0745a2bba37", "operatingSystem": "linux", "osImage": "Buildroot 2024.02", "systemUUID": "5afad69d-c2a8-4258-b8f7-e0745a2bba37" }

Slide 67

Slide 67 text

67 実際に動かしてみた 検証 $ kubectl apply -f https://k8s.io/examples/pods/user-namespaces-stateless.yaml pod/userns created

Slide 68

Slide 68 text

68 実際に動かしてみた 検証 $ 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 4178444288 65536

Slide 69

Slide 69 text

69 実際に動かしてみた 検証 $ 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 70

Slide 70 text

70 実際に動かしてみた 気がついた事 - Manifest のバリデーション kubernetes/kubernetes/blob/v1.31.3/pkg/apis/core/validation/validation.go#L3594-L3620 func validateHostUsers(spec *core.PodSpec, fldPath *field.Path) field.ErrorList { … if spec.SecurityContext.HostNetwork { allErrs = append(allErrs, field.Forbidden(fldPath.Child("hostNetwork"), "when `pod.Spec.HostUsers` is false")) } if spec.SecurityContext.HostPID { allErrs = append(allErrs, field.Forbidden(fldPath.Child("HostPID"), "when `pod.Spec.HostUsers` is false")) } if spec.SecurityContext.HostIPC { allErrs = append(allErrs, field.Forbidden(fldPath.Child("HostIPC"), "when `pod.Spec.HostUsers` is false")) } … }

Slide 71

Slide 71 text

71 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 が⾮対応で困っている... 😭 実際に動かしてみた 気がついた事 - mount_setattr(2)

Slide 72

Slide 72 text

72 https://elixir.bootlin.com/linux/v6.12/source/fs/nfsd/export.c#L398-L450 id-mapped mount をファイルシステム側が検証をしてくれているか ✓ NFS だとエラーを返してくれる ✓ upstream へ 懸念についてフィードバック済み kubernetes/enhancements#127#issuecomment-2505154828 static int check_export(struct path *path, int *flags, unsigned char *uuid) { … if (is_idmapped_mnt(path->mnt)) { dprintk("exp_export: export of idmapped mounts not yet supported.\n"); return -EINVAL; } … } 実際に動かしてみた 気がついた事 - id-mapped mount の検証

Slide 73

Slide 73 text

73 まとめ

Slide 74

Slide 74 text

74 まとめ KEP-127: Support User Namespaces (Beta) ✓ コンテナ内で安全に UID: 0(≒ root) を使える ⽀える技術 ✓ User Namespace: UID/GIDの分離、マッピング ✓ id-mapped mount: ファイルのマッピング 動かしてみる ✓ いろいろ最新のものが必要 ✓ まだまだ知⾒が少なく、ワナ(楽しいところ)はたくさんありそう

Slide 75

Slide 75 text

We’re hiring! Preferred Networks の基盤技術グループでは採⽤を実施中です! ● 機械学習プラットフォームエンジニア Kubernetes, 社内向け機械学習プラットフォーム、外販クラウドサービスの開発運⽤ キーワード: K8s, オンプレ, GPU, Observability, MLOps, HPC, スケジューラ, AWS,       Front/Backend, コンテナネットワーク, データセンタネットワーク, RDMA, RoCE v2 ● ストレージエンジニア ストレージの企画設計管理運⽤ ● ⼤規模計算基盤エンジニア/ネットワーク‧インフラ運⽤エンジニア クラスタの物理設計、MN-Core™ を含めた先端システム設計等 75 カジュアル⾯談にお気軽にご応募ください

Slide 76

Slide 76 text

Making the real world computable