容器是现代计算的重要组成部分,随着围绕容器的基础设施的发展,新的和更好的工具已经开始浮出水面。过去,你只需要用LXC就可以运行容器,然后Docker得到了普及,事情开始变得更加复杂。最终,我们得到了我们所需要的容器管理系统--Podman,一个无守护程序的容器引擎,使容器和pod易于构建、运行和管理。
容器直接与Linux内核能力对接,如c组和命名空间,它们在这些命名空间中产生大量的新进程。简而言之,运行一个容器就是在一个Linux系统内运行一个Linux系统。从操作系统的角度来看,它看起来非常像一种管理和特权活动。普通用户通常不能像容器那样自由支配系统资源,所以默认情况下,运行Podman需要root或sudo 的权限。然而,这只是默认设置,而且这绝不是唯一可用的设置。本文演示了如何配置你的Linux系统,使一个普通用户可以在不使用sudo ("无根")的情况下运行Podman。
命名空间的用户ID
内核命名空间本质上是一个假想的结构,它帮助Linux跟踪哪些进程属于一起。它是Linux的红色队列绳索。一个队列中的进程和另一个队列中的进程实际上没有什么区别,但它有助于将它们彼此分开。把它们分开是宣布一组进程为 "容器 "而另一组进程为操作系统的关键。
Linux通过用户ID(UID)和组ID(GID)跟踪哪个用户或组拥有每个进程。通常情况下,一个用户可以访问一千个左右的下级UID,以分配给命名空间的子进程。由于Podman运行的是分配给启动容器的用户的整个下属操作系统,你需要比默认分配的subuids和subgids多很多。
你可以用usermod 命令授予一个用户更多的subuids和subgids。例如,要授予用户更多的subuids和subgidstux ,选择一个适当高的、没有分配给它的用户的UID(如200,000),然后将其增加几千。
$ sudo usermod \
--add-subuids 200000-265536 \
--add-subgids 200000-265536 \
tux
命名空间访问
对命名空间也有限制。这通常被设置得很高,但你可以用systctl ,即内核参数工具来验证用户对命名空间的分配。
$ sysctl --all --pattern user_namespaces
user.max_user_namespaces = 28633
这是很充足的命名空间,而且这可能是你的发行版默认设置的。如果你的发行版没有这个属性或者设置得很低,那么你可以通过在文件/etc/sysctl.d/userns.conf 中输入这些文字来创建它。
user.max_user_namespaces=28633
加载该设置。
$ sudo sysctl -p /etc/sysctl.d/userns.conf
运行一个没有根的容器
一旦你设置了你的配置,重新启动你的计算机,以确保对你的用户和内核参数的改变被加载和激活。
在你重启之后,试着运行一个容器镜像。
$ podman run -it busybox echo "hello"
hello
容器像命令一样
如果你是第一次接触容器,可能会觉得很神秘,但实际上,它们和你现有的Linux系统没有什么不同。它们实际上是在你的系统上运行的进程,没有仿真环境或虚拟机的成本或障碍。容器和你的操作系统之间的区别只是内核命名空间,所以它们实际上只是带有不同标签的本地进程。Podman使这一点比以往更加明显,一旦你将Podman配置为无根命令,容器感觉更像命令而不是虚拟环境。Podman让容器和豆荚变得简单,所以请试一试。