阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

理解 Docker 容器中的 uid 和 gid

523次阅读
没有评论

共计 3085 个字符,预计需要花费 8 分钟才能阅读完成。

默认情况下,容器中的进程以 root 用户权限运行,并且这个 root 用户和宿主机中的 root 是同一个用户。听起来是不是很可怕,因为这就意味着一旦容器中的进程有了适当的机会,它就可以控制宿主机上的一切!本文我们将尝试了解用户名、组名、用户 id(uid)和组 id(gid)如何在容器内的进程和主机系统之间映射,这对于系统的安全来说是非常重要的。说明:本文的演示环境为 Ubuntu 16.04(下图来自互联网)。

理解 Docker 容器中的 uid 和 gid

先来了解下 uid 和 gid

uid 和 gid 由 Linux 内核负责管理,并通过内核级别的系统调用来决定是否应该为某个请求授予特权。比如当进程试图写入文件时,内核会检查创建进程的 uid 和 gid,以确定它是否有足够的权限修改文件。注意,内核使用的是 uid 和 gid,而不是用户名和组名
简单起见,本文中剩下的部分只拿 uid 进行举例,系统对待 gid 的方式和 uid 基本相同。

很多同学简单地把 docker 容器理解为轻量的虚拟机,虽然这简化了理解容器技术的难度但是也容易带来很多的误解。事实上,与虚拟机技术不同:同一主机上运行的所有容器共享同一个内核 (主机的内核)。容器化带来的巨大价值在于所有这些独立的容器(其实是进程) 可以共享一个内核。这意味着即使由成百上千的容器运行在 docker 宿主机上,但 内核控制的 uid 和 gid 则仍然只有一套 。所以同一个 uid 在宿主机和容器中代表的是同一个用户(即便在不同的地方显示了不同的用户名)。
注意,由于普通的用来显示用户名的 Linux 工具并不属于内核(比如 id 等命令),所以我们可能会看到同一个 uid 在不同的容器中显示为不同的用户名。但是对于相同的 uid 不能有不同的特权,即使在不同的容器中也是如此。

如果你已经了解了 Linux 的 user namespace 技术,参考《Linux Namespace : User》,你需要注意的是到目前为止,docker 默认并没有启用 user namesapce,这也是本文讨论的情况。笔者会在接下来的文章中介绍如何配置 docker 启用 user namespace。

容器中默认使用 root 用户

如果不做相关的设置,容器中的进程默认以 root 用户权限启动,下面的 demo 使用 ubuntu 镜像运行 sleep 程序:

$ docker run -d  –name sleepme ubuntu sleep infinity

注意上面的命令中并没有使用 sudo。笔者在宿主机中的登录用户是 nick,uid 为 1000:

理解 Docker 容器中的 uid 和 gid

在宿主机中查看 sleep 进程的信息:

$ ps aux | grep sleep

理解 Docker 容器中的 uid 和 gid

sleep 进程的有效用户名称是 root,也就是说 sleep 进程具有 root 权限。
然后进入容器内部看看,看到的情况和刚才一样,sleep 进程也具有 root 权限:

理解 Docker 容器中的 uid 和 gid

那么,容器内的 root 用户和宿主机上的 root 用户是同一个吗?
答案是:是的,它们对应的是同一个 uid。原因我们在前面已经解释过了:整个系统共享同一个内核,而内核只管理一套 uid 和 gid。

其实我们可以通过数据卷来简单的验证上面的结论。在宿主机上创建一个只有 root 用户可以读写的文件:

 理解 Docker 容器中的 uid 和 gid

然后挂载到容器中:

$ docker run –rm -it -w=/testv -v $(pwd)/testv:/testv ubuntu

在容器中可以读写该文件:

理解 Docker 容器中的 uid 和 gid

我们可以通过 Dockerfile 中的 USER 命令或者是  docker run 命令的 –user 参数指定容器中进程的用户身份。下面我们分别来探究这两种情况。

在 Dockerfile 中指定用户身份

我们可以在 Dockerfile 中添加一个用户 appuser,并使用 USER 命令指定以该用户的身份运行程序,Dockerfile 的内容如下:

FROM ubuntu
RUN useradd -r -u 1000 -g appuser
USER appuser
ENTRYPOINT [“sleep”, “infinity”]

编译成名称为 test 的镜像:

$ docker build -t test .

理解 Docker 容器中的 uid 和 gid

用 test 镜像启动一个容器:

$ docker run -d –name sleepme test

在宿主机中查看 sleep 进程的信息:

理解 Docker 容器中的 uid 和 gid

这次显示的有效用户是 nick,这是因为在宿主机中,uid 为 1000 的用户的名称为 nick。再进入到容器中看看:

$ docker exec -it sleepme bash

理解 Docker 容器中的 uid 和 gid

