首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Docker和--userns-remap,如何管理主机和容器之间共享数据的卷权限?

Docker和--userns-remap,如何管理主机和容器之间共享数据的卷权限?
EN

Stack Overflow用户
提问于 2016-02-09 11:58:40
回答 4查看 48.9K关注 0票数 115

在docker中,在容器中创建的文件在从主机上检查它们时往往具有不可预测的所有权。默认情况下,卷上文件的所有者是root (uid 0),但是一旦容器中涉及到非根用户帐户并将其写入文件系统,所有者就会或多或少地从主机的角度变得随机。

当您需要使用调用docker命令的同一个用户帐户从主机访问卷数据时,会出现问题。

典型的解决办法是

  • 在Dockerfile中强制用户在创建时使用uIDs (不可移植)
  • 将主机用户的UID作为环境变量传递给docker run命令,然后在入口点脚本中的卷上运行一些chown命令。

这两种解决方案都可以控制容器外部的实际权限。

我预计用户名称空间将是这个问题的最终解决方案。我已经运行了一些测试,最近发布的版本1.10和-用户-重新映射设置到我的桌面帐户。但是,我不确定它是否能使挂载卷上的文件所有权更容易处理,我担心它实际上可能正好相反。

假设我启动了这个基本容器

代码语言:javascript
复制
docker run -ti -v /data debian:jessie /bin/bash
echo 'hello' > /data/test.txt
exit

然后检查来自主机的内容:

代码语言:javascript
复制
ls -lh /var/lib/docker/100000.100000/volumes/<some-id>/_data/

-rw-r--r-- 1 100000 100000 6 Feb  8 19:43 test.txt

这个号码'100000‘是我的主机用户的一个子UID,但是由于它不符合我的用户的UID,所以我仍然不能编辑没有特权的test.txt。这个子用户似乎与我在码头外的实际普通用户没有任何关联。不是映射回来的。

本文前面提到的解决方案包括在主机和容器之间对UID,但是由于名称空间中发生的UID->sub-UID映射,UID不再工作了。

那么,是否有一种方法可以在启用用户命名空间(以提高安全性)的情况下运行对接器,同时仍然可以让运行停靠器的主机用户拥有卷上生成的文件?

EN

回答 4

Stack Overflow用户

发布于 2016-03-07 21:37:25

如果您可以预先安排用户和组,那么就可以以特定的方式分配UID和GID,这样宿主用户就可以与容器中的命名空间用户相对应。

下面是一个示例(Ubuntu14.04,Docker 1.10):

  1. 使用固定的数字ID创建一些用户: 用户添加-u 5000 ns1组添加-g 500000 ns1-根组添加-g 501000 ns1-user1用户添加-u 500000 -g ns1-root用户添加-u 501000 -g ns1-user1ns1 -m
  2. 手动编辑/etc/subuid/etc/subgid文件中自动生成的从属ID范围: ns1:500000:65536 (注意,由于ns1-rootns1-user1MAX_UIDMAX_GID限制,/etc/login.defs没有记录)
  3. /etc/default/docker中启用用户命名空间: DOCKER_OPTS="--userns-remap=ns1“ 重新启动守护进程service docker restart,确保创建/var/lib/docker/500000.500000目录。 现在,在容器中有root user1**,,在主机上-** ns1-root ns1-user1**,具有匹配的ID**。 UPDATE:以保证非根用户在容器中有固定的ID(例如user1 1000:1000),在图像构建期间显式地创建它们。

试驾:

  1. 准备卷目录 mkdir /vol1 chown ns1-root:ns1-root /vol1
  2. 从容器里试一试 docker -rm -ti -v /vol1:/vol1 busybox回显“Hellofrom容器”>/vol1/文件退出
  3. 试着从主机上 passwd ns1-root登录ns1-root cat /vol1/file“可以写”>> /vol1/file“

不是便携的,看起来像黑客,但很有效。

票数 58
EN

Stack Overflow用户

发布于 2019-02-23 21:57:36

一个解决办法是在构建时间上动态分配用户的uid,以匹配主机。

示例Dockerfile

代码语言:javascript
复制
FROM ubuntu
# Defines argument which can be passed during build time.
ARG UID=1000
# Create a user with given UID.
RUN useradd -d /home/ubuntu -ms /bin/bash -g root -G sudo -u $UID ubuntu
# Switch to ubuntu user by default.
USER ubuntu
# Check the current uid of the user.
RUN id
# ...

然后将其构建为:

代码语言:javascript
复制
docker build --build-arg UID=$UID -t mycontainer .

并以下列方式运行:

代码语言:javascript
复制
docker run mycontainer

如果已存在容器,则使用以下Dockerfile创建包装器容器

代码语言:javascript
复制
FROM someexistingcontainer
ARG UID=1000
USER root
# This assumes you've the existing user ubuntu.
RUN usermod -u $UID ubuntu
USER ubuntu

这可以在docker-compose.yml中包装,例如:

代码语言:javascript
复制
version: '3.4'
services:
  myservice:
    command: id
    image: myservice
    build:
      context: .
    volumes:
    - /data:/data:rw

然后构建并运行如下:

代码语言:javascript
复制
docker-compose build --build-arg UID=$UID myservice; docker-compose run myservice
票数 6
EN

Stack Overflow用户

发布于 2022-11-05 17:46:58

在某些情况下,码头形象是广泛共享的,不能修改。我一直在使用一种“蛮力”方法,每次启动容器并切换到容器中时,都会动态地在容器中创建匹配的用户。诚然,它很难看,但它只需要50行代码,并且一直运行良好:

https://github.com/thesofproject/sof/blob/0a4b1d62d5b31b41/scripts/sudo-cwd.sh

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35291520

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档