设为首页 收藏本站
查看: 765|回复: 0

[经验分享] 【转】唱衰docker,给大红大火的Docker泼点冷水

[复制链接]

尚未签到

发表于 2016-1-11 13:56:28 | 显示全部楼层 |阅读模式
  from:http://www.infoq.com/cn/articles/bad-mouthing-docker
  
从我上一次对Docker进行评价到现在已然经过了一年有余,想当初我在文章里对这套容器技术方案的架构设计缺陷与糟糕的用户体验做出了严厉的批判。不过在这段时间当中,Docker项目也开始逐步走向成熟,迎来自己的1.0版本并在Amazon的推动下声名大噪,但同时用户挫败感、过度宣传引发的指责甚至因漏洞遭利用而引发主机感染越来越多。当然,Docker Hub中私有库的引入让用户不必再为了托管部署而运行自有Registry系统,再配合webhook以及同GitHub的紧密集成, Docker看起来有一个良好的前途。
有鉴于此,我决定再给Docker一次机会,并以六个月为周期将其引入生产环境。结果非常糟糕,Docker性能极差,而旁门左道的解决方案加上以用户体验为代表的种种短板简直令人抓狂。实际上,Docker的性能表现实在太差,禁用缓存功能竟然能够加快build速度。
(感兴趣的朋友可以查看reddit与ycombinator网站上与该主题相关的讨论内容)。
 
相关厂商内容
AWS最新白皮书下载:安全、灾备、大数据分析、DevOps、企业备份。
探究AWS开发者生态最佳实践
有钱任性:注册即送 AWS 25美金折扣券
AWS新推WorkMail 主打兼容性与安全性
Bluemix动手实验室
 



相关赞助商
InfoQ AWS专区,汇聚AWS精华内容与最新信息,精彩呈现!


 

Dockerfile
Dockerfile存在着一系列问题,它令人讨厌、充满局限、不伦不类而且包含根本性缺陷。假如要构建一个库的多个镜像,例如第二个镜像包含内容调试工具,但两个镜像拥有同样的基础运行要求。Docker不支持这种做法(详见9198号问题),我们无法扩展Dockerfile(详见735号问题),使用子目录会破坏构建上下文并导致用户无法使用ADD/COPY(详见2224号问题)或者“管道(piping)”(详见2112号问题),我们也不能在构建过程中通过环境变量实现有条件的指令变更(详见2637号问题)。
我们给出的解决方案是创建一个基础镜像,两个特定环境的镜像以及其它一些包括重命名以及sed替换功能的Makefile自动化。除此之外,Docker中还有一些意想不到的“功能”有可能导致环境变量$HOME消失,进而产生无用的错误信息。太令人厌恶了。
Docker缓存/层
Docker有能力利用COW(即写入时复制)文件系统实现缓存Dockerfile指令,这一点与LVM快照机制相似,而且直到最近都只支持AuFS,而后者还存在大量问题。之后,0.7版本引入了多种不同的COW实现方式以改进稳定性与性能,感兴趣的朋友可以点击此处了解更多细节信息。
 
