Docker从2013年开源,即将经历三年的不断完善与优化。2015年是Docker开源项目突飞猛进的一年,在这一年的时间里,Docker先后发布了v1.5, v1.6, v1.7, v1.8, v1.9 等5个大版本以及7个修订版。
在功能上,不仅增加了”只读容器”、”ulimit支持”、”日志驱动”、”Volume插件”、”网络插件”、”IPAM插件”等新特性,而且更增加了适合企业多样化的应用场景;user namespace的支持也合并进了1.9实验版,这使得Docker的安全性得到大大提升。
Docker registry 2(github上的distribution项目)的发布,让镜像更加标准化,镜像的传输更加高效;新增了镜像签名验证机制,保证了镜像传输的安全,在国内希云cSphere推出了微镜像。
Docker社区的活跃度也不断提升,Docker项目的社区代码贡献者由年初的900多增加到目前的1200多,活跃的开源社区为Docker的稳定性和功能改进提供了有力的保障。
在6月份的DockerCon大会上,Docker公司与Linux基金会联合推出开放容器项目(OCP),微软、IBM、Google、Intel、Amazon等巨头的加入,使Docker成为了容器技术的业界标准。实际上,容器本身的价值非常有限,重要的是容器的生态!
在本文中,我们将从Docker的功能、稳定性以及代码质量方面对2015年Docker的进展情况进行总结。
功能进一步完善
只读容器
```
需求:为了方便项目迁移、升级和扩容,往往都需要制定一系列的标准和对数据日志数据的存储位置进行约束。
问题:开发团队并不是严格遵循制定的标准进行,把数据存放到了规定之外的路径下,导致数据丢失。这种情况下怎么办?
```
Docker引入的只读容器特性使容器的rootfs以只读方式挂载,这样运维人员可以强制规定日志或数据的存储路径。如果应用程序需要写数据,必须通过-v参数指定数据目录,这样能够很好地起到了强制约束的作用。
另外的一个应用场景是:如果基于Docker做PaaS平台,只读容器可能优势更为明显。
ulimit支持
Linux的ulimit提供了一种简单的配额控制机制。但在Docker 1.6之前,一个Docker daemon管理所有容器的ulimit是共享的,使用起来很不灵活。Docker 1.6提供了基于容器的ulimit参数控制,用户可以为不同的容器设置不同的ulimit数,这样使用起来更加灵活。
build过程的配置控制
```
问题:主机上已经跑了非常多的业务容器,在资源紧缺的情况下,如何做到既能成功构建任务,又能保证业务平稳运行?
```
镜像构建往往是一个非常消耗资源的操作,主机上还运行了很多线上业务,那么在构建镜像的时候很可能过度消耗系统资源而导致线上服务不稳定。不仅要保证构建任务顺利执行,而且更要保证线上业务稳定运行。所以Docker 1.6提供了对build过程的CPU、内存等资源进行配额控制的能力。
推荐:企业生产环境中,拿出几台机器专门做构建镜像的工作,高效并且安全!
日志驱动
```
问题:容器中推荐运行1个进程,如果运行了mysql,不安装syslog服务,收集日志怎么办?
```
大家应该都很熟悉ELK,之前在虚拟机里安装syslog这种方法很奏效,但在容器这就行不通了。
所以在v1.6中提供了可扩展的日志驱动接口,内置json-file和syslog两种日志驱动,用户可以根据需求把日志写入json文件或者发送到syslog(日志中心),这样就不需要再为每个容器都安装syslog服务。
基于日志驱动的go语言接口,在接下来的几个版中,逐步添加了fluentd, journald, awslog, gelf等日志驱动模块,满足用户各种复杂的日志记录与收集需求。
容器与镜像Label
```
问题:如果应用部署在单台主机上没有问题,那么如果想部署到多台主机上,该如何调度呢?
```
Docker 官方自己做了一个项目叫Swarm,并且现在Swarm已宣布可以在生产环境中使用。为了方便Swarm之类的集群管理工具对主机进行分组管理,在v1.4中,用户可以为Docker Daemon指定一个或多个Label,满足应用部署调度到相对应的服务器上。
Docker 1.6新增了容器与镜像Label的支持,方便用户根据Label来对容器和镜像进行分组管理与过滤。
Volume插件
```
问题:容器删除后,如何确保容器里的数据不被删除?
```
为了确保删除容器数据不被删除,我们之前的做法就是通过-v把容器的数据目录和主机的目录做一个映射,但这样数据还是存放在本地磁盘中。在v1.7实验版引入了Volume插件机制,用户可以根据需要开发自己的Volume插件来使用外部存储服务。
比如:通过AWS EBS Volume插件,可以在创建容器时,自动创建一块EBS,把容器的数据保存在EBS上。
如果需要,用户也可以自己根据Volume插件的RPC接口规范开发适合自己的Volume插件,通过企业内部的NAS、SAN等存储服务来保存容器数据。
Volume插件在v1.8进入正式版对外发布,这样一来Docker存储问题也就迎刃而解了。
Overlay网络
```
问题:单台主机容器之间通信没有问题,如果跨主机通信怎么办?
```
Docker容器ip不固定,以及跨主机互联一直是困扰Docker用户的一个问题,也是阻碍企业落地的一块绊脚石。
在Docker支持Overlay网络之前,常用的跨主机通信方案是通过在每台主机上运行ambassador容器作为代理。这种方式无疑造成了管理成本的增加,而且也不适合用到生产环境。
Docker 1.9正式支持了基于VXLAN的Overlay网络,用户可以通过Overlay网络方便的实现容器跨主机通信,但是仅仅是解决了跨主机通信,并没有实现固定容器的IP功能。
网络插件
6月份之前,Docker默认提供了bridge(NAT)网络、Host网络、容器网络(与其它容器共享网络命名空间)以及none(该模式下容器不创建网络设备,无法与外界通讯)等四种网络模式。
虽然这几种网络模式能满足大多数应用场景的需求,但不够灵活,用户无法直接使用企业内部现有的SDN来为容器提供网络服务。
在1.7发布之际,Docker实验版引入网络插件功能。基于网络插件的RPC协议,用户可以开发自定义的网络插件来为容器提供网络服务。
比如:用户可以自己开发基于IPVLAN、MACVLAN、VXLAN等技术的网络插件实现跨主机通信。第三方提供的网络插件也如雨后春笋般出现,如:支持多租户网络的Contiv 插件(https://github.com/contiv/netplugin),支持跨主机跨云通信的Weave网络插件等。
希云cSphere平台支持容器静态IP、容器重启后IP保持不变、跨主机通讯、内置名字服务,以及服务发现功能的网络方案,也很大程度上利用了Docker的插件机制,使企业业务在生产环境上更加有保证。
网络插件在历经半年之久的打磨后,1.9版本正式对外发布。
User Namespace
```
问题:如果容器和宿主机所使用的用户一样,那么容器安全吗?
```
容器安全问题是每个使用容器的技术人员都应该考虑的事情,Docker通过对Linux各种命名空间的巧妙运用,实现了软件运行环境的沙箱,保证同一个主机上不同进程之间的相互隔离。
但由于User Namespace的实现与libnetwork存在冲突,从而导致User Namespace的支持一直被搁置。所以很多使用容器的同学一直都还在担心容器的安全问题。
但毫无疑问,User Namespace能大大提高Docker的安全性。在User Namespace支持之前,所有容器里的root用户其实与宿主机上的root用户是一样的,一旦容器沙箱被攻破(越狱),恶意用户就获取了宿主机的root权限,这样确实是很不安全。
通过User Namespace,可以把容器中的root用户映射到宿主机上的一个普通用户,这样即使发生越狱事件,攻击者获取的也只是宿主机上的一个普通用户的权限,大大增加了容器的安全性。现在是不是对容器更加有信心了?
User Namespace在经过7个月的讨论以及无数次修改与完善后,终于在1.9版发布之前,合并进了master(参考:https://github.com/docker/docker/pull/12648)。用户可以通过目前最新的实验版Docker体验User Namespace的相关功能。
稳定性持续改进
回顾2015,Docker团队与开源社区在Docker的稳定性提升方面做了大量工作。
最明显的表现是集成测试的覆盖面,在v1.4.0, 集成测试用例377个;到v1.9.1, 集成测试数量提升到1138个。
在每个PR提交以后,会自动通过github hook触发Jenkins来执行所有测试用例,从而尽可能保证整体功能的稳定性,Docker在生产环境中已经很稳定地运行1年多了。
代码结构逐步优化
Docker的一个竞争产品rkt(https://github.com/coreos/rkt)推出时,曾批评Docker的代码缺乏设计,最明显地表现是过多的嵌套调用(如:Docker 1.7之前的Job接口),不过目前来看,rkt还是败给了docker。
2015年,Docker在代码结构上的重大调整主要包括:
- Job接口的移除,减少了过多冗余的嵌套调用
- 网络相关的功能抽象到libnetwork项目独立维护
- 容器生命周期的核心库libcontainer由docker账号迁移到runc项目
- 支持Registry V2
- 本地镜像存储格式支持content addressability,镜像ID由随机生成改为按镜像内容计算(防止串改镜像内容)
- API与Daemon功能的隔离,以及API路由的重新设计
- 镜像Builder的重构
- Graph模块重构
- 移除LXC执行引擎,从而更加专注于native执行引擎的开发与维护
总结
在过去的一年里,Docker逐步从一个实验品,成长为一个羽翼丰满的可在生产环境中使用的容器引擎。
Docker团队在开源方面的大力投入以及活跃的开源社区,为Docker的成长提供了有力的保障。
以希云cSphere、Swarm、Docker Compose、Kubernetes、Mesos为代表的容器管理与调度平台也如雨后春笋般出现,为Docker在企业内部落地提供了有力的支持。
相信在不远的将来,容器技术将会在企业界得到广泛的普及。它在运维管理、软件发行等方面的变革也将对企业IT生产力产生巨大的提升。
如了解更多docker相关知识,请观看培训视频:https://csphere.cn/training!
如需要docker相关产品,请访问希云官网首页:https://csphere.cn!
cSphere1.0版本已发布,正式商用!欢迎咨询 400-686-1560