来自 知乎:https://www.zhihu.com/question/22969309

作者: Li Yingjie

下面是我总结的一些Docker的使用场景,它为你展示了如何借助Docker的优势,在低开销的情况下,打造一个一致性的环境。内容来自:八个Docker的真实应用场景
1. 简化配置
这是Docker公司宣传的Docker的主要使用场景。虚拟机的最大好处是能在你的硬件设施上运行各种配置不一样的平台(软件、系统),Docker在降低额外开销的情况下提供了同样的功能。它能让你将运行环境和配置放在代码中然后部署,同一个Docker的配置可以在不同的环境中使用,这样就降低了硬件要求和应用环境之间耦合度。
2. 代码流水线(Code Pipeline)管理
前一个场景对于管理代码的流水线起到了很大的帮助。代码从开发者的机器到最终在生产环境上的部署,需要经过很多的中间环境。而每一个中间环境都有自己微小的差别,Docker给应用提供了一个从开发到上线均一致的环境,让代码的流水线变得简单不少。
3. 提高开发效率
这就带来了一些额外的好处:Docker能提升开发者的开发效率。如果你想看一个详细一点的例子,可以参考Aater在DevOpsDays Austin 2014 大会或者是DockerCon上的演讲。
不同的开发环境中,我们都想把两件事做好。一是我们想让开发环境尽量贴近生产环境,二是我们想快速搭建开发环境。
理想状态中,要达到第一个目标,我们需要将每一个服务都跑在独立的虚拟机中以便监控生产环境中服务的运行状态。然而,我们却不想每次都需要网络连接,每次重新编译的时候远程连接上去特别麻烦。这就是Docker做的特别好的地方,开发环境的机器通常内存比较小,之前使用虚拟的时候,我们经常需要为开发环境的机器加内存,而现在Docker可以轻易的让几十个服务在Docker中跑起来。
4. 隔离应用
有很多种原因会让你选择在一个机器上运行不同的应用,比如之前提到的提高开发效率的场景等。
我们经常需要考虑两点,一是因为要降低成本而进行服务器整合,二是将一个整体式的应用拆分成松耦合的单个服务(译者注:微服务架构)。如果你想了解为什么松耦合的应用这么重要,请参考Steve Yege的这篇论文,文中将Google和亚马逊做了比较。
5. 整合服务器
正如通过虚拟机来整合多个应用,Docker隔离应用的能力使得Docker可以整合多个服务器以降低成本。由于没有多个操作系统的内存占用,以及能在多个实例之间共享没有使用的内存,Docker可以比虚拟机提供更好的服务器整合解决方案。
6. 调试能力Docker
提供了很多的工具,这些工具不一定只是针对容器,但是却适用于容器。它们提供了很多的功能,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,这些特性可以帮助调试Bug。你可以在《Docker拯救世界》的文章中找到这一点的例证。
7. 多租户环境
另外一个Docker有意思的使用场景是在多租户的应用中,它可以避免关键应用的重写。我们一个特别的关于这个场景的例子是为IoT(译者注:物联网)的应用开发一个快速、易用的多租户环境。这种多租户的基本代码非常复杂,很难处理,重新规划这样一个应用不但消耗时间,也浪费金钱。
使用Docker,可以为每一个租户的应用层的多个实例创建隔离的环境,这不仅简单而且成本低廉,当然这一切得益于Docker环境的启动速度和其高效的diff命令。
你可以在这里了解关于此场景的更多信息。
8. 快速部署
在虚拟机之前,引入新的硬件资源需要消耗几天的时间。Docker的虚拟化技术将这个时间降到了几分钟,Docker只是创建一个容器进程而无需启动操作系统,这个过程只需要秒级的时间。这正是Google和Facebook都看重的特性。
你可以在数据中心创建销毁资源而无需担心重新启动带来的开销。通常数据中心的资源利用率只有30%,通过使用Docker并进行有效的资源分配可以提高资源的利用率。
编辑于 2015-01-28


作者: bnm zasdfg