然而,这套缓存系统不智能,它不能阻止单一指缓存(详见1996号问题),产生了一些意料之外的副作用。它的运行速度也极为缓慢,如果禁用缓存并避免使用层,其构建速度甚至能够得到提升。而Docker Hub缓慢的上传/下载速度则让情况进一步恶化,这个问题我们将在下文作进一步评述。
这些问题均源自Docker整体所采用的糟糕的架构设计,这直接导致它即使是在完全不适用的情况下,依然会强制执行线性指令(详见2439号问题)。作为构建缓慢的解决方案,可以使用支持异步执行的第三方工具,例如Salt Stack、Puppet甚至bash,它们完全能够达成层的目的而使层变得没用。
Docker Hub
Docker鼓励用户通过Docker Hub进行社会化合作。用户可以在上面发布Dockerfile——包括公开与私有文件。其他用户可以通过FROM指令而不是复制/粘贴来继承并使用这些Dockerfile。该生态系统类似于AWS市场以及Vagrant Boxes中的AMI,从理论上讲还是非常有用的。
然而由于一些原因,Docker Hub的实现存在缺陷。Dockerfile不支持多FROM指令(详见3378号、5714号以及5726号问题),这意味着只能继承单个镜像。此外,它没有版本强制。举例来说,dockerfile/ubuntu:14.04的作者可以替换该标签的内容,这相当于允许用户使用软件包管理器但又不没有版本强制机制。而且正如下文所提到,Docker Hub在这方面存在着令人沮丧的速度缓慢的限制。
Docker Hub还拥有一套自动化构建系统,能够检测到库中新提交内容并触发容器构建。因为许多原因,这项功能也是完全没用。由于几乎不能定制,构建配置受到了极大限制,甚至无法支持最基本的脚本执行前/后的钩子。Docker Hub采用一套特殊的项目结构,一个项目下只能有一个Dockerfile,这破坏了我们先前提到的构建解决方案,而且构建速度极为缓慢。
我们的解决方案是使用CircleCI,它是一个优秀的托管CI平台,能够从Makefile触发Docker构建并推送到Docker Hub。虽然这种方式无法解决速度慢的问题,但唯一的可选方案是使用我们自己的Docker Registry,其复杂程度都到了荒唐的地步。
安全性
Docker最初使用LXC作为默认执行环境,但现在,0.9版本默认使用libcontainer。这使得用户可以调整命名空间功能、权限,并且可以在使用合适的exec-driver时使用自定义的LXC配置文件。
这需要一直在主机上运行一个root守护进程,而且Docker一直存在着若干安全漏洞,例如CVE-2014-6407以及CVE-2014-6408。坦率地讲,这些问题起初就不应该存在。甚至Gartner公司也在其追踪报告中给出了糟糕评价,并表达了对Docker的不成熟和安全性问题的担忧。
按照设计,Docker对于命名空间功能给予充分信任,这就导致其攻击面要比其它典型的虚拟机管理程序更宽。Xen拥有129项CVE,相比之下Linux则拥有1279项。在某些情况下上述问题并非不可接受,例如在Travis CI当中进行公开构建,但这对于私有、多用户环境来说无疑是危险的。
容器与虚拟机并不是一回事
命名空间与cgroups功能极为强大,允许一个进程及其子进程拥有一个共享内核资源——例如网络堆栈以及进程表——的私有视图。这种细粒度控制与隔离机制配合上chroot jailing与grsec,能够提供非常出色的保护层。一些应用程序,如uWSGI,可以在没有Docker的情况下直接利用这些特性的优点,而不支持命名空间的应用程序则可以利用firejail实现沙箱化处理。如果您有冒险精神,可以将这种支持直接添加到自己的容器化项目的代码中,例如LXC以及Dokcer,从而在单一内核空间中利用这些特性的有点高效地运行多套发行版。相较于虚拟机管理程序,这种作法有时候会有降低内存使用率和减少启动时间的好处,但其代价就是降低安全性、稳定性以及兼容性。举个与Linux Kernel Interface相关的最糟糕的极端案例,在内核及用户空间中运行不兼容或者未经测试的glibc组合版本很可能引发意料之外的行为。
早在2008年LXC尚处于构思阶段时,硬件辅助虚拟化也仅仅诞生了几年时间,许多虚拟机管理程序都存在着性能以及稳定性问题。因此,虚拟化技术并没有得到广泛应用,而面对成本以及物理基础设施占用减少等优势,上述问题是可以接受的。不过如今我们的虚拟机管理程序在性能表现方面几乎与裸机设备不相上下,而且有趣的是,在某些情况下速度更快。另外,托管的、按需分配的虚拟机速度越来越快,成本越来越低,DigitalOcean在性能与成本方面都要远远胜过EC2,这也使应用程序与虚拟机之间进行一对一映射从经济角度讲成为可能。
[编辑意见]正如Bryan Cantrill提出的观点,虚拟化技术的性能将受到工作负载类型的显著影响。例如,IO任务繁重的应用程序会导致性能降低。
在某些特定的应用场景中,容器化确实是恰当的解决方案,不过除非能够明确说明为什么在你的应用场景中选择此类处理方式,否则你可能应用使用虚拟机管理程序代替。而且即使使用虚拟化技术方案,你仍然应该利用命名空间的优点,而在应用程序没有对这些特性提供原生支持的情况下,像firejail这样的工具可以提供帮助。
Docker并不是必须的
Docker增加了一个复杂的侵入层,使开发、故障排查以及调试工作的难度大幅上升,它带来的问题往往多于它能够解决的问题。它在部署上也没有任何优势,因为你仍然需要利用快照实现响应式自动扩展。更糟糕的是,如果大家并没有使用快照机制,那么生产环境的扩展就会依赖于Docker Hub的稳定性。
目前有不少项目都在滥用容器化技术,例如baseimage-docker,该镜像旨在通过运行作为入口的init.d简化检查、调试和兼容,甚至还提供一个可选的SSH服务器,实际上是将容器当作虚拟机对待,虽然作者本人以无甚说服力的言词反对这种观点。
总结
如果开发流程合乎情理,那么你已经明白Docker不是必须的。Docker中号称能够带来助益的全部功能要么完全无用,要么实现很差,而其最大的优势直接使用命名空间就很容易实现。如果放在8年前,Docker是一个有趣的概念,但以现在的眼光来看,它几乎是没用的。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-163106-1-1.html 上篇帖子: Docker(2)Repositories and PHP example on CentOS 下篇帖子: 解决Docker build时 Sending build context to Docker daemon 过大的问题
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表