Skip to content

Commit 5c83d94

Browse files
committed
Update note
1 parent 8a0a213 commit 5c83d94

File tree

1 file changed

+116
-0
lines changed

1 file changed

+116
-0
lines changed
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# 【小记】在 Google Colab 上基于 Apptainer 运行 GPU 容器
2+
3+
最近想到了可能的创新点,准备开始做实验了。在前期我准备先薅一波提供免费 GPU 运算资源的平台的羊毛,但这些平台提供的免费时长并不多,可能这家配额跑完了就要换下家,如果每次都要重新搭建环境多少有些不方便。
4+
5+
![subaru_nerd-2025-01-18](https://raw.githubusercontent.com/cat-note/bottleassets/main/img/subaru_nerd-2025-01-18.png)
6+
7+
那咱用容器化技术不就行啦!直接把环境打包成镜像,哪个平台都能跑。
8+
9+
比起 Docker,这回咱决定采用**更为轻量的** Apptainer(前身为 Singularity):
10+
11+
* Apptainer 默认以普通用户的身份运行容器,无需类似于 root 用户的特权,不像 Docker Daemon 那样必须要运行在特权用户下。(因而更安全,也更容易安装部署,不会有什么权限问题)
12+
* Apptainer 针对高性能计算(HPC)这种并行场景进行了优化(虽然我还不太用得上)。
13+
* Apptainer 支持 Docker 镜像,体验上近乎无缝(这个是最爽滴)。
14+
15+
这篇笔记主要记录一下咱在 Google Colab 上基于 Apptainer 运行 GPU 容器时的踩坑和爬出坑的过程。
16+
17+
## 1. 安装 Apptainer
18+
19+
这里不多赘述,图快的话咱主要推荐以下两种安装方式:
20+
21+
### 1.1. 利用官方脚本安装
22+
23+
* [官方文档](https://apptainer.org/docs/admin/1.3/installation.html#install-unprivileged-from-pre-built-binaries)
24+
25+
注:文档中提到在执行脚本前可能需要安装 `curl`, `cpio`, `rpm2cpio` 等必要的工具:
26+
27+
```bash
28+
sudo apt-get update
29+
# rpm2cpio 是 rpm 包的工具
30+
sudo apt-get install -y curl cpio rpm
31+
```
32+
33+
34+
### 1.2. 利用包管理器安装
35+
36+
* [官方文档](https://apptainer.org/docs/admin/1.3/installation.html#install-ubuntu-packages)
37+
38+
Colab 默认是 Ubuntu 系统,copy 官方文档中的命令就能顺利安装了~
39+
40+
## 2. 尝试跑一下 hello-world 镜像
41+
42+
### 2.1. 构建 .sif 文件
43+
44+
Apptainer 可以直接拉取 Docker Hub 上的镜像并构建成 `.sif` 单文件:
45+
46+
```bash
47+
apptainer build hello.sif docker://hello-world
48+
```
49+
50+
![build_hello-2025-01-18](https://raw.githubusercontent.com/cat-note/bottleassets/main/img/build_hello-2025-01-18.png)
51+
52+
### 2.2. 建立普通用户
53+
54+
Colab 默认在 root 用户下执行命令,这里建立一个普通用户 `somebottle`
55+
56+
```bash
57+
adduser --home /home/somebottle --gecos "" --shell /bin/bash --disabled-password somebottle
58+
```
59+
60+
* root 用户当然是可以运行 Apptainer 容器的,但为了安全起见,咱接下来会尝试用普通用户来运行容器。
61+
62+
### 2.3. 启动容器
63+
64+
Colab **对 root 用户的权限有所限制**,如果直接尝试启动容器会出现挂载问题:
65+
66+
```bash
67+
apptainer run hello.sif
68+
# >> FATAL: container creation failed: mount hook function failure: mount overlay->/var/lib/apptainer/mnt/session/final error: while mounting overlay: can't mount overlay filesystem to /var/lib/apptainer/mnt/session/final: while setting effective capabilities: CAP_DAC_READ_SEARCH is not in the permitted capability set
69+
```
70+
71+
* 相关 issue:https://github.com/apptainer/apptainer/issues/1041
72+
73+
利用 `setcap` 进行权限设定还是麻烦了,这里我根据 issue 中的指引,直接在一个新的**命名空间**下运行了容器:
74+
75+
```bash
76+
# 在 root 用户下执行这条命令,容器内用户为 root
77+
unshare -r apptainer run hello.sif
78+
```
79+
> `unshare -r` 建立一个新的**用户命名空间**,并把当前用户映射为命名空间内的 root 用户,这个命名空间内的进程将会默认拥有完整的 capabilities 权限集。
80+
81+
* 💡 注:如果在 root 用户下执行上面这条命令,其实仍然相当于在特权用户下启动了容器。
82+
83+
---
84+
85+
✨ 或者**以普通用户的身份**运行容器:
86+
87+
```bash
88+
# 以 somebottle 身份启动容器,容器内用户为 somebottle
89+
sudo -u somebottle apptainer run hello.sif
90+
```
91+
92+
> Apptainer 默认借助用户命名空间来运行容器,系统应支持以非特权方式建立用户命名空间,经测试 Colab 已经满足了这点。具体要求可查看[文档](https://apptainer.org/docs/admin/1.3/user_namespace.html)
93+
94+
---
95+
96+
✨ 为了能**让普通用户在容器内以 root 用户的身份运行**,可以加上 `--fakeroot` 选项:
97+
98+
```bash
99+
# 以 somebottle 身份启动容器,容器内用户为 root
100+
sudo -u somebottle apptainer run --fakeroot hello.sif
101+
```
102+
103+
具体行为可见[官方文档](https://apptainer.org/docs/user/1.3/fakeroot.html)说明。
104+
105+
106+
107+
108+
TODO: sudo -E -u somebottle <command> ,这里 -E 的作用是否需要阐释。注:新的用户命名空间建立时默认会**继承**当前进程的环境变量。
109+
110+
111+
112+
113+
114+
115+
116+

0 commit comments

Comments
 (0)