容器中的当前用户就是我们设置的 appuser,如果查看容器中的 /etc/passwd 文件,你会发现 appuser 的 uid 就是 1000,这和宿主机中用户 nick 的 uid 是一样的。

让我们再创建一个只有用户 nick 可以读写的文件:

理解 Docker 容器中的 uid 和 gid

同样以数据卷的方式把它挂载到容器中:

$ docker run -d –name sleepme -w=/testv -v $(pwd)/testv:/testv test

理解 Docker 容器中的 uid 和 gid

在容器中 testfile 的所有者居然变成了 appuser,当然 appuser 也就有权限读写该文件。

这里到底发生了什么?而这些又这说明了什么?
首先,宿主机系统中存在一个 uid 为 1000 的用户 nick。其次容器中的程序是以 appuser 的身份运行的,这是由我们通过 USER appuser 命令在 Dockerfile 程序中指定的。
事实上,系统内核管理的 uid 1000 只有一个,在宿主机中它被认为是用户 nick,而在容器中,它则被认为是用户 appuser。
所以有一点我们需要清楚:在容器内部,用户 appuser 能够获取容器外部用户 nick 的权利和特权。在宿主机上授予用户 nick 或 uid 1000 的特权也将授予容器内的 appuser。

从命令行参数中自定用户身份

我们还可以通过 docker run 命令的 –user 参数指定容器中进程的用户身份。比如执行下面的命令:

$ docker run -d –user 1000 –name sleepme ubuntu sleep infinity

理解 Docker 容器中的 uid 和 gid

因为我们在命令行上指令了参数 –user 1000,所以这里 sleep 进程的有效用户显示为 nick。进入到容器内部看一下:

$ docker exec -it sleepme bash

理解 Docker 容器中的 uid 和 gid

这是个什么情况?用户名称居然显示为 “I have no name!”!去查看 /etc/passwd 文件,里面果然没有 uid 为 1000 的用户。即便没有用户名称,也丝毫不影响该用户身份的权限���它依然可以读写只有 nick 用户才能读写的文件,并且用户信息也由 uid 代替了用户名:

理解 Docker 容器中的 uid 和 gid

需要注意的是,在创建容器时通过 docker run –user 指定的用户身份会覆盖掉 Dockerfile 中指定的值。
我们重新通过 test 镜像来运行两个容器:

$ docker run -d test

查看 sleep 进程信息:

理解 Docker 容器中的 uid 和 gid

$ docker run –user 0 -d test

再次查看 sleep 进程信息:

理解 Docker 容器中的 uid 和 gid

指定了 –urser 0 参数的进程显示有效用户为 root,说明命令行参数 –user 0 覆盖掉了 Dockerfile 中 USER 命令的设置。

总结

从本文中的示例我们可以了解到,容器中运行的进程同样具有访问主机资源的权限(docker 默认并没有对用户进行隔离),当然一般情况下容器技术会把容器中进程的可见资源封锁在容器中。但是通过我们演示的对数据卷中文件的操作可以看出,一旦容器中的进程有机会访问到宿主机的资源,它的权限和宿主机上用户的权限是一样的。所以比较安全的做法是为容器中的进程指定一个具有合适权限的用户,而不要使用默认的 root 用户。当然还有更好的方案,就是应用 Linux 的 user namespace 技术隔离用户,笔者会在接下来的文章中介绍如何配置 docker 开启 user namespace 的支持。

 

 

 

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计3085字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19351
评论数
4
阅读量
8000200
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
CSDN,你是老太太喝粥——无齿下流!

CSDN,你是老太太喝粥——无齿下流!

CSDN,你是老太太喝粥——无齿下流! 大家好,我是星哥,今天才思枯竭,不写技术文章了!来吐槽一下 CSDN。...
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

4盘位、4K输出、J3455、遥控,NAS硬件入门性价比之王

  4 盘位、4K 输出、J3455、遥控,NAS 硬件入门性价比之王 开篇 在 NAS 市场中,威...
星哥带你玩飞牛NAS-4:飞牛NAS安装istore旁路由,家庭网络升级的最佳实践

星哥带你玩飞牛NAS-4:飞牛NAS安装istore旁路由,家庭网络升级的最佳实践

星哥带你玩飞牛 NAS-4:飞牛 NAS 安装 istore 旁路由,家庭网络升级的最佳实践 开始 大家好我是...
免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

免费无广告!这款跨平台AI RSS阅读器,拯救你的信息焦虑

  免费无广告!这款跨平台 AI RSS 阅读器,拯救你的信息焦虑 在算法推荐主导信息流的时代,我们...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...
Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集

Prometheus:监控系统的部署与指标收集 在云原生体系中,Prometheus 已成为最主流的监控与报警...
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...
星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

  星哥带你玩飞牛 NAS-16:飞牛云 NAS 换桌面,fndesk 图标管理神器上线! 引言 哈...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...