现象
将主机上的目录挂载到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
下的大多数内容,其他更多的文件内容是不允许的。
解决办法
目前至少有以下三种方式解决挂载的目录没有权限的问题:
- 修改文件安全性标签
- 关闭
SELinux
- 使用特权容器
下面分别介绍具体三种解决办法
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