我来说一个比较不一样的应用场景吧,这个是我最近在搞着玩的东西:把docker的镜像在裸机上跑,当作自己的日常桌面系统使用!

大家在按照正常的习惯使用日常桌面系统的时候,或多或少都会遇到下面的这些问题吧:

  1. 某天莫名其妙地出于某种原因,系统突然坏了,可能是某个程序的文件不小心损坏了吧,磁盘并没坏,重装一下就好了,问题再也不见了,然而重装+配置浪费了一上午的时间。
  2. 系统用的久了,慢慢变慢了,也产生了一些不会被自动清除的垃圾文件,这些文件堆放的零零散散的,清理起来也不好清理。
  3. 某次系统更新,包管理器提示说文件冲突,或者依赖关系无法满足,导致更新安装不上,折腾了好久都没法更新。
  4. 磁盘突然挂了,然而自己好久都没有备份系统了,衰。
  5. 自己决定干一件什么事情了,于是安装了一大堆的库,跟工具,还费了半天劲去配置。然而自己有多台设备,所有的这些安装配置的流程要在自己家里的pc上,笔记本上,办公室的pc上这些地方都走一遍,很麻烦。
  6. 换了台新电脑,又要重新安装操作系统,然而已经不记得随着时间的推移,自己是怎么一步步把现在电脑上运行的系统配制成自己用这最舒服的状态了。而且就算记得,重新配置一遍也麻烦。
  7. 偶尔借用一下别人的电脑,或者用一下网吧的公用电脑。然后发现别人的电脑真难用啊,各种东西都没有配制成自己习惯的样子。

所有的这一切问题,都可以用docker来帮我们解决:我们写一个Dockerfile制作一个镜像,这个镜像包含我们桌面系统用到的一切。然后把这个镜像上传到DockerHub提供的免费空间上去。然后,在本地通过对initramfs做一些手脚,在启动的时候,直接把镜像的本地docker缓存中的内容当作根目录挂载并启动,这样就可以把docker镜像直接在裸机上跑,当日常系统用了。这么做,上述的那些问题都能得到解决:

  1. 参考docker容器的工作原理。Docker镜像是只读的,每运行一次镜像,docker都会创建一个读写层,所有的写入都是在最上方的读写层中进行的。我们这里采用了相同的手段,每次开机都新建一个读写层,这就好比装了网吧的还原精灵,不管这次开机的过程中是不是某个程序出bug把啥东西搞坏了,这都无所谓,下次开机又是一条好汉。
  2. 同上
  3. 每次更新系统实际上都是用Dockerfile从最新的软件仓库重新构建一遍,自然不会有跟之前某些包的依赖图或者文件出现冲突的情况。
  4. 本地只是云端的缓存而已,根本没必要定期备份。
  5. 多台设备之间同步系统的更改非常简单,只需要一个docker pull然后重启就行了。
  6. 新电脑是不需要从头安装操作系统的,用光盘启动,分好区,挂载到/var/lib/docker上面去,docker pull一下,然后安装个启动管理器就行了。
  7. 偶尔用一下别的电脑,只需要在那台电脑上安装docker,然后就可以直接在docker里面启动一个kde桌面,然后一切都回到了自己最熟悉的样子。

OK, 说了这么多,技术细节见博客:
https://zasdfgbnm.github.io/2017/12/28/%E6%8A%8Adocker%E9%95%9C%E5%83%8F%E5%BD%93%E4%BD%9C%E6%A1%8C%E9%9D%A2%E7%B3%BB%E7%BB%9F%E6%9D%A5%E7%94%A8/

更新一下吧,评论区有人问docker怎么运行图形界面的程度:我给出的答案是:
最好的方法就是直接把docker在裸机上(而不是容器中)运行。
这种方法具体实现请参见我上面附上的博客链接。
https://github.com/zasdfgbnm-dockers/archlinux-kde
https://github.com/zasdfgbnm-dockers/scripts/blob/master/docker-startkde

