美国西部时间2月23号,Docker举办了名为“containerd summit”的技术交流会议。邀请容器生态伙伴和containerd developer一起深度讨论containerd的设计、后续规划以及和其他系统的集成。阿里云作为Docker的战略合作伙伴和containerd项目的初始成员,也受邀参加了此次会议。除阿里云外, AWS、Google、IBM等公司也都有参加。
背景
随着容器技术的快速发展,生态逐渐地从围绕单机环境构建和运行容器化应用,发展为支持大规模容器编排技术。云平台成为了分布式网络操作系统,而容器成为了“进程”执行单元。容器可以动态地运行在不同宿主机环境之中。其中Kubernetes, Mesos, Docker诸强争霸,各胜擅长。2016年6月,Docker开始宣布在Docker Engine中内置Swarm mode,极大简化了容器编排的复杂性。但这也遭到了社区的强烈反弹。Google发起CRI(Container Runtime Interface 容器运行时接口)项目,通过shim的抽象层使得调度框架支持不同的容器引擎实现。Mesos推出了Unified Containerizer支持Docker 、Appc、OCI等不同的镜像格式,而无需Docker Engine。
面对这些挑战,2016年12月14日,Docker公司宣布将Docker Engine的核心组件Containerd捐赠到一个新的开源社区独立发展和运营,目标是提供一个标准化的容器runtime,注重简单、 健壮性、可移植性。由于Containerd只包含容器管理最基本的能力,上层框架可以有更大的灵活性来提供容器的调度和编排能力。阿里云,AWS, Google,IBM和Microsoft会作为Containerd的初始成员,会为项目贡献力量。
containerd分享
首先是Docker公司的同学介绍了containerd的设计理念,新特性以及Roadmap。
整个分享内容干货十足,涵盖了containerd所有的模块。细节不再一一赘述,简单的总结下比较有趣的几个点
更灵活的镜像分发机制
当你用docker run image启动容器的时候,Docker会先检查镜像有没有在本地,如果没有,就从Registry里先把镜像拉下来。拉镜像的操作内置在Docker Daemon里,对于大多数用户来说,可以方便的使用Docker命令就可以把镜像从远程Docker Registry里下载好。但是这种方式很不灵活,镜像下载逻辑内置在Docker Daemon里,镜像只能存储在Docker Registry里,下载过程严格遵循Registry定义的API,下载过程使用HTTP/HTTPS。你可能希望以某些自定义的方式存储镜像,比如把镜像的层加密之后再存储,以免数据泄露造成安全风险,又或者希望使用诸如FTP、NFS的方式传输镜像,而不是HTTP,在Docker都不支持。
containerd解耦了镜像分发和使用。它能兼容Docker的镜像分发机制,但是并不限制你使用其他方式。在containerd里,你可以用自己的方式传输镜像,只要在最后把数据推给containerd就可以了。以前面的场景为例,你在NFS上保存加密之后的镜像,当你想用这些镜像启动容器的时候,只需要先把NFS挂载到本地,然后执行
cat /path/to/nfs/layer-path | decrypt you-secret-key | dist ingress
这是一个很简单的命令,先把layer发给decrypt解密,最后提交给containerd。dist是containerd提供的镜像管理工具。当然,上面的命令实际上只处理了镜像的一个层,用同样的方式继续处理镜像的其他层。
Snapshot
Docker的Graph Driver负责把多个镜像层构造成一个完整的容器文件系统。在containerd里,用Snapshot替代了原来的Graph Driver。Snapshot设计上比Graph Driver更清晰简单,适配新的文件系统也更容易。目前已经支持overlay、btrfs,aufs不再支持。
更灵活的容器网络
使用Docker启动容器时,你可以选择各种网络模式:none、host、bridge、overlay,也可以是通过Docker网络插件自定义的网络。在容器网络方面,现在有两套模型:Docker的CNM(Container Network Model)和K8s的CNI(Container Network Interface)。
containerd不明确定义网络模型,不限制你用CNM还是CNI还是其他的方式。在创建和启动容器之间,你可以设置容器的namespace,利用oci hooks对namespace初始化。不需要写插件,一个简单Shell脚本就够了。
这些特性和containerd的定位有关:它面对的是上层的编排系统,而非直接用户,所以更注重灵活性。对于普通用户来说,使用Docker足以满足需求,更方便易用。
K8S和containerd集成
Google的Tim Hockin分享了k8s CRI(Container Runtime Interface)设计。涵盖了CRI架构、接口设计、第三方集成等方面。其中提到了CRI目前遇到的挑战。
从功能上,只有Docker能完整支持k8s所有的功能,但是CRI+Docker的实现上有一些问题,一方面是层次太深了,整个请求栈从kubelet -> CRI shim -> docker daemon -> containerd -> runc,另一方面Docker里有很多功能k8s根本用不到,比如Volume,Networking等,这些功能在k8s里已经有了。所以containerd刚好解决了这些问题,完全满足k8s需求。
然后IBM的Phil Estes分享了gRPC的一些内容。
下午则是针对conatinerd的一些设计和要添加的新功能进行讨论。这场讨论给我的印象非常深刻,在场的很多都是业界知名的大牛,年纪很大的老前辈,但是都在认真的讨论containerd里每个功能应该怎么实现,怎么设计接口才合理。这种对技术认真的追求和踏踏实实做技术的态度值得每一个程序员学习。
总结
从这次会议能充分的感受到containerd作为未来开放的容器runtime标准,得到了广泛的关注和支持。一方面containerd可以提供更加稳定和开放的容器runtime,另一方面允许上层编排系统灵活控制底层容器资源,满足了不同容器技术供应商的诉求。容器生态再添一并利器,无论对容器开发者还是最终用户,都是一件好事。
Containerd计划17年2Q发布,Google已经计划跟进并对K8S集成进行POC,计划17年4Q替换K8S底层相应实现。一个更轻量另外的容器管理引擎,能够帮助编排系统更灵活的与底层的容器交互。
最后,猜猜这是谁?