我一直在重读Docker文档,试图理解Docker和完整VM之间的区别。它是如何设法提供一个完整的文件系统、隔离的网络环境等而不那么沉重的?

为什么将软件部署到Docker映像(如果这是正确的术语)比简单地部署到一致的生产环境更容易?


当前回答

Feature Virtual Machine (Docker) Containers
OS Each VM Does contains an Operating System Each Docker Container Does Not contains an Operating System
H/W Each VM contain a virtual copy of the hardware that OS requires to run. There is No virtualization of H/W with containers
Weight VM's are heavy -- reason sited above-- containers are lightweight and, thus, fast
Required S/W Virtuliazation achieve using software called a hypervisor Containerzation achieve using software called a Docker
Core Virtual machines provide virtual hardware (or hardware on which an operating system and other programs can be installed) Docker containers don’t use any hardware virtualization. **It helps to use container
Abstraction Virtual machines provide hardware abstractions so you can run multiple operating systems. Containers provide OS abstractions so you can run multiple containers.
Boot-Time It takes a long time (often minutes) to create and require significant resource overhead because they run a whole operating system in addition to the software you want to use. It takes less time because Programs running inside Docker containers interface directly with the host’s Linux kernel.

其他回答

对于虚拟机,我们有一台服务器,在该服务器上有一个主机操作系统,然后我们有一个管理程序。然后在该虚拟机管理程序之上运行,我们在该服务器上有任意数量的来宾操作系统,其中包含应用程序及其从属二进制文件和库。它带来了一个完整的客户操作系统,非常重量级。此外,您可以在每个物理机器上实际投入多少也是有限制的。

另一方面,Docker容器略有不同。我们有服务器。我们有主机操作系统。但在本例中,我们使用的是Docker引擎,而不是管理程序。在这种情况下,我们并没有带来一个完整的客户操作系统。我们带来了一个非常薄的操作系统层,容器可以与主机操作系统进行对话,以获得那里的内核功能。这使得我们可以拥有一个非常轻的容器。

它所包含的只有应用程序代码以及所需的任何二进制文件和库。如果您希望这些二进制文件和库也可以在不同的容器中共享。这使我们能够做的事情有很多。它们的启动时间要快得多。你不能像那样在几秒钟内建立一个虚拟机。同样地,也要尽快地把它们取下来。。所以我们可以很快地放大和缩小,稍后我们将对此进行研究。

每个容器都认为它在自己的操作系统副本上运行。它有自己的文件系统,自己的注册表等等,这是一种谎言。它实际上是虚拟化的。

我在生产环境和登台中使用过Docker。当你习惯了它,你会发现它对于构建一个多容器和隔离环境非常强大。

Docker是基于LXC(Linux容器)开发的,在许多Linux发行版中都能完美运行,尤其是Ubuntu。

Docker容器是隔离的环境。当您在Docker容器中发出top命令时,可以看到它,Docker容器是从Docker映像创建的。

此外,由于dockerFile配置,它们非常轻便和灵活。

例如,您可以创建一个Docker映像并配置一个DockerFile,然后告诉它,例如,当它运行时,运行wget“this”,apt-get“that”,运行“some shell script”,设置环境变量等等。

在微服务项目和架构中,Docker是一项非常可行的资产。您可以通过Docker、Docker swarm、Kubernetes和Docker Compose实现可伸缩性、弹性和弹性。

Docker的另一个重要问题是Docker Hub及其社区。例如,我使用Prometheus、Grafana、PrometheusJMXExporter和Docker实现了一个用于监控kafka的生态系统。

为此,我为zookeeper、kafka、Prometheus、Grafana和jmx收集器下载了已配置的Docker容器,然后使用YAML文件为其中一些容器安装了自己的配置,我更改了Docker容器中的一些文件和配置,并在一台机器上使用多容器Docker构建了一个用于监控kafka的完整系统,该系统具有隔离性、可扩展性和弹性,该架构可以轻松移动到多个服务器中。

除了Docker Hub站点之外,还有一个名为quay.io的站点,您可以使用它在那里创建自己的Docker图像仪表板,并将其推送到码头。您甚至可以将Docker图像从DockerHub导入码头,然后在自己的机器上从码头运行。

注意:学习Docker一开始看起来既复杂又困难,但当你习惯了它之后,你就不能没有它了。

我记得在使用Docker的第一天,我发出了错误的命令,或者错误地删除了我的容器和所有数据和配置。

资料来源:Kubernetes in Action。

Docker封装了一个应用程序及其所有依赖项。

虚拟机封装了一个OS,该OS可以运行它通常可以在裸机上运行的任何应用程序。

了解虚拟化和容器如何在低级别上工作可能会有所帮助。这将澄清很多事情。

注意:我在下面的描述中简化了一点。有关详细信息,请参阅参考文献。

虚拟化如何在低级别工作?

在这种情况下,VM管理器接管CPU环0(或较新CPU中的“根模式”),并拦截来宾操作系统发出的所有特权调用,以产生来宾操作系统拥有自己硬件的错觉。有趣的事实:在1998年之前,人们认为在x86架构上实现这一点是不可能的,因为没有办法进行这种拦截。VMware的员工是第一个有想法重写内存中的可执行字节以供来宾操作系统的特权调用来实现这一点的人。

其净效果是虚拟化允许您在同一硬件上运行两个完全不同的操作系统。每个来宾操作系统都要经过引导、加载内核等所有过程。例如,来宾操作系统无法完全访问主机操作系统或其他来宾操作系统,从而造成混乱。

容器如何在低液位下工作?

2006年左右,包括谷歌员工在内的一些人实现了一个名为名称空间的新内核级功能(然而,这个想法早就存在于FreeBSD中)。操作系统的一个功能是允许在进程之间共享网络和磁盘等全局资源。如果这些全局资源被包装在命名空间中,以便它们只对在同一命名空间中运行的那些进程可见,该怎么办?例如,您可以获取一块磁盘并将其放在命名空间X中,然后在命名空间Y中运行的进程无法看到或访问它。同样,命名空间X中的进程无法访问分配给命名空间Y的内存中的任何内容。当然,X中的程序无法看到或与命名空间Y中的进程对话。这为全局资源提供了一种虚拟化和隔离。Docker是这样工作的:每个容器都在自己的命名空间中运行,但使用与所有其他容器完全相同的内核。之所以发生隔离,是因为内核知道分配给进程的命名空间,并且在API调用期间,它确保进程只能访问自己命名空间中的资源。

容器与虚拟机的局限性现在应该很明显:你不能像虚拟机那样在容器中运行完全不同的操作系统。但是,您可以运行不同的Linux发行版,因为它们共享相同的内核。隔离级别不如VM中的隔离级别强。事实上,在早期的实现中,“来宾”容器可以接管主机。您还可以看到,当您加载一个新容器时,OS的整个新副本并不像在VM中那样启动。所有容器共享同一内核。这就是为什么集装箱重量轻。与VM不同的是,您不必为容器预先分配大量内存,因为我们没有运行新的OS副本。这允许在一个操作系统上运行数千个容器,同时对它们进行装箱,如果我们在它们自己的VM中运行操作系统的单独副本,这可能是不可能的。