一、Docker容器中用户权限管理
Linux系统的权限管理是由uid和gid负责,Linux系统会检查创建进程的uid和gid,以确定它是否有足够的权限修改文件,而非是通过用户名和用户组来确认。
同样,在docker容器中主机上运行的所有容器共享同一个内核也可以理解为共享权限管理方式。
在volume挂载目录时默认属于root用户,如果没有chown给其他用户的话,在Volume卷中创建的文件和文件夹将拥有与在容器中的卷相同的uid:gid(数字)。
1.1、容器启动的权限规则
容器启动的时候,容器中的用户
没有指定用户:默认使用root
指定用户:使用指定用户
1.2、 namespace隔离技术
namespace隔离技术:docker容器内部依然是以"root"的权限管理,但实际只有普通用户的权限,从而达到权限隔离的效果。
1.3、如果在容器内对挂载目录下的文件进行了操作,则相应文件的所有者就会升级为root,如果容器中只有非root用户的权限,就无法对这些文件进行操作了。
如果在容器内对挂载目录下的文件进行了操作,则相应文件的所有者就会升级为root,如果容器中只有非root用户的权限,就无法对这些文件进行操作了。
二,我们这里使用elasticsearch作为案例
构成镜像的dockerfile
我们创建了es用户
启动cmd命令是通过es用户启动的
FROM centos:7.7.1908
# 创建者
MAINTAINER HuiDian <www.smartdot.com.cn>
COPY elasticsearch-7.4.2-linux-x86_64.tar.gz /home
COPY elasticsearch-analysis-ansj-7.4.2.0-release.zip /home
COPY elasticsearch.yml /home
COPY jvm.options /home
ENV JAVA_HOME /docker/elasticsearch-7.4.2/jdk
RUN mkdir -p /docker/ &&\
yum install -y unzip zip lrzsz vim &&\
# 解压
mv /home/elasticsearch-7.4.2-linux-x86_64.tar.gz /docker/ &&\
cd /docker &&\
tar -zxvf elasticsearch-7.4.2-linux-x86_64.tar.gz &&\
# ansj 分词器 解压到指定目录
unzip /home/elasticsearch-analysis-ansj-7.4.2.0-release.zip -d /docker/elasticsearch-7.4.2/plugins/ansj &&\
# 添加配置文件
mv /home/elasticsearch.yml /docker/elasticsearch-7.4.2/config/ &&\
mv /home/jvm.options /docker/elasticsearch-7.4.2/config/ &&\
# 创建es用户
useradd es && chown -R es:es /docker/elasticsearch-7.4.2 &&\
# 删掉安装包
rm -rf /docker/elasticsearch-7.4.2-linux-x86_64.tar.gz &&\
rm -rf /home/elasticsearch-analysis-ansj-7.4.2.0-release.zip
# cmd,run命令使用es用户启动
USER es
EXPOSE 9200
EXPOSE 9300
CMD "/docker/elasticsearch-7.4.2/bin/elasticsearch"
当不使用数据卷启动后
容器中的用户是es
/docker/elasticsearch-7.4.2/data 的用户也是es
容器正常启动
docker run -d \
--name elasticsearch \
-p 9200:9200 \
-p 9300:9300 \
elasticsearch_huidian:7.4.2
我们查看一下未挂载数据卷时候的目录权限和当前用户
docker rm -f elasticsearch
docker run -id --name=elasticsearch elasticsearch_huidian:7.4.2
docker exec -it elasticsearch bash -c "whoami && id"
docker exec -it elasticsearch bash -c "ls -la /docker/elasticsearch-7.4.2/data"
当使用数据卷启动后,启动失败
启动容器
docker rm -f elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -v /home/hd/docker/elasticsearch/data:/docker/elasticsearch-7.4.2/data elasticsearch_huidian:7.4.2
docker ps -a
我们查看挂载数据卷时候的目录权限和当前用户
docker rm -f elasticsearch
docker run -it --name=elasticsearch -v /home/hd/docker/elasticsearch/data:/docker/elasticsearch-7.4.2/data elasticsearch_huidian:7.4.2 bash -c "whoami && id"
docker rm -f elasticsearch
docker run -it --name=elasticsearch -v /home/hd/docker/elasticsearch/data:/docker/elasticsearch-7.4.2/data elasticsearch_huidian:7.4.2 bash -c "ls -la /docker/elasticsearch-7.4.2/data"
说明
当容器启动的时候,如果容器要对数据卷的主机目录进行修改或者添加,那么会将权限提升为root。也就是说/docker/elasticsearch-7.4.2/data目录和nodes目录会将es的权限提升为root,也就是当前我们看到的。
启动失败说明
当"es"用户的进程访问"/docker/elasticsearch-7.4.2/data"目录时,没有root权限,会出现 Permission denied的问题。
宿主机上的数据卷目录
当前路径下"data"目录的拥有者是"root",这是因为这个目录是Docker进程缺省创建出来的。
如果容器要对数据卷的主机目录进行修改或者添加,那么会将权限提升为root。导致失败,应该怎么处理?
方式1–修改数据卷权限
把当前目录的拥有者赋值给uid 1000,再启动"elasticsearch"容器就一切正常了
chown -R 1000:1000 /home/hd/docker/elasticsearch/data
docker rm -f elasticsearch
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -v /home/hd/docker/elasticsearch/data:/docker/elasticsearch-7.4.2/data elasticsearch_huidian:7.4.2
docker ps -a
当我们再进入容器内部查看"/home/hd/docker/elasticsearch/data"目录的权限,其拥有者已经变成 “es”
在宿主机上我们看到的"data"目录的拥有者是"hd",这是因为"hd"用户的uid是1000。
而容器中es用户的uid也是1000,说明hd和es本质是同一个用户
docker exec -it elasticsearch bash -c “ls -la /docker/elasticsearch-7.4.2/data”