或者另一种变通点的方法是,给display manager添加一个xsession,这个xsession做的事情就是docker run一个容器中的startkde,注意开启—privileged,关掉网络隔离,然后把/run等的目录传给docker容器。这样的话,容器中的程序就会链接host上的xserver来显示。具体的话参见下面这几个链接:

编辑于 2017-12-31


作者: Yohann

简单说就是PaaS,可实现方便的服务创建、删除,做到可伸缩,意义重大。可以快速构建一个容器,很快的构建一个 PaaS 容器,对不同的环境使用不同的 Docker 容器即可。

flynn和deis是基础Docker实现的开源PaaS,相比CloudFoundry更小、更轻。

Docker依赖Linux LXC技术,轻量容器概念,其上实际运行的程序是在宿主机上的,本身不是完整的程序系统,也正是其特别之处。


根据Docker布道师Jerome Petazzoni的说法,Docker约等于LXC+AUFS(之前只支持ubuntu时)。其中LXC负责资源管理,AUFS负责镜像管理;而LXC又包括cgroup、namespace、chroot等组件,并通过cgroup进行资源管理。所以只从资源管理这条线来看的话,Docker、LXC、CGroup三者的关系是:cgroup在最底层落实资源管理,LXC在cgroup上封装了一层,Docker又在LXC封装了一层。

Docker是Linux下应用容器引擎,提供一种比LXC高级的API。Docker使用Go语言开发,利用了Linux提供的LXC,AUFS,namespace和cgroup技术。实现了文件系统,资源和网络的隔离,最终目标实现类似PaaS平台的应用隔离。

LXC——Linux容器工具,容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心 CPU 本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化(paravirtualization)和系统调用替换中的复杂性。
容器在提供隔离的同时,还通过共享这些资源节省开销,这意味着容器比真正的虚拟化的开销要小得多。

我们都知道Linux有一个进程号为1,名字为init的进程,系统服务的父进程都是init进程。 Docker容器中进程号为1的进程是bash,而不是init,一个运行的Linux竟然没有init进程,简直太不思议了。这其实得益于强大的Linux提供的LXC功能。宿主机器中运行的docker服务就是该容器中ubuntu系统的init进程。其实每个运行的容器仅仅是宿主机器中运行的一个进程而已,在容器中运行的任何程序其实也是运行在宿主机器中的一个进程。Docker通过cgroup将属于每个容器的进程分为一组进行资源(内存,cpu,网络,硬盘)控制;通过namespace将属于同一个容器的进程划分为一组,使分属于同一个容器的进程拥有独立的进程名字和独立分配的进程号,比如宿主机器存在一个进程号为1的进程,容器中也存在一个进程号为1的进程。

如果对同一台服务上的少数应用需要控制资源的直接使用 cgroup 是较好的选择,可以按用户或用户组控制系统资源。如果服务需要指出多种环境,那么 Docker 就是最好的。

补充(20140625):
With the release of version 0.9 Docker.io have dropped LXC as the default execution environment, replacing it with their own libcontainer.
In other words, as of Docker 0.9, LXC is now optional.
by: Docker drops LXC as default execution environment


作者: 无知

我们(AVOS Cloud)是做 BaaS,场景非常适合使用 Docker,抛出来大家一起聊下。
在我们的平台上,一台 16 核 32G 内存的虚拟机上,需要跑 500+ 个用户的应用(每个应用的功能可以认为是一个网站 + 一系列的 RESTful API),有两个事情很重要:

  • 资源隔离:比如限制应用最大内存使用量,或者资源加载隔离等。
  • 低消耗:虚拟化本身带来的损耗需要尽量的低。

我们不可能在一台机器上开 500 个虚拟机,虽然可以在资源隔离方面做的很好,但这种虚拟化本身带来的资源消耗太严重。
另一个方面,我们可以考虑使用语言级别沙箱,虽然这种「虚拟化」本身的消耗可以低到忽略不计,但是资源隔离方面绝对是噩梦,比如你打算在一个 JVM 里隔离内存的使用。
而 Docker 很好的权衡了两者,即拥有不错的资源隔离能力,又有很低的虚拟化开销。