资料来源:https//flipboard.com/topic/container

如果你是程序员或技术人员,你很可能听说过Docker:在容器中打包,分发和运行应用程序的一款非常有用的工具。它很难不引起大家的注意力– 从开发人员到系统管理员。即使像谷歌,VMware和亚马逊这样的大公司也正在构建支持它的服务。

不管你是否对Docker有一个使用的想法,我仍然认为了解一些关于容器是什么的基本概念以及它与虚拟机(VM)的区别是很重要的。虽然互联网上好的Docker用户指南非常多,但我找不到许多适合初学者的概念指南,特别是关于容器的构成。所以,希望这篇文章能说明这个问题:)

让我们首先了解VM和容器是什么。

什么是“容器(container)”和“虚拟机(VM)”?

容器和虚拟机的用途相似:都是将应用程序及其依赖项隔离到可以在任何地方运行的独立单元。

此外,容器和VM消除了对物理硬件的需求,从而在能耗和成本效率方面允许更有效地使用计算资源。

容器和VM之间的主要区别在于它们的架构方法。让我们仔细看看。

虚拟机(VM)

VM本质上是对真实计算机的仿真,像真实计算机一样执行程序。VM使用hypervisor在物理机器上运行。反过来,hypervisor可以在主机上运行,​​也可以在裸机上运行。

让我们理解下面行话:

一个hypervisor是运行虚拟机的软件,固件或硬件的中间层。hypervisor本身在物理计算机上运行,​​称为主机。主机为VM提供资源,包括RAM和CPU。这些资源在VM之间划分,可以根据需要进行分发。因此,如果一个VM运行的应用程序使用资源比较多,您可能会分配更多的资源给它。

在主机上运行的VM(同样,使用hypervisor)通常也称为“guest machine”。该guest machine包含应用程序以及运行该应用程序所需的任何内容(例如系统二进制文件和库)。它还带有自己的整个虚拟化硬件,包括虚拟化网络适配器,存储和CPU - 这意味着它还拥有自己的完整的guest操作系统。从内部来看,guest machine具有自己的专有资源。从外部来看,我们知道它是一个VM - 共享主机提供的资源。

如上所述,guest machine既可以运行在主机hypervisor上也可以运行在裸机hypervisor。但它们之间具有很大的差异。

首先,主机虚拟化hypervisor在主机的操作系统上运行。例如,运行OSX的计算机可以在该OS之上安装VM(例如VirtualBox或VMware Workstation 8)。VM无法直接访问硬件,因此必须通过主机操作系统(在我们的例子中是Mac的OSX)。

host虚拟化hypervisor的好处是底层硬件不那么重要。主机的操作系统负责硬件驱动程序而不是hypervisor本身,因此被认为具有“硬件兼容性”。另一方面,硬件和hypervisor之间的这个附加层会产生更多的资源开销,从而降低VM的性能。

裸机虚拟化hypervisor环境通过在主机的硬件上安装和运行来解决性能问题。因为它直接与底层硬件交互,所以它不需要运行主机操作系统。在这种情况下,作为操作系统安装在主机服务器上的第一件事就是hypervisor。与托管虚拟机hypervisor不同,裸机虚拟机hypervisor具有自己的设备驱动程序,可直接与每个组件交互,以执行任何I / O,处理或特定于操作系统的任务。这样可以获得更好的性能,可扩展性和稳定性。这里的权衡是硬件兼容性有限,因为hypervisor预装的设备驱动程序数量有限。

在讨论了hypervisor之后,您可能想知道为什么我们在VM和主机之间需要额外的“hypervisor”层了。

好吧,由于VM拥有自己的虚拟操作系统,所以hypervisor 扮演了一个重要的角色,为VM提供了一个平台来管理和调用操作系统,使虚拟机可以共享其主机资源。

虚拟机图

如图所示,VM包含虚拟硬件,内核(即操作系统)和用户空间。

容器(container)

与硬件虚拟化的VM不同,容器通过抽象“用户空间”来提供操作系统级虚拟化。当我们解开术语容器时,你会明白我的意思。

出于意图和目的,容器看起来像VM。例如,它们具有用于处理的私有空间,以root身份执行命令,有自己的网络接口和IP地址,允许自定义路由和iptable规则,可以挂载文件系统等。

容器和VM之间的一个最大区别是容器与其他容器共享主机系统的内核。

容器图

此图显示容器仅包含用户空间,而不是像VM那样还包括内核或虚拟硬件。每个容器都有自己独立的用户空间,以允许多个容器在单个主机上运行。我们可以看到所有操作系统级体系结构都在容器之间共享。需创建的唯一部分是bins和libs。这就是容器如此轻巧的原因。

Docker从哪里来?

Docker是一个基于Linux容器的开源项目。它使用Linux内核功能(如命名空间和控制组)在操作系统之上创建容器。

容器并非新的事物; 谷歌多年来一直在使用自己的容器技术。其他Linux容器技术包括Solaris Zones,BSD jails和LXC,它们已经存在多年。

