修复 docker 挂载 volume 提示 Permission denied 的所有方法,包括不关闭 SELinux

现象

将主机上的目录挂载到docker容器中后,访问挂载的文件出现如下的提示:

[root@localhost ~]#docker run --rm -ti -v /root/.ssh/:/root/.ssh/ alpine
/ # ls ~/.ssh/
ls: can't open '/root/.ssh/': Permission denied

原因

当使用SELinux 来控制容器中的进程时。
docker 默认情况下使用 system_u:system_r:svirt_lxc_net_t:s0 标签运行。
svirt_lxc_net_t 类型只允许 读取 & 执行 /usr 下的大多数内容,其他更多的文件内容是不允许的。

解决办法

目前至少有以下三种方式解决挂载的目录没有权限的问题:

  1. 修改文件安全性标签
  2. 关闭 SELinux
  3. 使用特权容器

下面分别介绍具体三种解决办法

1. 修改文件安全性标签

修改文件安全性标签也有两种方式,分为手动和自动添加。

1.1 自动添加

新版本 docker 命令已经支持在启动时通过 -v 参数自动修改挂载对象的安全性标签了,具体使用方式为给-v 参数最后加上:z参数。

比如上面的命令修改成:

docker run --rm -ti -v /root/.ssh:/root/.ssh:z alpine

注意:-v 参数加上 :Z时,大写的Z和小写的Z是两个参数,产生的效果不同。(感兴趣的可以搜索多类别安全性(MCS)标签进一步了解)

1.2 手动添加

通过执行 chcon -Rt svirt_sandbox_file_t /root/.ssh 来修改安全性标签

[root@localhost ~]# chcon -Rt svirt_sandbox_file_t /root/.ssh
[root@localhost ~]# ls -Z /root/.ssh
-rw-------. root root unconfined_u:object_r:container_file_t:s0 authorized_keys

如果提示chcon: can't apply partial context to unlabeled file 的话,执行下面这行命令后重新执行上面的命令就好了

[root@localhost ~]# chcon -R -h system_u:object_r:xxxx_t:s0 /root/.ssh

chcon 命令使用方法:

# 更改安全性文本的格式如下
chcon [-R] [-t type] [-u user] [-r role] 文件或者目录

选顷不参数: 
-R  :连同该目录下癿次目录也同时修改; 
-t  :后面接安全性本文的类型字段!例如 httpd_sys_content_t ; 
-u  :后面接身份识别,例如 system_u; 
-r  :后面街觇色,例如 system_r

2. 关闭 Selinux

关闭 SELinux 有两种关闭方式。

2.1 临时关闭
第一种是临时关闭,通过执行下面的命令就可以关闭,但是机器重启会恢复成原来的状态。

setenforce 0

2.2 永久关闭
第二种通过修改 selinux 配置文件 etc/selinux/config的方式,将文件中的 SELINUX=enforcing 改为 SELINUX=disabled后保存后退出即可。
更改后的内容如下:

# This file controls the state of SELinux on the system.
# SELINUX= can take one of these three values:
#     enforcing - SELinux security policy is enforced.
#     permissive - SELinux prints warnings instead of enforcing.
#     disabled - No SELinux policy is loaded.
SELINUX=disabled
# SELINUXTYPE= can take one of three two values:
#     targeted - Targeted processes are protected,
#     minimum - Modification of targeted policy. Only selected processes are protected. 
#     mls - Multi Level Security protection.
SELINUXTYPE=targeted

此时当前selinux防火墙的安全策略仍为Enforcing,配置文件不是即时生效的,需要重启才能生效。

3. 使用特权容器

在运行容器的时候,给容器加上 --privileged=true 参数就可以启动一个特权容器

docker run -i -t -v /soft:/soft --privileged=true 686672a1d0cc /bin/bash
### 解决 Docker 权限被拒绝问题 当遇到 `permission denied` 错误时,通常是由于当前用户缺乏必要的权限来访问 Docker 套接字 `/var/run/docker.sock` 或者容器内的文件系统。以下是几种常见的解决方案: #### 方法一:调整 Docker 套接字权限 对于所有用户都需要使用 Docker 的情况,可以修改 Docker 套接字的权限设置为 666,使得任何用户都能对其进行读写操作。 ```bash sudo chmod 666 /var/run/docker.sock ``` 这种方法简单直接,但存在安全隐患,因为这会让所有本地用户都能够控制 Docker 守护进程[^1]。 #### 方法二:创建并加入 Docker 用户组 更为安全的做法是创建一个新的名为 `docker` 的用户组,并将需要使用的用户添加进去。这样只有特定用户才能管理 Docker。 ```bash sudo groupadd docker # 添加用户组 sudo gpasswd -a ${USER} docker # 将当前用户添加至用户组 newgrp docker # 更新用户组 ``` 完成上述配置后,重新启动终端或注销再登录即可生效[^2]。 #### 方法三:更改容器内部用户的默认身份 如果是在容器内遇到了权限足的情况,则可以在执行命令时指定以 root 身份运行,从而获得更高的权限级别。 ```bash docker exec -it --user=root <container_id> /bin/sh ``` 此方式适用于那些确实需要更高权限的操作场景下[^3]。 #### 方法四:赋予宿主机目录适当权限 有时也会碰到试图从宿主机进入已挂载到容器中的某个路径却遭遇权限错误的情形。此时应该确保该路径下的文件夹拥有足够的权限供目标用户访问。 ```bash sudo chmod -R 777 /path/to/host/directory ``` 请注意这样做可能会带来潜在的安全风险,在生产环境中应谨慎考虑是否采用这种做法[^5]。 #### 方法五:启用特权模式与禁用 SELinux 某些情况下可能还需要进一步放宽限制条件,比如通过开启 `-privileged=true` 参数允许容器享有更多底层资源访问权;或者是暂时停用 SELinux 政策以便绕过其强加的各种约束。 ```bash docker run -i -t -v /soft:/soft --privileged=true <image_id> /bin/bash setenforce 0 # 关闭SELinux强制模式(需root权限) ``` 过这些措施同样涉及到安全性折衷的问题,因此建议仅在必要时候才采取相应行动[^4]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值