问题描述
docker
容器中生成的文件,在宿主机上无法操作。在宿主机上通过ll
命令可以看到,它的拥有者是root
,而我们一般工作中很少能有root
权限,甚至删除都必须再去镜像里操作。
原因描述
这里存在一个docker
容器非常奇怪的实现。
在存在挂载的情况下:
容器中如果使用root
用户生成的文件,即在容器中的所有者是root
,那么它在宿主机中,所有者也是宿主机的root
用户,即容器内外的权限一致。其他用户同理。
内外对用户的标识采用id
进行映射。即:容器内id=1000
的用户与宿主机id=1000
的用户是对应的。即使容器内外相同id
对应的用户名不同。
可选方案
方案一: 在容器中使用与宿主机相同的用户id
进行操作
方案二: 在容器中使用root
用户操作,并在容器中更改生成的文件的权限
方案一
使用方法
-
docker
命令中,docker run -it -u $(id -u):$(id -g) llama-factory-llama-factory /bin/bash
-
docker-compose.yml
中,设置services.user=$(id -u):$(id -g)
$id -u
和id -g
获取当前用户的id
和用户组id
缺点
一些代码很可能需要访问/
目录,非root
用户没有权限
以THUDM/ChatGLM2-6B
项目为例,需要访问/.cache
和/.triton
(其实一般大模型训练都需要访问这两个地址),代码会报错。这时候需要将这些目录挂载出去,或者给当前用户所需要的权限。
以上面的命令为例,需要修改为:
docker run -it -u $(id -u):$(id -g) -v ./.cache:/.cache -v ./.triton:/.triton llama-factory-llama-factory /bin/bash
方案二
使用方法
在容器中使用root
用户操作,并在容器中更改生成的文件的权限
即:大多数镜像,启动后不指定用户,默认是用root
进入,在生成完文件后,修改文件的权限
bash
chown 1000:1000 /path/to/file_or_directory
chmod 755 /path/to/file_or_directory
这里的
1000:1000
指的是宿主机的用户id
和组id
缺点
每个文件都需要去赋权,很麻烦。如果只是为了少数文件可以用此方法。毕竟它省去了一些无用的挂载,减少了对宿主机的污染。
疑问
为什么不能设计成这样:
宿主机上,哪个用户下使用docker指令,docker生成的文件就是哪个用户的权限,即容器中的root
权限与宿主机的用户权限对应。