前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >rootless Podman如何工作?【Programming】

rootless Podman如何工作?【Programming】

作者头像
Potato
修改2019-11-25 15:13:30
2.2K0
修改2019-11-25 15:13:30
举报

了解Podman如何利用用户名称空间在无根模式下运行。

图片来源:Opensource.com
图片来源:Opensource.com

上一篇有关用户名称空间和Podman的文章中,我讨论了如何使用Podman命令来启动具有不同用户名称空间的不同容器,从而更好地分隔容器。Podman还利用用户名称空间来以无根模式运行。基本上,当非特权用户运行Podman时,该工具将设置并加入用户名称空间。在Podman成为用户名称空间内的root用户后,允许Podman挂载某些文件系统并设置容器。请注意,除了用户可用的其他UID之外,此处没有特权升级,如下所述。

如何创建用户名称空间?

shadow-utils

当前大多数Linux发行版都包含一个Shadow-utils版本,该版本使用/ etc / subuid和/ etc / subgid文件来确定用户名称空间中用户可以使用哪些UID和GID。

代码语言:javascript
复制
$ cat /etc/subuid
 dwalsh:100000:65536
 test:165536:65536
 $ cat /etc/subgid
 dwalsh:100000:65536
 test:165536:65536

添加用户程序自动为添加到系统中的每个用户分配65536个UID。如果系统上已有用户,则需要自己分配UID。这些文件的格式为用户名:STARTUID:TOTALUIDS。在我的情况下,这意味着为dwalsh分配了100000至165535的UID以及我的默认UID,该ID恰好是在/etc/passwd中定义的3265。分配这些UID范围时,请注意它们与系统上的任何实际UID都不重叠。如果您有一个列为UID100001的用户,那么我(dwalsh)将能够成为此UID并可能读取/写入/执行该UID拥有的文件。

Shadow-utils还添加了两个setuid程序(或setfilecap)。在Fedora上,我有:

代码语言:javascript
复制
$ getcap /usr/bin/newuidmap
 /usr/bin/newuidmap = cap_setuid+ep
 $ getcap /usr/bin/newgidmap
 /usr/bin/newgidmap = cap_setgid+ep

Podman执行这些文件以设置用户名称空间。通过在无根容器内部检查/proc/self/uid映射和/proc/self/gid映射,可以看到映射。

代码语言:javascript
复制
$ podman run alpine cat /proc/self/uid_map /proc/self/gid_map
         0       3267            1
         1       100000          65536
         0       3267            1
         1       100000          65536

如上所示,Podman默认将容器中的root映射到当前UID(3267),然后在/etc/subuid和/etc/subgid中映射分配的UID/gid范围,从1开始。在我的示例中,容器中的UID1是UID100000,UID2是UID100001,一直到65536,也就是165535。

任何来自用户名称空间之外、由UID或GID拥有、但没有映射到用户名称空间的项目似乎都属于kernel.overflowuidsysctl中配置的用户,默认值为35534,my/etc/passwd文件称该用户没有名称nobody。由于您的进程不能作为未映射的ID运行,所以不应用所有者和组权限,因此您只能基于它们的“其他”权限访问这些文件。这包括运行容器的系统上真实root拥有的所有文件,因为root没有映射到用户名称空间。

Buildah命令具有一个很酷的功能,buildah unshare。这使您处于Podman运行时所处的用户命名空间中,但无需输入容器的文件系统,因此您可以列出主目录的内容。

请注意,当在用户名称空间之外列出home dir属性时,内核将所有权报告为dwalsh,而在用户名称空间内部,内核将目录报告为root拥有。这是因为主目录归3267所有,并且在用户名称空间内,我们将该UID视为根目录。

在 Podman中设置用户名称空间后会发生什么?

Podman使用容器/存储来提取容器映像,并且容器/存储足够智能,可以将映像中root拥有的所有文件映射到用户名称空间的根,以及不同uid拥有的任何其他文件映射到用户名称空间uid。默认情况下,此内容被写入~/.local/share/containers/storage。容器存储在无根模式下工作,无论是vfs模式还是Overlay模式。注意:只有在安装了fuse-overlayfs可执行文件时才支持Overlay。

内核仅允许用户名称空间root挂载某些类型的文件系统。目前,它允许挂载procfs,sysfs,tmpfs,fusefs和绑定挂载(只要源和目标归运行Podman的用户所有。虽然内核团队正在努力允许挂载OverlayFS,但尚不支持OverlayFS)。

然后,如果使用fuse-overlayfs,Podman将挂载容器的存储;如果存储驱动程序使用vfs,则不需要挂载。不过,vfs上的Podman需要很大的空间,因为每个容器都会复制整个底层文件系统。

紧接着Podman会与一些tmpfs一起装载/proc和/sys,并在容器中创建设备。

为了使用主机网络以外的网络,Podman使用slirp4netns程序为无特权的网络名称空间设置用户模式网络。Slirp4netns允许Podman将容器内的端口暴露给主机。注意,内核仍然不允许非特权进程绑定到小于1024的端口。需要Podman-1.1或更高版本才能绑定到端口。

无根Podman可以使用用户名称空间进行容器分离,但您只能访问/etc/subuid文件中定义的uid。

总结

Podman工具使人们能够在不牺牲系统安全性的情况下构建和使用容器。 您可以授予开发人员所需的访问权限,而无需授予他们root权限。

而且,当您将容器投入生产时,您可以利用用户名称空间提供的额外安全性,以使工作负载彼此隔离。

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 如何创建用户名称空间?
    • shadow-utils
    • 在 Podman中设置用户名称空间后会发生什么?
    • 总结
    相关产品与服务
    容器服务
    腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档