『他山之石』系列之《普通的VM与Docker的不同之处在哪里?》
楼主问:我反复研读Docker文档,想要搞清楚Docker与虚拟机之间的差别。很想搞明白它是怎么做到在提供满的文件系统,以及相互隔离的网络环境等等的境况下,运行起来又不费力的?
最佳答案:
Docker较早使用LXC技术,但是之后又转而使用runC(早期的时候叫做libcontainer)技术,跟LXC是同一个操作系统主机下的。这样的话,就可以共享很多主机操作系统资源。Docker也使用像AuFS一样的分层文件系统,也管理网络。
AuFS是一个分层文件系统,在上面可以有一个可读部分,还有一个可写部分,也可以将这两者合并到一起。所以可以将操作系统的普通部分作为只读,这个部分是可以在你所有的容器中共享,然后再给每个容器写的时候自己加载。
现在我们有一个1GB大小的容器镜像。如果想使用Full VM,可能就需要有1GB倍数的VM。而有了LXC和AuFS,就可以分享1GB中的大部分东西,如果你有1000个容器,假设他们全部同时在一个操作镜像上运行,那么容器操作系统可能仍然只需要略大于1GB的空间。
完全虚拟化系统有属于自己的编进资源,而且基本上不分享出去。隔离性程度会更大,但是会更加重(需要更多的资源)。
有了LXC,隔离性程度降低,也会更加轻便,对资源的要求更低。所以可以轻易的在一个主机上跑1000台都不会宕机。如果尝试用Xen,那么除非你有一台足够大的主机,不然绝对不可能。
完全虚拟化系统通常需要几分钟来启动,LXC容器需要的时间是以秒计的,而且有时间甚至连一秒都用不到。
每个不同的系统都有各种的优缺点,如果想要与保障资源完全隔离开,那么完全虚拟化是一个好办法。如果你仅仅是想要这些进程互相隔离开,并且想要在一个大小合理的主机上运行大量的程序,那么LXC是最好的选择。
想要了解更多信息,点击查看这一系列的帖子,可以很好的解除你对LXC如何运作的疑惑。
追问:
虽然问这个有点蠢,但是还是想问一下,为什么在Docker镜像上部署软件比只部署在与其一致的生产环境中来得简单?
部署一致的生产环境说起来简单做起来难。即使使用像Chef和Puppet一样的工具,仍然还是会有操作系统的更新和其他东西会改变主机和环境。
Docker所做的就是将操作系统备份成为一个普通的镜像,并且使之在其他Docker主机上部署也十分简单。本地,dev,qa,prod,etc都是一样的镜像。当然,你也可以用其他工具来完成,但是不会那么容易,而且速度也不会快。
这对于单元测试来说真的是极好的,假设你有1000个测试需要连接到数据库,而为了不破坏任何需要连续运行的东西,测试不能互相依赖(在一个事务中运行每个测试,之后卷回恢复)。有了Docker,就可以创建自己的数据库的镜像,然后并行运行所有的测试,因为你知道他们都会运行的时候防范数据库的备份。既然他们都是连续运行在LXC容器中的,那么他们在同一时间在同样的box中就可以运行所有的东西,所以你的测试也会完成的快一点。可以尝试着用完全虚拟机来完成。
追问:
有意思!但是我还是对备份的操作系统很疑惑。如果没有建立操作系统镜像,要怎么完成呢?
好吧,我来解释一下。首先,你是从一个基底镜像开始的,然后作出自己的修改,并且用docker提交那些修改,这样就创造了一个新的镜像。这个镜像仅仅包含了跟基底不一样的东西。当你想要运行你的镜像的时候,你仍然需要基底底层,而且它会在基底的最基本层用一个分层系统将镜像分层。AUFS将不同的层次合并到一起,所以可以得到你想要的,并且你需要做的就只是运行它。你可以不断地在这个基础上添加镜像(或者层次),然后它只是会一直保存差异指令。docker典型的就是建立在已完成的镜像上的代码库,你就很少需要去给整个操作系统备份了。
追答:
赞同Ken的回答。
但我想要添加一个没有提到的细节。我觉得吧,Docker在整个进程中也是不同于VM的,与VM相比,Docker不仅仅是关于硬件最优资源共享,还有就是,它会为应用打包提供一个“系统”(作为Microservices,最好是可以提供这样一个系统,但也不是必须要这么做。)
像rpm,debian packages,maven,npm+git这样的面向开发人员的工具,和Puppet, VMWare, Xen等等这类的工具之间有一个技术空白,对我来说,Docker正好填补了这样一个空白。
虽然问这个有点蠢,但是还是想问一下,为什么在Docker镜像上部署软件比单单部署在与其一致的生产环境中来得简单?
你的问题是假设在一致的生产环境的前提下的。但是如何将之保持一致呢?考虑到一定数量的服务和应用程序(大于10)还在管道阶段。我们为了使之同步,就要开始使用Puppet,Chef或者是自己的供应脚本,一些未发表的规则或者是很多文档。理论上来说,服务器可以无限运行的,并且保持环境完全一致,保持最新更新。实践管理无法完全管理服务器的配置,所以就会有相当大的空间配置漂移,在运行服务器的时候就会有意想不到的变化。
现在有一个已知的模式阻止这个,所谓的immutable Server。但是immutable Server并不受欢迎。很多时候由于VM的限制,通常在Docker之前使用immutableServer。处理几个基于千兆字节的大镜像的时候,移动这些大镜像只是为了改变app里面的一些域值,很费力气。真是难以理解……
有了Docker生态系统,就再也不用在小修改上面移动基于千兆字节的东西了,而且在将应用打包到Docker容器中运行的时候,也不需要担心性能损失。也不需要担心那个镜像的版本。并且最后即使是在linux笔记本上你也可以经常复制复杂的生产环境(别告诉我你没法儿用)。
当然,你也可以在VMs上开启Docker容器(这是个好主意)。在VM层次上减少服务器供应。以上都可以通过Docker托管。
P.S.同时,Docker使用自己的配置来执行“libcontainer”来替代LXC。但是LXC也还是可以使用的。
通过这个帖子,我们现在来列出一些VM和LXC之间的差别。首先呢,让我们来定义一下他们。
VM:
VM就是一个虚拟机器模拟物理计算环境,但是还是需要CPU,内存,硬盘,网络以及其他硬件资源通过虚拟层次来托管,并将这些请求转化为底层物理硬件。
在这情境下,VM是游客,而运行的环境则是主机。
LXC:
LXC是操作系统层次权证,使运行多个相互隔离的Linux容器在一个控制主机上(LXC主机)。Linux容器以轻便的优势,以及不需要监控程序(即Virtualbox,KVM,Xen等等)替代了VM。
现在除非你是被Alan(《宿醉》系列主角之一)下药了,或者是过去那么多年都在Vegas,那么你应该很清醒的知道Linux容器技术所喷射出的巨大的利益。如果要我说的话,容器项目在过去几个月内创造的轰动世界的就是,Docker引领了一些可以在云计算环境中 的建议。容器技术由于其较低的开销和潜在的性能将取代VM。
但是问题是,它可行吗?这么做明智吗?
a.
LXC只能运行在Linux的实例上。它可能就是不同口味的Linux Ubuntu容器(例如:Centos主机上的Ubuntu仍然是Linux)。同样的,基于windows的容器只能运行在windows的实例上,如果我们看VM的话,会发现,他们有一个更加广阔的视野,并且使用管理程序,这样你就不再局限于操作系统Linux或者windows了。
b.
LXC管理费用较低,而且性能比VM更好。工具(即Docker)是建立在LXC技术的基础上,提供给开发者一个平台来运行他们的应用,同时,授权给使用Ops的人们一个可以让他们部署同样的容器在生产服务器或者是数据中心的工具。它尝试着让开发人员在运行程序的时候的经验来启动和测试应用,来启动测试操作人员,来无缝配置这个应用。因为这就是矛盾存在的地方,也是DevOps要打破这些筒仓的目的。
因此,最佳的做法就是,云计算基础设施提供者应该提倡适当使用VM和LXC的方法,因为他们都是处理特定的工作负载和场景。现在放弃VM是不切实际的,所以VM和LXC都有他们各自存在的道理和重要性。
他们两个都是很独特的。
Docker很轻便,而且使用LXC/libcontainer(依赖于内核namespace和cgroup),也没有机器/硬件仿真,比如管理程序,KVM,Xen,这些都是很繁重的。
Docker和LXC对沙箱机制,容器化和资源意味颇多。它使用主机(目前只有linux内核)的克隆API,这个API可以提供namespacing给IPC, NS(mount),namespacing,NS(mount),网络,PID,UTS等等。那么内存,io,cpu这些怎么样呢?这些地方都是可以通过特定的资源(cpu,内存)规范/限制来创建groups的,并且还可以把你的程序也放在那里。在LXC上,Docker提供存储后端服务(http://www.projectatomic.io/docs/filesystems/)。
比如,可以在单元加载文件系统里添加图层,并且在不同的加载namespace里分享图层。这是一个强大的功能,在这里,基底镜像通常是只读的,只有当容器在图层里修改东西的时候,它才会写一些东西来读写分区(又名“写前拷贝”)。同时,它也提供了许多的包装比如注册表以及多版本镜像。有了普通的LXC,你需要有一些rootfs,或者分享一些rootfs。当分享的时候,作出的修改会在其他容器上体现。由于添加了很多这样的功能,docker比LXC受欢迎得多。LXC在嵌入式环境中很受欢迎,因为在进程中采取安全技术保护措施会暴露在外部实体比如网络和用户界面。Docker在云的多用户租赁环境中很受欢迎,这种环境下很期待一致的生产环境。
通常VM(virtualbox,VMware)使用管理程序,相关的技术有一个可以成为第一操作系统的第一层的专属固件,没有那个的话,就是有一个可以在主机操作系统上运行的软件来给游客操作系统提供硬件仿真比如CPU,USB/配件,内存,网络等等。虚拟机仍然(截至2015年)在高安全多租户环境中很受欢迎。
Docker/LXC几乎可以在任何便宜的硬件上运行(小于1GB的内存也可以,只要你有新的内核就可以)。而普通的VM要执行任意有意义的事情则需要至少2GB的内存。但是Docker支持主机操作系统,却不支持像windows一样的操作系统(截至2014年11月),而VM的很多类型都可以在windows,linux,mac上面运行。
以上是来自Stack Overflow的一篇问答帖,点击这里阅读原文
![]() |
(图片来源于网络) |
最佳答案:
Docker较早使用LXC技术,但是之后又转而使用runC(早期的时候叫做libcontainer)技术,跟LXC是同一个操作系统主机下的。这样的话,就可以共享很多主机操作系统资源。Docker也使用像AuFS一样的分层文件系统,也管理网络。
AuFS是一个分层文件系统,在上面可以有一个可读部分,还有一个可写部分,也可以将这两者合并到一起。所以可以将操作系统的普通部分作为只读,这个部分是可以在你所有的容器中共享,然后再给每个容器写的时候自己加载。
现在我们有一个1GB大小的容器镜像。如果想使用Full VM,可能就需要有1GB倍数的VM。而有了LXC和AuFS,就可以分享1GB中的大部分东西,如果你有1000个容器,假设他们全部同时在一个操作镜像上运行,那么容器操作系统可能仍然只需要略大于1GB的空间。
完全虚拟化系统有属于自己的编进资源,而且基本上不分享出去。隔离性程度会更大,但是会更加重(需要更多的资源)。
有了LXC,隔离性程度降低,也会更加轻便,对资源的要求更低。所以可以轻易的在一个主机上跑1000台都不会宕机。如果尝试用Xen,那么除非你有一台足够大的主机,不然绝对不可能。
完全虚拟化系统通常需要几分钟来启动,LXC容器需要的时间是以秒计的,而且有时间甚至连一秒都用不到。
每个不同的系统都有各种的优缺点,如果想要与保障资源完全隔离开,那么完全虚拟化是一个好办法。如果你仅仅是想要这些进程互相隔离开,并且想要在一个大小合理的主机上运行大量的程序,那么LXC是最好的选择。
想要了解更多信息,点击查看这一系列的帖子,可以很好的解除你对LXC如何运作的疑惑。
追问:
虽然问这个有点蠢,但是还是想问一下,为什么在Docker镜像上部署软件比只部署在与其一致的生产环境中来得简单?
![]() |
(图片来源于网络) |
部署一致的生产环境说起来简单做起来难。即使使用像Chef和Puppet一样的工具,仍然还是会有操作系统的更新和其他东西会改变主机和环境。
Docker所做的就是将操作系统备份成为一个普通的镜像,并且使之在其他Docker主机上部署也十分简单。本地,dev,qa,prod,etc都是一样的镜像。当然,你也可以用其他工具来完成,但是不会那么容易,而且速度也不会快。
这对于单元测试来说真的是极好的,假设你有1000个测试需要连接到数据库,而为了不破坏任何需要连续运行的东西,测试不能互相依赖(在一个事务中运行每个测试,之后卷回恢复)。有了Docker,就可以创建自己的数据库的镜像,然后并行运行所有的测试,因为你知道他们都会运行的时候防范数据库的备份。既然他们都是连续运行在LXC容器中的,那么他们在同一时间在同样的box中就可以运行所有的东西,所以你的测试也会完成的快一点。可以尝试着用完全虚拟机来完成。
追问:
有意思!但是我还是对备份的操作系统很疑惑。如果没有建立操作系统镜像,要怎么完成呢?
好吧,我来解释一下。首先,你是从一个基底镜像开始的,然后作出自己的修改,并且用docker提交那些修改,这样就创造了一个新的镜像。这个镜像仅仅包含了跟基底不一样的东西。当你想要运行你的镜像的时候,你仍然需要基底底层,而且它会在基底的最基本层用一个分层系统将镜像分层。AUFS将不同的层次合并到一起,所以可以得到你想要的,并且你需要做的就只是运行它。你可以不断地在这个基础上添加镜像(或者层次),然后它只是会一直保存差异指令。docker典型的就是建立在已完成的镜像上的代码库,你就很少需要去给整个操作系统备份了。
追答:
赞同Ken的回答。
但我想要添加一个没有提到的细节。我觉得吧,Docker在整个进程中也是不同于VM的,与VM相比,Docker不仅仅是关于硬件最优资源共享,还有就是,它会为应用打包提供一个“系统”(作为Microservices,最好是可以提供这样一个系统,但也不是必须要这么做。)
像rpm,debian packages,maven,npm+git这样的面向开发人员的工具,和Puppet, VMWare, Xen等等这类的工具之间有一个技术空白,对我来说,Docker正好填补了这样一个空白。
虽然问这个有点蠢,但是还是想问一下,为什么在Docker镜像上部署软件比单单部署在与其一致的生产环境中来得简单?
你的问题是假设在一致的生产环境的前提下的。但是如何将之保持一致呢?考虑到一定数量的服务和应用程序(大于10)还在管道阶段。我们为了使之同步,就要开始使用Puppet,Chef或者是自己的供应脚本,一些未发表的规则或者是很多文档。理论上来说,服务器可以无限运行的,并且保持环境完全一致,保持最新更新。实践管理无法完全管理服务器的配置,所以就会有相当大的空间配置漂移,在运行服务器的时候就会有意想不到的变化。
现在有一个已知的模式阻止这个,所谓的immutable Server。但是immutable Server并不受欢迎。很多时候由于VM的限制,通常在Docker之前使用immutableServer。处理几个基于千兆字节的大镜像的时候,移动这些大镜像只是为了改变app里面的一些域值,很费力气。真是难以理解……
有了Docker生态系统,就再也不用在小修改上面移动基于千兆字节的东西了,而且在将应用打包到Docker容器中运行的时候,也不需要担心性能损失。也不需要担心那个镜像的版本。并且最后即使是在linux笔记本上你也可以经常复制复杂的生产环境(别告诉我你没法儿用)。
当然,你也可以在VMs上开启Docker容器(这是个好主意)。在VM层次上减少服务器供应。以上都可以通过Docker托管。
P.S.同时,Docker使用自己的配置来执行“libcontainer”来替代LXC。但是LXC也还是可以使用的。
通过这个帖子,我们现在来列出一些VM和LXC之间的差别。首先呢,让我们来定义一下他们。
![]() |
(图片来源于网络) |
VM:
VM就是一个虚拟机器模拟物理计算环境,但是还是需要CPU,内存,硬盘,网络以及其他硬件资源通过虚拟层次来托管,并将这些请求转化为底层物理硬件。
在这情境下,VM是游客,而运行的环境则是主机。
LXC:
LXC是操作系统层次权证,使运行多个相互隔离的Linux容器在一个控制主机上(LXC主机)。Linux容器以轻便的优势,以及不需要监控程序(即Virtualbox,KVM,Xen等等)替代了VM。
现在除非你是被Alan(《宿醉》系列主角之一)下药了,或者是过去那么多年都在Vegas,那么你应该很清醒的知道Linux容器技术所喷射出的巨大的利益。如果要我说的话,容器项目在过去几个月内创造的轰动世界的就是,Docker引领了一些可以在云计算环境中 的建议。容器技术由于其较低的开销和潜在的性能将取代VM。
但是问题是,它可行吗?这么做明智吗?
a.
LXC只能运行在Linux的实例上。它可能就是不同口味的Linux Ubuntu容器(例如:Centos主机上的Ubuntu仍然是Linux)。同样的,基于windows的容器只能运行在windows的实例上,如果我们看VM的话,会发现,他们有一个更加广阔的视野,并且使用管理程序,这样你就不再局限于操作系统Linux或者windows了。
b.
LXC管理费用较低,而且性能比VM更好。工具(即Docker)是建立在LXC技术的基础上,提供给开发者一个平台来运行他们的应用,同时,授权给使用Ops的人们一个可以让他们部署同样的容器在生产服务器或者是数据中心的工具。它尝试着让开发人员在运行程序的时候的经验来启动和测试应用,来启动测试操作人员,来无缝配置这个应用。因为这就是矛盾存在的地方,也是DevOps要打破这些筒仓的目的。
因此,最佳的做法就是,云计算基础设施提供者应该提倡适当使用VM和LXC的方法,因为他们都是处理特定的工作负载和场景。现在放弃VM是不切实际的,所以VM和LXC都有他们各自存在的道理和重要性。
他们两个都是很独特的。
Docker很轻便,而且使用LXC/libcontainer(依赖于内核namespace和cgroup),也没有机器/硬件仿真,比如管理程序,KVM,Xen,这些都是很繁重的。
Docker和LXC对沙箱机制,容器化和资源意味颇多。它使用主机(目前只有linux内核)的克隆API,这个API可以提供namespacing给IPC, NS(mount),namespacing,NS(mount),网络,PID,UTS等等。那么内存,io,cpu这些怎么样呢?这些地方都是可以通过特定的资源(cpu,内存)规范/限制来创建groups的,并且还可以把你的程序也放在那里。在LXC上,Docker提供存储后端服务(http://www.projectatomic.io/docs/filesystems/)。
比如,可以在单元加载文件系统里添加图层,并且在不同的加载namespace里分享图层。这是一个强大的功能,在这里,基底镜像通常是只读的,只有当容器在图层里修改东西的时候,它才会写一些东西来读写分区(又名“写前拷贝”)。同时,它也提供了许多的包装比如注册表以及多版本镜像。有了普通的LXC,你需要有一些rootfs,或者分享一些rootfs。当分享的时候,作出的修改会在其他容器上体现。由于添加了很多这样的功能,docker比LXC受欢迎得多。LXC在嵌入式环境中很受欢迎,因为在进程中采取安全技术保护措施会暴露在外部实体比如网络和用户界面。Docker在云的多用户租赁环境中很受欢迎,这种环境下很期待一致的生产环境。
通常VM(virtualbox,VMware)使用管理程序,相关的技术有一个可以成为第一操作系统的第一层的专属固件,没有那个的话,就是有一个可以在主机操作系统上运行的软件来给游客操作系统提供硬件仿真比如CPU,USB/配件,内存,网络等等。虚拟机仍然(截至2015年)在高安全多租户环境中很受欢迎。
Docker/LXC几乎可以在任何便宜的硬件上运行(小于1GB的内存也可以,只要你有新的内核就可以)。而普通的VM要执行任意有意义的事情则需要至少2GB的内存。但是Docker支持主机操作系统,却不支持像windows一样的操作系统(截至2014年11月),而VM的很多类型都可以在windows,linux,mac上面运行。
以上是来自Stack Overflow的一篇问答帖,点击这里阅读原文