系统管理员的容器指南:容器的工作原理是什么?
容器无疑是当下IT技术的“网红”。而根据具体情况,它可能对不同的用意味着不同的内容。
传统的Linux容器实际上只是Linux系统上的普通进程。这些进程组使用资源约束(控制组[cgroups]),Linux安全约束(Unix权限,功能,SELinux,AppArmor,seccomp等)和命名空间(PID,网络,装载,等等)。
如果你启动一个现代Linux系统并查看cat/proc/PID/cgroup的任何进程,你会看到该进程位于cgroup中。如果查看/ proc / PID / status,就会看到功能。如果你查看/ proc / self / attr / current,你会看到SELinux标签。如果查看/ proc / PID / ns,会看到进程所在的命名空间列表。因此,如果你将容器定义为具有资源限制,Linux安全性约束和命名空间的进程,则根据定义,Linux上的每个进程系统在一个容器中。这就是为什么我们经常说Linux是容器,容器是Linux。容器运行时是修改这些资源约束,安全性和命名空间并启动容器的工具。
Docker引入了容器镜像的概念,这是一个标准的TAR文件,它结合了:
- Rootfs(容器根文件系统):系统上看起来像操作系统的标准根(/)的目录。例如,带有/ usr,/ var,/ home等的目录。
- JSON文件(容器配置):指定如何运行rootfs;例如,容器启动时在rootfs中运行的命令或入口点;为容器设置的环境变量;容器的工作目录;和一些其他设置。
Docker“tar up”rootfs和JSON文件来创建基本镜像。这使你可以在rootfs上安装其他内容,创建新的JSON文件,并使用更新的JSON文件来解决原始镜像与新镜像之间的差异。这会创建一个分层镜像。
容器镜像的定义最终由Open Container Initiative(OCI)标准组织定为OCI镜像规范。
用于创建容器镜像的工具称为容器镜像构建器。有时容器引擎执行此任务,但可以使用几个可以构建容器镜像的独立工具。
Docker采用了这些容器镜像(tarball)并将它们移到一个Web服务,从中可以拉出它们,开发了一个协议来提取它们,并将Web服务称为容器注册表。
容器引擎是可以从容器注册表中提取容器镜像并将它们重新组装到容器存储上的程序。容器引擎也启动容器运行时(见下文)。
Linux容器内部。Scott McCarty的插图。
容器存储通常是写时复制(COW)分层文件系统。从容器注册表中下载容器镜像时,首先需要解压rootfs并将其放在磁盘上。如果你有多个构成镜像的图层,则会下载每个图层并将其存储在COW文件系统的不同图层上。COW文件系统允许每个层单独存储,这最大化了分层镜像的共享。容器引擎通常支持多种类型的容器存储,包括overlay,devicemapper,btrfs,aufs和zfs。
在容器引擎将容器镜像下载到容器存储之后,它需要创建容器运行时配置。运行时配置组合来自调用者/用户的输入以及容器镜像规范的内容。例如,调用者可能希望指定对正在运行的容器的安全性的修改,添加其他环境变量或将卷装入容器。
OCI标准组织还将容器运行时配置和rootfs的布局标准化为OCI运行时规范。
最后,容器引擎启动一个读取容器运行时规范的容器运行时;修改Linux cgroups,Linux安全性约束和命名空间;并启动容器命令以创建容器的PID 1。此时,容器引擎可以将stdin / stdout中继回调用者并控制容器(例如,停止,启动,附加)。
请注意,正在引入许多新的容器运行时以使用Linux的不同部分来隔离容器。人们现在可以使用KVM分离(比如迷你虚拟机)运行容器,或者他们可以使用其他管理程序策略(例如拦截来自容器中进程的所有系统调用)。由于我们有一个标准的运行时规范,这些工具都可以由相同的容器引擎启动。甚至Windows也可以使用OCI运行时规范来启动Windows容器。
更高层次的是容器编排。容器编排是用于协调多个不同节点上的容器执行的工具。容器编排工具与容器引擎通信以管理容器。它告诉容器引擎启动容器并将它们的网络连接在一起,它可以监控容器并在负载增加时启动其他容器。