阅读 50 SEO

Linux内核又躺枪 之《docker挂载volume的权限问题》

Linux内核又躺枪 之《docker挂载volume的权限问题》

我对docker不太成熟的认知!写的不好望指出!互相学习、交流!


对docker的认知

为什么说Linux内核又躺枪了,日常甩锅,只能把锅甩给Linux 内核了,哈哈哈…


docker依赖于Linux的两个内核特性:


Namespaces - 命名空间

Control groups(cgroups)- 控制组

1

2

Namespaces

命名空间提供了一种系统资源的隔离,包括了文件系统、网络、进程等。


docker有以下5种命名空间:


PID:进程隔离

NET:网络管理接口

IPC:管理跨进程通信访问

MNT:管理挂载点

UTS:隔离内核和版本标识

1

2

3

4

5

Control groups

这是Linux内核提供的一种可以限制,记录,隔离物理进程组的机制。他提供了以下功能:


资源限制

优先级设定

资源计量

资源控制

1

2

3

4

docker 基本能力

Namespaces和Control groups带给了容器下面的能力:


文件系统的隔离:每个容器都有自己的root文件系统

进程隔离:每个容器都运行在自己的进程环境中

网络隔离:每个容器间虚拟网络接口和ip地址都是分开的

资源隔离和分组:Control groups可以将CPU和内存之类的资源独立分配给每个docker容器

1

2

3

4

5

6

使用场景

我们在使用docker容器的时候,经常要给容器里面挂载本地服务器目录,从而实现某个文件在宿主机和容器内部都可以访问的效果。


例如:在容器内部进行删除、添加、复制、剪切、读写文件,说白了就是访问挂载的卷


问题介绍 - docker挂载volume的权限问题

报错:一般都是在进行一系列操作抛出权限问题


touch: cannot touch '/var/jenkins/copy_file.log' : Permission denied

can not write to  '/var/jenkins/copy_file.log' . Wrong volume permission?

# 这是在说你没有权限在这个目录里面创建文件,以及写东西

1

2

3

问题根由

因为容器共享宿主机的uid,如果不指定user,容器内部默认使用root用户来运行,容器内部用户的权限与外部用户相同,所以一定要确保容器执行者的权限和挂载数据卷对应

1

扩展干货…(后续会继续补充)

1、为什么docker输出的文件权限为 root?

Docker容器运行的时候,如果没有指定user,容器内部默认以root用户运行


2、怎么确定运行的用户为root?

可以通过容器里的执行用户的id是0,输出文件的权限也是0。


当docker容器运行在宿主机上的时候,仍然只有一个内核。容器共享宿主机的内核,所以所有的uid和gid都受同一个内核来控制。

比如,当一个进程尝试去写文件,内核会检查创建这个进程的的user的uid和gid,来决定这个进程是否有权限修改这个文件。


# 怎么查看用户的UID和GID?

(1)id 用户名

(2)cat /etc/passwd | grep 用户名

# root:x:0:0:root:/root:/bin/bash

# 两个bai0就是uid和gid

1

2

3

4

5

3、为什么容器里的用户名不一定和宿主内核一样呢?

比如,test 容器的用户叫做 test, 而本机没有 test 这个用户。这是因为username不是Linux kernel的一部分。简单的来说,username是对uid的一个映射。由于权限控制的依据是uid,而不是username。


That’s because the username (and group names) that show up in common linux tools aren’t part of the kernel, but are managed by external tools (/etc/passwd, LDAP, Kerberos, etc). So, you might see different usernames, but you can’t have different privileges for the same uid/gid, even inside different containers

1

解决方案

方案一 : 关闭SELinux

临时关闭(不用重启机器)SELinux

# 执行命令

setenforce 0 

1

2

修改配置文件需要重启机器(或者使用source使其生效,没有亲测,不确定是否有效)

# 修改/etc/selinux/config 文件

将SELINUX=enforcing改为SELINUX=disabled

1

2

方案二:指定user

使用run的时候指定

# 通过volume挂载的方式,指定运行user为1001, 启动容器 test:

docker run -d --name test -p 8080:8080 -u 1001:1001 -v $(pwd):/tmp test

# docker run -u 可以指定宿主机运行docker命令的用户, -u指定的uid就是docker实际运行的进程拥有者

1

2

3

亦可以在dockerfile的时候指定

RUN useradd -r -u 1001 -g test test

USER test

# -g:指定用户所属的群组。值可以使组名也可以是GID。用户组必须已经存在的,期默认值为100,即users。

# -u:指定用户ID号。该值在系统中必须是唯一的。0~499默认是保留给系统用户账号使用的,所以该值必须大于499。

# -r:建立系统账号。

# USER指令用于指定容器执行程序的用户身份,默认是 root用户。

————————————————

版权声明:本文为CSDN博主「浮世绘太空」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/weixin_40960688/article/details/110413297


文章分类
后端
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 gxwowoo@163.com 举报,一经查实,本站将立刻删除。
相关推荐