Docker 为 lxc-tools(用户空间 LXC 工具)添加了啥?

Posted

技术标签:

【中文标题】Docker 为 lxc-tools(用户空间 LXC 工具)添加了啥?【英文标题】:What does Docker add to lxc-tools (the userspace LXC tools)?Docker 为 lxc-tools(用户空间 LXC 工具)添加了什么? 【发布时间】:2013-08-02 02:17:48 【问题描述】:

如果你看一下 Docker 的特性,大部分都是 LXC 提供的。

那么 Docker 增加了什么?为什么我要使用 Docker 而不是普通的 LXC?

【问题讨论】:

【参考方案1】:

来自Docker FAQ:

Docker 不是 lxc 的替代品。 “lxc”指的是 linux 内核的功能(特别是命名空间和控制组),它们允许将进程相互沙盒化,并控制它们的资源分配。

在内核功能的这种低级基础之上,Docker 提供了一个具有多种强大功能的高级工具:

跨机器的可移植部署。 Docker 定义了一种格式,用于将应用程序及其所有依赖项捆绑到一个对象中,该对象可以传输到任何支持 docker 的机器上,并使用保证暴露给应用程序的执行环境是相同的。 Lxc 实现了进程沙箱,这是可移植部署的一个重要前提条件,但仅此一点还不足以进行可移植部署。如果您向我发送了一份安装在自定义 lxc 配置中的应用程序的副本,它几乎肯定不会像在您的机器上那样在我的机器上运行,因为它与您机器的特定配置相关:网络、存储、日志记录、发行版、等。Docker 为这些特定于机器的设置定义了一个抽象,以便完全相同的 docker 容器可以在许多不同的机器上运行 - 不变 - 具有许多不同的配置。

以应用程序为中心。 Docker 针对应用程序的部署进行了优化,而不是机器。这反映在其 API、用户界面、设计理念和文档中。相比之下,lxc 辅助脚本专注于将容器作为轻量级机器——基本上是启动速度更快且需要更少内存的服务器。我们认为容器不仅仅如此。

自动构建。 Docker 为开发人员提供了一个工具,可以从他们的源代码自动组装一个容器,完全控制应用程序依赖项、构建工具、打包等。他们可以免费使用 make、maven、chef、puppet、salt、debian 包、rpms、源tarball 或以上的任意组合,无论机器的配置如何

版本控制。 Docker 包含类似 git 的功能,用于跟踪容器的连续版本、检查版本之间的差异、提交新版本、回滚等。历史还包括 容器是如何组装的以及由谁组装的,因此您可以从生产服务器一直到上游开发人员获得完整的可追溯性。 Docker 还实现了增量上传和下载,类似于“git pull”,因此只需发送 diff 即可传输容器的新版本。

组件重用。任何容器都可以用作“基础映像”来创建更专业的组件。这可以手动完成,也可以作为自动构建的一部分。例如,您可以准备理想的 Python 环境,并将其用作 10 个不同应用程序的基础。您理想的 postgresql 设置可以重新用于您未来的所有项目。以此类推。

共享。 Docker 可以访问公共注册表 (https://registry.hub.docker.com/),成千上万的人在其中上传了有用的容器:从 redis、couchdb、postgres 到 irc 保镖再到 rails 应用服务器的任何东西将 hadoop 作为各种发行版的基础映像。注册表还包括由 docker 团队维护的有用容器的官方“标准库”。注册表本身是开源的,因此任何人都可以部署自己的注册表来存储和传输私有容器,例如用于内部服务器部署。

工具生态系统。 Docker 定义了一个 API,用于自动化和自定义容器的创建和部署。有大量工具与 docker 集成以扩展其功能。类 PaaS 部署(Dokku、Deis、Flynn)、多节点编排(maestro、salt、mesos、openstack nova)、管理仪表板(docker-ui、openstack Horizo​​n、shipyard)、配置管理(chef、puppet)、持续集成(jenkins、strider、travis)等。Docker 正在迅速将自己确立为基于容器的工具的标准。

我希望这会有所帮助!

【讨论】:

当您说“任何容器都可以用作基础镜像”时,我认为您的意思是 Docker 容器,而不是独立于 Docker 创建的 LXC 容器。据我所知,不能从头开始创建 Docker 容器,它必须始终从另一个 Docker 容器继承(相关问题:***.com/questions/18274088/…)。 您可以使用“docker import”从任何 tarball 轻松创建新容器。例如:“debootstrap raring ./rootfs; tar -C ./rootfs -c . | docker import flimm/mybase”。 既然 Docker 有了 libcontainer(它不是替代品),这仍然是真的吗? @GaretClaborn 是的,因为 libcontainer 只是他们自己的用于访问命名空间和 cgroup 的库,所以所罗门所说的一切仍然适用。 Linux 容器是使用一组 Linux 工具限制和隔离进程的结果:chroot、cgroups 和命名空间。 LXC 是一个操纵这些设施的用户空间工具。 libcontainer 是 LXC 的替代品,可以操作这些相同的设施。 Docker 默认使用 libcontainer,但也可以使用 LXC。也就是说,Docker 不仅仅是 libcontainer/LXC 之上的一个兼容层。它添加了其他答案列出的其他功能。【参考方案2】:

让我们看看list of Docker's technical features,看看哪些是LXC提供的,哪些不是。

特点:

1) 文件系统隔离:每个进程容器运行在一个完全独立的根文件系统中。