那么为什么Docker会突然获得成功?

1. 易于使用: Docker使任何人 - 开发人员,系统管理员,架构师和其他人 - 更容易利用容器来快速构建和测试便携式应用程序。它允许任何人在他们的笔记本电脑上打包应用程序,而这些应用程序不做修改又可以在任何公共云,私有云甚至裸机上运行。这便是:“建造一次,随处运行”。

2. 速度: Docker容器非常轻巧,快速。由于容器只是在内核上运行的沙盒环境,因此它们占用的资源更少。与VM相比,您可以在几秒钟内创建并运行Docker容器,因VM每次都必须启动完整的虚拟操作系统, 会花费更多的时间。

3. Docker Hub: Docker用户也从日益丰富的Docker Hub生态系统中受益,您可以将其视为“Docker镜像的应用商店”.Docker Hub拥有数万个社区创建的公共镜像,这些镜像随时可用。搜索满足您需求的镜像是非常容易的, 然后去镜像库拉取并几乎不用修改的使用镜像。

4. 模块化和可扩展性: Docker可以轻松地将应用程序的功能拆分到独立的容器中运行。例如,您的Postgres数据库可能在一个容器中运行,而您的Redis服务器在另一个容器中运行,而Node.js应用程序在另一个容器中。使用Docker,将这些容器链接在一起以创建应用程序变得更加容易,从而使您可以在将来轻松扩展或更新组件。

最后但并非最不重要的是,谁不喜欢Docker鲸?;)

资料来源:https//www.docker.com/docker-birthday

基本的Docker概念

现在我们已经初步了解了docker,让我们逐步了解Docker的基础组件:

Docker引擎(Docker Engine)

Docker引擎是Docker运行层。它是一个轻量级的运行时和工具,可以管理容器,镜像,构建等。它在Linux系统上本机运行,由以下部分组成:

1.在主机中运行的Docker守护程序。
2. Docker客户端,负责与Docker守护程序通信以执行命令。
3.用于远程与Docker守护程序交互的REST API。

Docker客户端(Docker Client)

Docker客户端就像Docker的最终用户一样与之通信。可以把它想象成Docker的UI。例如,当你做...

您正在与Docker客户端进行通信,然后Docker客户端将您的指令传递给Docker守护程序。

Docker守护进程(Docker Daemon)

Docker守护程序实际上是执行发送到Docker Client的命令 - 比如构建,运行和分发容器。Docker守护程序在主机上运行,​​但作为用户,您永远不会直接与守护程序通信。Docker Client也可以在主机上运行,​​但不是必需的。它可以在不同的计算机上运行,​​并与在主机上运行的Docker守护程序进行通信。

Dockerfile

您可以在Dockerfile中编写构建Docker镜像的指令。这些指令可以是:

ï 运行apt-get y install some-package:安装软件包

ï EXPOSE 8000:暴露端口

ï ENV ANT_HOME / usr / local / apache-ant传递环境变量

等等。一旦设置了Dockerfile,就可以使用docker build命令从中构建映像。这是Dockerfile的一个例子:

示例Dockerfile

Docker 镜像( Docker Image)

镜像是只读模板,您可以在Dockerfile中编写的一组指令构建这些模板。镜像定义了您希望打包的应用程序及其依赖项看起来像*and*的在启动时运行的进程。

Docker镜像是使用Dockerfile构建的。Dockerfile中的每条指令都为镜像添加了一个新的“镜像层”,镜像层表示镜像文件系统的一部分,可以添加或替换它下面的镜像层。镜像层是Docker轻巧而强大的结构的关键。Docker使用Union File System来实现这个目的:

联合文件系统(Union File Systems

Docker使用Union File Systems来构建镜像。您可以将UFS视为可堆叠文件系统,这意味着可以透明地覆盖单独文件系统(称为分支)的文件和目录以形成单个文件系统。

在重叠分支内具有相同路径的目录的内容被视为单个合并目录,这避免了为每个层创建单独副本的需要。作为替代,它们都可以被赋予指向同一资源的指针; 当某些层需要修改时,它会创建一个副本并修改一个本地副本,保持原始版本不变。这就是文件系统如何显得可写而没有实际修改原因内容。(换句话说,就是“copy-on-write”系统。)

分层系统有两个主要优点:

1.避免复制:每次使用镜像创建和运行新容器时,镜像层都有助于避免复制完整的文件集,从而使docker容器的实例化非常快速且便宜。
2. 镜像层隔离:进行更改要快得多 - 当您更改镜像时,Docker只会将更新传播到被修改的镜像层。

卷是容器的存储数据部分,在创建容器时初始化。卷允许您持久化并共享容器的数据。数据卷与默认的Union File System是分开的,数据卷作为主机文件系统上的普通目录和文件存在。因此,即使您销毁,更新或重建容器,数据卷也将保持不变。如果要更新卷,可以直接对其进行更改。(作为额外的奖励,数据卷可以在多个容器之间共享和重用,这非常简洁。)

Docker容器(Docker Containers )

如上所述,Docker容器将应用程序和运行所需的所有内容封装到一个黑色沙箱中。这包括操作系统,应用程序代码,运行时,系统工具,系统库等.Docker容器是基于Docker镜像构建的。由于镜像是只读的,因此Docker在镜像的只读文件系统上添加了一个读写文件系统来创建容器。

资料来源:Docker

然后创建容器,Docker创建一个网络接口,以便容器可以与本地主机通信,将可用的IP地址附加到容器,并在定义镜像时执行指定的运行应用程序的进程。

成功创建容器后,即可在任何环境中运行它,而无需进行更改。

双击“容器”Double-clicking on “containers”

让我感到好奇的一件事容器是如何实现的,特别是因为容器周围没有任何抽象的基础设施边界。经过大量的阅读,这一切都是有道理的,所以这是我尝试向你解释它!:)

