20 | 容器安全(2):在容器中,我不以root用户来运行程序可以吗?
该思维导图由 AI 生成,仅供参考
问题再现
- 深入了解
- 翻译
- 解释
- 总结
在容器中以root用户运行程序可能存在的安全问题一直备受关注。本文深入探讨了这一问题,并提出了两种解决方案。首先,通过指定普通用户uid或使用User Namespace来避免容器以root用户运行的方法。其次,分析了这两种方法可能存在的问题和局限性。通过实例和技术概念的讲解,读者可以深入了解容器中root用户运行程序的安全问题及解决方案。此外,文章还介绍了rootless container的概念,即以非root用户来创建和管理容器,进一步提升容器的安全性。总的来说,本文深入浅出,适合技术人员阅读。文章内容涵盖了容器安全性的重要议题,以及解决这些问题的实用方法,对于关注容器安全的读者具有很高的参考价值。
《容器实战高手课》,新⼈⾸单¥59
全部留言(10)
- 最新
- 精选
- 我来也最近在使用Helm部署gitlab服务的过程中,就发现了 postgresql 和 redis 组件默认是不以root用户执行的,而是一个 User ID 为1001的用户在执行. 这样做,就需要有个k8s的 initContainer 容器先以root用户权限去修改存储目录的权限. 否则后面服务的1001号用户可能就没有权限去写文件了. ------------------ 最近遇到一个问题,想咨询一下老师: 你们有使用过 容器资源可视化隔离方案(lxcfs) 么, 有没有什么坑? 通俗点就是:让容器中的free, top等命令看到容器的数据,而不是物理机的数据。 ------------------ 我遇到的问题是在容器内执行类似`go build/test`命令时,默认是根据当前CPU核数来调整构建的并发数. 这就导致了实际只给容器分配了1个核,但是它以为自己有16个核. 然后就开16个link进程,互相之间除了有竞争,导致CPU上下文切换频繁,更要命的是把磁盘IO给弄满了.影响了整台宿主机的性能. (由于项目比较大,需要构建的文件比较多,所以很容器就让宿主机的IO达到了云服务器SSD磁盘的限制 160MB/s) 我知道在我这个场景下,可以通过指定构建命令`-p`来控制构建的并发数. (https://golang.org/cmd/go/#hdr-Compile_packages_and_dependencies) 实际也这么尝试过,效果也不错. 但问题是,我的项目会很多,每个人构建命令的写法都完全不一样,如果每个地方都去指定参数,就会比较繁琐,且容易遗漏. ------------------ 后来,我看到一篇文章: 容器资源可视化隔离的实现方法 (https://mp.weixin.qq.com/s/SCxD4OiDYsmoIyN5XMk4YA) 之前也在其他专栏中看老师提到过 lxcfs. 我在想,老师在迁移上k8s的过程中,肯定也遇到过类似的问题,不知道老师是如何解决的呢?
作者回复: @我来也 很好的问题。我们在最开始也考虑过使用lxcfs, 当时碰到的问题也是当一批java应用从虚拟机迁移到容器平台之后,发现jvm看到的是整个宿主机的资源。 不过后来,发现大部分语言和应用都是可以加参数或者做修改来适配容器化的,因此,我们的方向是让应用也必须考虑容器和云原生的设计,因为这个是大的趋势,应用这边也是愿意接受这个改变的。 还有一点,当时我们在试lxcfs的时候发现,如果容器需要的cpu不是整数,似乎lxcfs也不能支持(不知道最新的lxcfs是不是有所改变),同时在host上需要额外维护这个lxcfs的可靠性。 这样在大部分主要应用都愿意往容器化方向走的大环境下,我们就不再考虑lxcfs了。
2020-12-31814 - Sunuser limit 是session的?每个容器及时使用相同的user id ,也不会当做累计? User resource limits dictate the amount of resources that can be used for a particular session. The resources that can be controled are: maximum size of core files maximum size of a process's data segment maximum size of files created maximum size that may be locked into memory maximum size of resident memory maximum number of file descriptors open at one time maximum size of the stack maximum amount of cpu time used maximum number of processes allowed maximum size of virtual memory available It is important to note that these settings are per-session. This means that they are only effective for the time that the user is logged in (and for any processes that they run during that period). They are not global settings. In other words, they are only active for the duration of the session and the settings are not cumulative. For example, if you set the maximum number of processes to 11, the user may only have 11 processes running per session. They are not limited to 11 total processes on the machine as they may initiate another session. Each of the settings are per process settings during the session, with the exception of the maximum number of processes.
作者回复: @Sun 很好的问题! 我在这里指的是pam_limits, 在/etc/security/limits.conf中限制某个用户资源之后,然后在pam *_auth 和 runuser中enable pam_limits 之后,那么同一个用户即使在不同的session里,资源的限制也是累计了。 你可以在CentOS的系统里试试。
2021-01-0722 - Action老师 docker -u 参数 是不是就是 通过user namespace 进行隔离
作者回复: -u 只是指定了在容器启动的时候缺省用的uid/gid, 这里的uid/gid和宿主机上的是一样的,并没有建立出新的user namespace.
2021-03-0431 - Action"由于用户 uid 是整个节点中共享的,那么在容器中定义的 uid,也就是宿主机上的 uid,这样就很容易引起 uid 的冲突。"老师这句话怎么理解,容器内uid与宿主机uid是怎么样的关系呢
作者回复: 当容器没有使用user namespace, 那么容器中进程所属的uid/gid, 就是宿主机里uid/gid。你可以运行一下课程中的例子,从宿主机上看看容器进程的uid。
2021-03-04 - 争光 Alan老师,感谢您的分享,学到了很多知识,也感谢解答了很多疑问,有个小小的请求:能公布个微信群之类的吗?把学员加一起相互讨论问题,交流心得
作者回复: @争光 Alan, 我还是会定期回答这个专栏中的大家的提问的。如果你有什么问题,还是在可以在这里提问的。
2021-02-21 - 朱新威老师,我发现一个很有趣的现象,有点困惑; 在宿主机上: 以root用户运行capsh --print 发现Current字段包含许多capabilities 以非root用户运行capsh --print 发现Current 字段包含零个capabilities,说明非root用户启动的进程缺省没有任何capabilities docker容器内: root用户运行capsh --print 发现Current 字段包含14个capabilities,比宿主机上少了一些,对宿主机的/etc/shadow有读写权限 非root用户运行capsh --print 发现Current字段仍然包含14个capabilities,对宿主机的/etc/shadow没有读写权限 这就让我感觉有点困惑了,原本预期容器内非root用户运行capsh --print的capabilities应该为空呀,或者知道少于root用户的capabilities吧?2021-01-0914
- janeyKubernetes v1.25 添加了对容器 user namespaces 的支持2022-11-15归属地:江苏3
- JianXuinstall slirp4netns and Podman on your machine by entering the following command: $ yum install slirp4netns podman -y We will use slirp4netns to connect a network namespace to the internet in a completely rootless (or unprivileged) way.2022-09-08归属地:上海
- 自然有个场景:用jenkins 在 openjdk镜像里 maven 编译java项目, 一个 maven目录(在主机上,而且还有其他很多工具),一个项目源码目录 需要映射到 openjdk镜像里(普通用户启动docker),jenkins 里的pipline 是大家都可以写的。 如何防止 加载主机上目录 在docker镜像里 root用户 随意修改呢( 比如 我不想他删除 主机上的maven)?2022-07-22
- sunnoy如果容器内的用户uid在宿主机上不存在呢,这个时候描述符的分配是怎么样的呢2022-04-24