提供普通的 LXC。

2) 资源隔离:可以使用 cgroups 将 cpu 和内存等系统资源分配给每个进程容器。

提供普通的 LXC。

3) 网络隔离:每个进程容器在自己的网络命名空间中运行,具有自己的虚拟接口和 IP 地址。

提供普通的 LXC。

4) Copy-on-write:根文件系统是使用 copy-on-write 创建的,这使得部署速度非常快,内存和磁盘都很便宜。

这是由 AUFS 提供的,它是 Docker 所依赖的联合文件系统。您可以使用 LXC 手动设置 AUFS,但 Docker 将其用作标准。

5) 日志记录:收集并记录每个流程容器的标准流(stdout/stderr/stdin),以便实时或批量检索。

Docker 提供了这个。

6) 变更管理:对容器文件系统的变更可以提交到新镜像中并重新用于创建更多容器。无需模板或手动配置。

“模板化或手动配置”是对 LXC 的引用,您需要了解这两方面的知识。 Docker 允许您像处理虚拟机一样处理容器,而无需了解 LXC 配置。

7) 交互式 shell:docker 可以分配一个伪 tty 并附加到任何容器的标准输入,例如运行一次性的交互式 shell。

LXC 已经提供了这个。


我才刚刚开始学习 LXC 和 Docker,所以我欢迎任何更正或更好的答案。

【讨论】:

恕我直言,这个答案没有抓住重点。 Docker 不“提供”这些功能。它只是使它们易于使用。如果我们想挑剔,我们可以说 LXC 不提供隔离:namespaces 提供它,而 LXC 只是一个商品用户空间工具,使它们比基本的unshare 更易于使用工具(或直接使用clone() 系统调用)。同样,Docker 使这些东西更易于使用(并带来了更多功能,例如推/拉图像的能力)。我的 2c。 @jpetazzo:LXC 其实很简单,Docker 是如何让它变得更简单的(除了添加其他功能,比如推送和拉取图像)? @Flimm:我喜欢Admin Magazine 的第 16 期中的比较,第 16 页。 34:Docker 将 LXC 与其他一些支持技术捆绑在一起,并将其包装在一个易于使用的命令行界面中。使用容器有点像尝试仅通过 update-indexread-tree 之类的命令使用 Git,而没有 addcommitmerge 等熟悉的工具。 Docker 在 LXC 的“管道”之上提供了“瓷器”层,使您能够处理更高层次的概念,而不必担心低层次的细节。 我在 docker 容器和 LXC 容器中运行了 UnixBench 基准测试,运行相同的操作系统,LXC 在得分方面表现出色。作为基于 LXC 的 docker,我对自己的结果感到非常困惑。 在我看来,Docker的性能下降与磁盘I/O有关,因此可能是由于采用了AUFS。【参考方案3】:

随着LXD continues to enhance LXC 的发展,上述帖子和答案正在迅速过时。是的,我知道 Docker 也没有停滞不前。

LXD 现在为 LXC 容器镜像实现了一个存储库,用户可以从中推送/拉取以贡献或重用。

LXD 到 LXC 的 REST api 现在支持本地和远程使用非常简单的命令语法创建/部署/管理 LXC 容器。

LXD 的主要特点是:

通过设计确保安全(非特权容器、资源限制和 更多) 可扩展(从笔记本电脑上的容器到数千个计算 节点) 直观(简单、清晰的 API 和清晰的命令行体验) 基于图像(不再有分发模板,只有好的、受信任的 图片)实时迁移

有NCLXD plugin now for OpenStack allowing OpenStack 使用 LXD 将 LXC 容器部署/管理为 OpenStack 中的虚拟机,而不是使用 KVM、vmware 等。

不过,NCLXD 还支持混合了传统硬件虚拟机和 LXC 虚拟机的混合云。

OpenStack nclxd 插件支持的功能列表包括:

stop/start/reboot/terminate container
Attach/detach network interface
Create container snapshot
Rescue/unrescue instance container
Pause/unpause/suspend/resume container
OVS/bridge networking
instance migration
firewall support

到 2016 年 4 月发布 Ubuntu 16.04 时,将会有其他很酷的功能,例如块设备支持、实时迁移支持

【讨论】:

【参考方案4】:

Docker 使用分层构建的图像。这在可移植性、共享、版本控制和其他功能方面增加了很多。这些图像非常容易移植或传输,并且由于它们是分层的,因此后续版本中的更改以层的形式添加到先前的层上。因此,在多次移植时,您不需要移植基础层。 Docker 拥有运行这些包含执行环境的镜像的容器,它们将更改添加为新层,从而提供简单的版本控制。

除此之外,Docker Hub 是一个很好的注册表,包含数千个公共镜像,您可以在其中找到安装了操作系统和其他软件的镜像。因此,您可以为您的应用程序获得一个很好的开端。

【讨论】:

当您说“内置层”时 - 这是什么意思 - (A) 基础层的副本,经过调整并提交给“新”层。那么,基础层与下一层断开了吗? (B) 基础层包含在“新”层中并且也被链接。因此,对基础层的更改会自动反映到“新”层。抱歉,如果所寻求的澄清过于幼稚。 :( 卡皮尔 Docker 镜像是分层构建的。用细粒度的术语来说,当一个层被提交时,所有的变化都存在于直到那个点的图像层中。之后所做的任何更改都将添加到下一层和上一层。因此,新层链接到基础层。我不认为可以将相同的新层添加到不同的基础层并进行额外的更改。但是,如果多个实体想要保持一致性并具有相同的基础层,则只需将新层赋予这些实体即可达到相同的状态。 但是,我没有更新关于 docker 的当前发展情况,并且可能对 docker 映像实现进行了上述评论未涵盖的更改。 更具体地说,层由签名标识(我相信是 SHA-something),这意味着如果您更改层,它是不同的层。 @ Kapil:这意味着虽然它的行为更接近您的选项 (B),但您实际上无法对基础层进行更改。 (或任何层,就此而言)图像由层列表构建,每个层都按顺序应用;不再需要时,可以清理层(我认为它们会由 docker 自己自动清理);即,当所有参考图像都已被删除时。 @Kapil:老实说,您的问题可能最适合作为一个新问题,而不是作为对此问题的评论,因为它对人们能够自行查找很有用。如果你想作为一个新问题问它,我也会在那里回答。【参考方案5】:

要保持这个简洁,这已经被问到并回答了above。

不过,我会退后一步,回答稍有不同,docker 引擎本身添加了编排作为其附加功能之一,这是破坏性的部分。一旦您开始将应用程序作为跨多个容器引擎“某处”运行的容器组合来运行,它就会变得非常令人兴奋。鲁棒性、水平扩展、从底层硬件中完全抽象出来,我可以继续……

不仅仅是 Docker 提供了这个功能,事实上,事实上的容器编排标准是 Kubernetes,它有很多不同的风格,一个 Docker,还有 OpenShift、SuSe、Azure、AWS...

那么在 K8S 之下还有替代的容器引擎;有趣的是 Docker 和 CRIO——最近构建的无守护进程,旨在作为专门用于 Kubernetes 但不成熟的容器引擎。我认为它们之间的竞争将是容器引擎真正的长期选择。

【讨论】:

以上是关于Docker 为 lxc-tools(用户空间 LXC 工具)添加了啥?的主要内容,如果未能解决你的问题,请参考以下文章

docker基础-基本概念

Docker的名字空间

docker 学习

Docker镜像

Docker镜像

docker 笔记 base镜像