从国内来看,从14年的发迹,到15年的红火。基于Docker的国内创业公司不停的涌现,Docker的概念不断地炒作。软件界似乎人人在谈论Dcoker,给我的感觉就像中国大妈跳广场舞一样,歌声大,动作乱,到底有没有用,难说。毕竟Docker只是一项技术,技术是否能成功应用,给你的产品带来价值才是最重要的。下面是个人一些对Docke的看法与见解,可能有不对之处,望交流赐教:
标准化是基础
从对Linux的贡献角度来说,Docker并没有什么技术创新。但为什么它会得到如此众多的追捧,主要他得益它制定了标准。尤其是我所在电信行业感受最深,真是得标准得天下:
- 容器镜像:软件的交付件标准化,使得软件在云环境中的构建,发布,运行,迁移,复制等软件分发变得更加容易。
- 容器引擎:容器操作方式标准化,提供标准的Rest API,使得对容器的创建,删除,启停等生命周期管理更简单。
简单就是生产力
我们再来看Docker的诞生,它是来源于Docker公司前身dotCloud的实践,出发点是为了解决如何帮助开发人员实现软件的快速打包,部署。其实也就是目前大家都在说的CICD,通过统一的格式来提升打包,测试,部署的效率。所以大家看到Docker宣传的“Build,Ship,Run”,也就说它最大的特点,简化了开发到部署操作,极大地提高的软件开发验证效率。
会带来什么价值
除前面的提高软件的开发验证效率,它还能给出我们带来什么价值?首先,Docker屏蔽了软件运行环境差异,这个怎么理解呢?因为它的镜像具有便携性,一致性的特点。这极大地简化了软件在部署过程由于环境的差异带来的不确认性。其次Docker本身就是一种OS容器技术。而OS容器是基于操作系统内核的虚拟化,是一种轻量的虚拟化。相比于Hypervisor的虚拟化技术,它没有指令转化这一层,只是共享主机内核,划出不同的Namesapce。在计算能力上它是没有什么性能损耗的。容器可以运行在物理机或虚拟机之上,不依赖于虚拟化软件。所以它的价值主要体现在两大方面:
降成本(相比Hypervisor)
- 基于Hypervisor虚拟化的应用性能下降比较高,尤其是IO密集型,同等性能指标需要消耗更多的资源。
- 采Hypervisor虚拟化技术,License费用支出高,虚拟化管理软件也有成本支出。
- Hypervisor虚拟化对资源划分粒度比较大,而容器可以更细粒度你分割资源,可以提整体资源利用率。
- 虚拟机镜像大(以G为单位),启动慢(分钟级);而容器镜像相对小(以M为单位),启动快(秒级),应用可以快速伸缩,降低维护成本
- 容器能快速创建与销毁,可以应用在一些短任务的业务(如大数据分析),长短任务的业务混合部署,错峰填谷来提升资源利用率。
加速创新
- 改变软件的交付模式:CICD变得更加容易,可以使软件快速开发、上线、验证。软件开发迭代周期缩短,试错风险小,加速业务的创新能力。
- 改变软件的架构模式:容器即完整执行环境,可以使用软件“微”服务化,服务之间能够快速组合和重构,提升业务的创新能力。
网络与存储
相对于传统的虚拟化来说,包括三个方面,计算虚拟化,网络虚拟化,存储虚拟化。映射到容器技术上来说,计算能力就是Docker引擎,而网络则是容器网络管理,存储则是容器卷管理。Docker在容器管理上是相对比较成熟的,但在网络方面目前还是相对比较弱,Docker现有的网络模型主要是通过使用Network namespace、Linux Bridge、Iptables、veth pair等技术实现的。Docker提供了四种网络模式:
- host模式: 容器和宿主机共享Network namespace。没有网络隔离,多容器需要规划端口,适合不需要动态调度的静态部署使用Docker。
- bridge模式: Bridge模式是Docker的默认模式,即NAT方式,容器网卡从docker0网桥所在的IP网段中选取一个未使用的IP,容器端口映射到主机上。性能下降15~20%,对网络性能与时延敏感的应用不适合。
- container模式: 容器和另外一个容器共享Network namespace。kubernetes中的pod就是多个容器共享一个Network namespace。这些方式有它特定的应用场景。
- none模式:容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。这些方式适合通过Libnetwokr方式扩展。
目前Docker释放出Libnetwork,旨在将Docker的网络功能从Docker核心代码中分离出去,形成一个单独的库。 Libnetwork通过插件的形式为Docker提供网络功能。用户可以根据自己的需求实现自己的Driver来提供不同的网络功能。 Libnetwork引入了容器网络模型(CNM):
- Network Sandbox:容器中一个网络配置的隔离环境
- Endpoint:在某个网络上进行网络通讯的接口,Endpoint可以加入一个network,同时,多个Endpoint也可以在一个网络沙盒中共存。
- Network:一个唯一的、可识别的endpoint组,组内endpoint可以相互通讯。
Libnetwork从Docker1.7开始,目前整体来说,还是属于起步阶段。由于网络是一个绕不开的话题,网络方案热度很高,目前各个企业在使用Docker时也是有各自的解决方案,他们各所有长,没有包打天下的方案。Docker 1.9发布,已把libnetwork合入,号称已Production Ready,实际还是底层调用OVS或Vxlan。OVS与Vxlan在性能上都存在损耗。
容器卷的管理相对网络来说,热度比较低。Docker之前可以通过Monut主机的目录来解决数据持久存储的问题,由于容器的特点是便携,本地数据肯定存在数据迁移的问题。Docker 1.9重新设计的一套完整存储卷管理系统,也像网络一样,支持能过插件形式来为Docker提供卷功能,实现自己的Driver来提供不同的卷管理功能。卷管理这一块走在前面是Flocker,其它没有看到较成熟的产品。
Docker开放网络与卷管理扩展能力,可能是出于建立生态考虑。毕竟即使开源,如果系统的开放性不够,就会导致商业可能为黑寡妇,最终伤害也是自己的利益。
使用方式
正如前面所说的,容器涉及到计算,存储,网络。而目前网络与存储相对不是很成熟,也是影响着大家使用Docker的方式,目前主要有几种形态:
- IaaS + Docker:在虚拟机或物理机上是使用容器,容器是对资源进一步的分割与隔离。目前是主流,应用较成熟。
- 轻量虚拟机 + Docker:主要是虚拟化技术厂商为准,借助虚拟化在存储,网络,安全的能力。像Vmware的Photon,创建虚拟机时同时拉起容器。其它代表有Intel的ClearLinux,国内的Hyper.sh。目前还实验阶段。
目前大家还是把Docker当工具使用,因为整个工具链还不太成熟。容器编排与调度领域目前有K8S与Mesos/Marathon,Docker自家也有compose与swarm,但明显Google在这一领域更有发言权(Borg的成熟应用),也主导了CNCF。将来Google领导的K8S可能是容器编排的事实标准。
而传统的虚拟化厂商明显感到来自Docker的挑战,所以也顺适而为,摧出轻量虚拟化+Docker结合技术,来继续巩固已有的虚拟化市场,这真是一个有意义的现象。
标准之争
CoreOS不满于Docker在容器技术一家独食,发起了AppC的容器规范,并实现该规范RTK与其竞争。其后在15年6月大家握手言和,成立了OCI(Open Container Initiative)组织。RunC就是Docker贡献出来的,按照该开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。而Docker公司也很不情愿地把LibContainer以RunC方式贡献出来。从使用量来看,目前RKT使用很少,Docker是事实标准。值得一提的是,我司也在标准这块发挥着重要作用,并发布了OCT,一个基于开放容器规范的测试框架。