术语“容器”实际上只是一个抽象概念,用于描述一些不同的组件如何协同工作以抽象为“容器”。让我们快速浏览它们:

1)命名空间

命名空间为容器提供了自己的底层Linux系统视图,限制了容器可以查看和访问的内容。当您运行容器时,Docker会创建特定容器将使用的命名空间。

Docker使用的内核中有几种不同类型的命名空间,例如:

a. NET:为容器提供自己的系统网络栈视图(例如,自己的网络设备,IP地址,IP路由表,/ proc / net目录,端口号等)。

b. PID: PID代表进程ID。如果您曾在命令行中运行ps aux来检查系统上正在运行的进程,那么您将看到一个名为“PID”的列。PID命名空间为容器提供了他们可以查看和交互的进程的范围视图,包括独立的init(PID 1),它是“所有进程的祖先”。

c. MNT:为容器提供系统上“挂载”的自己视图。因此,不同安装命名空间中的进程具有不同的文件系统层次结构视图。

d. UTS: UTS代表UNIX分时系统。它允许进程识别系统标识符(即主机名,域名等)。UTS允许容器拥有自己的主机名和NIS域名,该域名独立于其他容器和主机系统。

e. IPC: IPC代表InterProcess Communication。IPC命名空间负责隔离每个容器内运行的进程之间的IPC资源。

f. USER:此命名空间用于隔离每个容器中的用户。它的功能是允许容器与主机系统相比具有uid(用户ID)和gid(组ID)范围的不同视图。因此,进程的uid和gid可以在用户命名空间的内部和外部不同,这也允许进程在容器外部拥有非特权用户,而不会牺牲容器内的root权限。

Docker将这些命名空间一起使用,以隔离并开始创建容器。下一个功能称为控制组。

2)控制Control groups

控制组(也称为cgroup)是一种Linux内核功能,用于隔离,确定优先级并说明一组进程的资源使用情况(CPU,内存,磁盘I / O,网络等)。从这个意义上讲,cgroup确保Docker容器只使用他们需要的资源 - 如果需要,还可以设置容器使用的资源限制。cgroup还确保单个容器不会耗尽其中一个资源并导致整个系统崩溃。

最后,联合文件系统是Docker使用的另一个功能:

3)隔离联盟文件系统Isolated Union file system

上面在Docker Images部分中描述:)

这就是Docker容器的全部内容(当然,魔鬼在实现细节中 - 比如如何管理各个组件之间的交互)。

Docker的未来:Docker和VM将共存

虽然Docker已经获得了非常大的成功,但我认为它不会成为虚拟机的真正威胁。容器将继续发挥作用,但有许多场景仍然更适合虚拟机。

例如,如果您需要在多个服务器上运行多个应用程序,则使用VM可能是有意义的。另一方面,如果您需要运行单个应用程序的许多“副本”,Docker优势更明显。

此外,虽然容器允许您将应用程序分解为更多功能性的服务单元以创建关注点分离,但这也意味着需要管理的部件越来越多,这可能变得难以处理。

安全性也是Docker容器所关注的一个领域 - 由于容器共享相同的内核,容器之间的隔离更薄。虽然完整的VM只能向主机hypervisor发出超级调用,但Docker容器可以向主机内核发出系统调用,从而为攻击创建更大的范围。当安全性特别重要时,开发人员可能会选择由抽象硬件隔离的虚拟机 - 这使得互相干扰变得更加困难。

当然,安全和管理等问题肯定会随着容器在生产中的更多曝光和用户的进一步审查而发展。就目前而言,关于容器与虚拟机之间的争论对于那些每天使用它们的开发者来说真的是最好的!

结论

我希望您现在拥有了解Docker所需的知识,甚至可能有一天会在项目中使用它。

像往常一样,如果我犯了任何错误或者无论如何都会有所帮助,请在评论中留言!:)

英文原文链接:https://medium.freecodecamp.org/a-beginner-friendly-introduction-to-containers-vms-and-docker-79a9e3e119b

更多文章欢迎访问 http://www.apexyun.com/

联系邮箱:public@space-explore.com

(未经同意,请勿转载)