Skip to content

Instantly share code, notes, and snippets.

@mountkin
Last active January 7, 2016 08:58
Show Gist options
  • Save mountkin/3d44f651280f605ea100 to your computer and use it in GitHub Desktop.
Save mountkin/3d44f651280f605ea100 to your computer and use it in GitHub Desktop.

Docker 2015年度回顾

Docker从2013年开源,到目前已经经历了三年的不断完善与优化。2015年是Docker开源项目突飞猛进的一年, 在这一年时间里,Docker先后发布了1.5, 1.6, 1.7, 1.8, 1.9 5个大版以及7个修订版。

功能上增加了只读容器、ulimit支持、日志驱动、Volume插件、网络插件、IPAM插件等新特性,更加适合企业多样化的应用场景; user namespace的支持也合并进了1.9实验版,这使得Docker的安全性得到大大提升。

Docker registry 2(github上的distribution项目)的发布,让镜像更加标准化,镜像的传输更加高效; 新增了镜像签名验证机制,保证了镜像传输的安全。

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、内存等资源进行配额控制的能力。

日志驱动

v1.6 提供了可扩展的日志驱动接口,内置json-file和syslog两种日志驱动,用户可以根据需求把日志写入json文件或者发送到syslog。 基于日志驱动的go语言接口,在接下来的几个版中,逐步添加了fluentd, journald, awslog, gelf等日志驱动模块,满足用户各种复杂的日志记录与收集需求。

容器与镜像Label

在v1.4,用户可以为Docker Daemon指定一个或多个Label,方便Swarm之类的集群管理工具对主机进行分组管理。 Docker 1.6新增了容器与镜像Label的支持,方便用户根据Label来对容器和镜像进行分组管理与过滤。

Volume插件

v1.7实验版引入了Volume插件机制,用户可以根据需要开发自己的Volume插件来使用外部存储服务。 比如:通过AWS EBS Volume插件,可以在创建容器时,自动创建一块EBS,把容器的数据保存在EBS上。 如果需要,用户也可以自己根据Volume插件的RPC接口规范开发适合自己的Volume插件,通过企业内部的NAS、SAN等存储服务来保存容器数据。 Volume插件在v1.8进入正式版对外发布。

Overlay网络

跨主机互联一直是困扰Docker用户的一个问题。在Docker支持Overlay网络之前, 常用的跨主机通信方案是通过在每台主机上运行个ambassador容器作为代理。这种方式无疑造成了管理成本的增加。 Docker 1.9正式支持了基于VXLAN的Overlay网络,用户可以通过Overlay网络方便的实现容器跨主机通信。

网络插件

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的一个竞争产品rkt(https://github.com/coreos/rkt)推出时,曾批评Docker的代码缺乏设计。 比较明显的表现是过多的嵌套调用(如:Docker 1.7之前的Job接口)。

2015年,Docker在代码结构上的重大调整主要包括:

  • Job接口的移除,减少了过多冗余的嵌套调用
  • 网络相关的功能抽象到libnetwork项目独立维护
  • 容器生命周期的核心库libcontainer由docker账号迁移到runc项目
  • 支持Registry V2
  • 本地镜像存储格式支持content addressability,镜像ID由随机生成改为按镜像内容计算
  • API与Daemon功能的隔离,以及API路由的重新设计
  • 镜像Builder的重构
  • Graph模块重构
  • 移除LXC执行引擎,从而更加专注于native执行引擎的开发与维护

总结

在2015年,Docker逐步从一个实验品成长为一个羽翼丰满的可在生产环境使用的容器引擎。 Docker团队在开源方面的大力投入和活跃的开源社区,为Docker的成长提供了有力的保障。 以希云cSphere、Swarm、Docker Compose、Kubernetes、Mesos为代表的容器管理与调度平台也如雨后春笋般出现, 为Docker在企业内部落地提供了便利。相信在不远的将来,容器技术将会在企业内部得到大范围的普及, 容器技术带来的运维管理、软件发行方面的变革也将对企业IT生产力产生巨大的提升。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment