Docker 架构演进之路

简介: 前言Docker已经推出了5年,在这5年中它极大的改变了互联网产品的架构,推进了新的产品开发、测试和运维方法。但是它自身也在激烈变化中。特别是最近2年随着Docker开源项目的不断演化,Docker内部结构发生了翻天覆地的变化。

前言

Docker已经推出了5年,在这5年中它极大的改变了互联网产品的架构,推进了新的产品开发、测试和运维方法。但是它自身也在激烈变化中。特别是最近2年随着Docker开源项目的不断演化,Docker内部结构发生了翻天覆地的变化。作为一个容器平台的使用者,可以不用关注具体的Docker演进细则,但是必须明白Docker的衍化会对自己的PaaS平台带来什么样的影响(如果您对Docker技术细节不关注,你可以直接看第2章和最后两章)。本文材料来自于Docker社区,对Docker最近几年的变化趋势做出了总结。同时在结尾处给出了基于k8s PaaS平台在底层容器上选型建议。 

演进方向


img_0ad3f480a490790a284321f1df3efe8d.png
图2-1 Docker结构图

这里先把结论抛出来,Docker这几年的架构演进方向:

1、原有引擎功能下沉入containerd,containerd向着独立于Docker 作为通用容器运行时工具方向演进

2、swarm功能整合入引擎,swarmkit模块不断弱化,最终将被引擎吸收

3、引擎内部功能不断解藕出新模块,同时新功能不断加入Docker 引擎。

一言以蔽之:containerd核心化,引擎集群化。

背景

Docker公司在集群管理服务编排工具竞争上落败

Docker公司在2015年Docker 1.9推出了自己的集群管理服务编排工具swarm,刚开始swarm作为一个独立的工具,在Docker 引擎之外。但是从Docker 1.12开始Docker公司将swarm整合入了Docker引擎。至此Docker swarm作为一个完整的服务编排工具和谷歌主导、红帽支持的kubernetes社区直接冲突。于此同时Docker公司在2015开启了自己的商业化之路,开源社区为了避免Docker公司商业化过程中将Docker沦为绑架社区的工具,所以顺势推出了多个Docker替代方案例如rkt。kubernetes社区推出了CRI-O标准,只要是遵从此标准的容器运行时都可以被K8s支持。一时间Docker大有被主流社区抛弃之势!经过2年和K8s的竞争时间来到2017年,Docker swarm已经在事实上彻底落败,Kubernetes社区已经成为开源项目中热度最高的项目。为了应对如此多的不利因素,Docker公司在2017年将自己主导的containerd捐献给CNCF基金会(k8s是旗下的子项目);并且将更多的Docker引擎的功能下沉到Containerd中。借此避免自己在开源社区中被边缘化。

容器世界的标准化不断推进

Docker公司在2013念推出Docker后,极大的颠覆了这个行业,也推进了业务容器化过程。2015 Docker公司主导之下社区推出了容器的第一个行业标准OCI标准(开放容器协议)。彼时Docker公司推出了第一个OCI标准的容器运行时runc。runc作为第一个oci标准运行时(runtime),只是一个参考实现,仅仅承担容器与主机之间的交互。容器运行状态检查、监控,容器生命期管理,io管理、信号传递等一些列容器运行必不可少的功能却“无处安放”。所以Docker公司将Containerd定位为一个生产环境下的OCI 标准运行时。它承担了runc所缺少的大部分容器运行必要功能:生命期管理,io管理,信号管理。在2017年的时候OCI v1标准发布,Docker公司将Docker镜像格式捐献给了OCI协议。所以在2017年发布的Containerd1.0中存储管理这些原来由引擎承担的功能也进入了Containerd(网络管理功能,在https://containerd.io路线图中被列为roadmap,但是在2016年12月份Containerd的主要维护者投票中,网络功能不被列入containerd的功能范畴 而继续交给上层完成,在github containerd的readme中2017 1月12日正式将网络部分功能从containerd 维护范畴中删除)

Containerd

Containerd在Docker 1.11中才正式出现,刚开始时0.x版本;2017年才推出了1.x标准。如上文所说,Container d作为一个生产环境可用的Oci 实现,它利用了OCI 运行时和镜像格式.下图展现了Containerd对自己在社区中地位作出了诠释


img_1450202f51866f7cd98f800b4d3a2299.png
图2-1 Containerd在Paas社区上的定位

可以看到Containerd作为PaaS工具的通用容器运行时适配层,它利用已有的oci运行时(Containerd使用runc作为运行时,在windows上则是hcsshim),屏蔽底层操作系统的差异;为Paas提供通用的容器支撑。从这个图可以看到Containerd计划支持所有现有应用广泛的Paas平台工具。现在可以确认的是AWS ECS,k8s,Docker上使用containerd。Mesos和cloud foundry今天(2018年9月)尚未确定。

下图为Containerd 1.x的架构图


img_f9ea17c3f2ff9280384e6e6822338eb3.png
图2-2 Containerd1.x架构图

从此架构图可以清楚的看到Containerd对上提供grpc接口方式的api,而Metric api是度量功能使用的。所有的编排工具容器适配层都可以使用grpc api作为containerd的客户端,使用containerd操作容器。

Distribution用于容器镜像的pull和push动作(这部分出现在Containerd中完全是因为oci v1标准推出Docker公司将自己镜像格式贡献了出去,所以containerd理所当然需要对镜像进行管理了)。Bundle(在docker的语景里是容器运行的目录集)子系统用于容器存储管理它的作用就是原来的graphdriver,它提供将容器镜像拆解成容器运行时刻需要的Bundle。Runtime子系统用于容器执行和监控,就是它直接操作runtime,传递和接收信号(signal),中转fifo,记录日志。Content、Metadata和Snapshots是存储管理组建,Excutor和Supervisor是执行体组建。整个系统通过Event事件驱动。

根据github上containerd的介绍containerd项目工作内容集中在如下几个领域上:

1、执行:容器创建、运行、停止、暂停、恢复,exec,信号传递、和删除。

2、cow 文件系统支持:在overlay,aufs和其他cow文件系统上内置了存储功能

3、度量系统

4、发布:容器镜像的pull和push,镜像的管理和获取

下面内容不作为containerd项目的工作范畴:

1、网络:网络的创建和管理由高层来完成

2、build:镜像的构建

3、volumes:volume管理:mounts,bind等针对volume的功能应该有高层来完成

4、logging

此处需要说明一下网络曾经作为containerd社区争论的焦点。但是在16年年底的社区维护者投票中多数人支持网络不留在containerd中,因为按照大多数维护者的认识网络过于复杂,而且网络设置常常需要跨越节点。这部分功能由containerd的客户端(Docker Engine 或k8s)做更合适。

这里顺便介绍一下Containerd版本兼容规则:Containerd同一个大版本下的连续两个小版本是兼容的。例Containerd1.1.0和1.2.0却是兼容的,1.0.0和1.2.0却不保证兼容。

Docker的演进

下图介绍了containerd在1.11之前(不含)的Docker架构


img_28523137cb2cbf70bc71799b896d760e.png
图3-1Docker1.11(不含)之前的架构

可以看到在Docker1.11之前,没有containerd模块,由libcontainer直接操作主机os接口。

下图介绍了在Docker 1.11--Docker 17.10之间的docker架构


img_9edda1cc3aa0e2e74e624c163c26232f.png
图3-2 Docker 1.12-17.10之前(含)架构

从图3-2看到这一时期的Docker架构变化就是引入了Containerd和runc,由Containerd完成容器生命期管理。

下图列出了Docker 17.11(Docker 17.12为真正的stable版)开始的架构


img_f0c5a4a5df8a73536ef551fb063715dc.png
图3-3 docker 17.12以后架构


需要注意的一点图网络部分并不在containerd中,仍然在docker engine里。

Docker 17的具体架构演进

这里介绍的内容均来自于Moby社区的roadmap和Docker\docker-ce 的分析。

17.06---17.10的路线图描述此一时期,moby社区(引擎)的主要工作是:

1、插件功能的提升:方便插件的发布(通过registry以docker镜像方式发布),解决插件开发的共性问题(插件任何时候的需要active,在用户容器启动之前就start,以及插件写在困难)

2、引擎内部解藕:api已完成重构,builder实现在daemon中已完全独立。

3、提升引擎集群管理能力:当前跨节点网络(overlay网络)和节点发现已经整合到引擎里。但是引擎尚不能不依赖于swarmkit完成task调度

4、cli从engine中独立出来(这一点源自于github moby代码分析)。

17.11--18.03 的路线描述此一时期,moby社区(引擎)的主要工作:

1、引擎使用Containerd1.0

2、引擎内部解藕,计划整合buildkit工具

Docker架构演进大事记

1、Docker 1.9 推出swarm,作为独立工具,用于集群管理和服务编排

2、Docker 1.11 推出containerd和runc。

3、Docker 1.12 swarm进入引擎

4、Docker 17.06 引擎社区更名为moby,do c ke r社区版本更名为docker-ce(类似于红帽的fedora和rhel)

5、Docker 17.12 Docker正式引入containerd 1.0

6、Docker 18.06 正式在engine里加入了buildkit,在设置一个环境变量后可以使用buildkit完成docker build过程。

Docker 18.06.1正式将containerd 1.1引入docker。


k8s社区对Docker 17.03之后版本态度

在Docker 17.03后Docker因为moby和containerd等原因版本变动比较大,我们可以看到k8s r11发布后的2018年9月仍然没有将Docker 17.03以后(不含)版本作为k8s的兼容Docker版本。从社区的讨论来看社区已经推荐将containerd直接对接cri,完成k8s的集成。见https://github.com/kubernetes/kubernetes/issues/42926,其中cpuguy83(此人为moby社区的主要维护者)推荐直接使用containerd替代docker 17.03以后的版本对接k8s。本来docker在k8s社区中的兼容性测试由k8s sig-node 工作组完成,但是通过k8s讨论可以看到sig-node并没有计划做docker 17.03以后docker的兼容性测试。

最新消息是2018年9月27日k8s出r12 rc的时候,kubeadm里已经加入了对docker18.06的支持,且完成了ci测试。12 rc 文档里将docker17.12,18.03,18.06之后列入支持表。但在k8s中 sig-node工作组负责底层容器接口,docker在k8s版本的兼容性测试本应由此工作组完成,但是sig-node对于docker 17.03版本以后docker版本的态度依然冷淡,一直未列入明确的工作计划中。sig-node工作组两位主席是谷歌和红帽的,它们对于cri更感兴趣。在2018年5月,sig-node和containerd社区共同完成了cri-containerd合入containerd1.1的工作,并发布了containerd 整合到kubenetes的GA。完成此部分工作后,k8s驱动containerd的结构更简单明确。下图介绍了docker,containerd在k8s上的架构图:


img_846a5f3aa629b402465b1058e2c1a960.png
docker在k8s上的架构图




img_3a09ae69a557cd79be2b25082acf1825.png
containerd1.1在k8s上的架构图

从上面两幅图我们可以看到containerd1.1在k8s上拥有更简单的结构图,驱动更为简单。而且根据k8s社区的测试,直接使用containerd替代docker可以获得容器启动时间、内存消耗和cpu消耗减少的红利。上述结论来自于:

https://kubernetes.io/blog/2018/05/24/kubernetes-containerd-integration-goes-ga/

所以sig-node工作组对docker 高版本不感冒。目前多方力量博弈,未来k8s下层的runtime花落谁家还再观察。


img_c17bd51db99f79d54b7cfe01cbf01fe5.png
kubelet调用docker容器的方式

docker-manager是老的kubelet介入docker的方式。

cri从k8s 1.6开始正式进入k8s

cri直接介入containerd是从18年4月,containerd1.1开始


PaaS平台选型建议

如果你正在对基于k8s的PaaS平台进行生产环境选型,我建议你使用Docker17.03,因为它成熟稳定且k8s r9,r10和r11做过稳定、兼容性测试。如果你喜欢尝试新事物,我建议你跳过Docker17.03之后,直接在kublet上使用containerd1.1如果你喜欢docker新版本,那么你可以尝试docker18.06,因为Docker17.12是Docker变化最剧烈的一个版本稳定性不好说,且kuberadm中r12 rc里加入了对18.06的支持所以用最新的好了。而且更关键的一点docker 18.06.1使用containerd 1.1,它支持一个特性:上层容器控制平台的namespace隔离,简单点说就是docker和k8s均可以在同一个节点上操作同一个containerd,且相互隔离不可见。如此可以预留选择传统k8s+docker组合时刻,保留将来切换成k8s+containerd组合的可能性,进而为自己的框架保持演进的灵活性

相关实践学习
容器服务Serverless版ACK Serverless 快速入门:在线魔方应用部署和监控
通过本实验,您将了解到容器服务Serverless版ACK Serverless 的基本产品能力,即可以实现快速部署一个在线魔方应用,并借助阿里云容器服务成熟的产品生态,实现在线应用的企业级监控,提升应用稳定性。
云原生实践公开课
课程大纲 开篇:如何学习并实践云原生技术 基础篇: 5 步上手 Kubernetes 进阶篇:生产环境下的 K8s 实践 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
目录
相关文章
|
29天前
|
Kubernetes 开发者 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【2月更文挑战第29天】在当今快速发展的软件开发领域,微服务架构已成为提高系统可维护性、扩展性和敏捷性的关键解决方案。本文将深入探讨如何利用Docker容器化技术和Kubernetes集群管理工具,共同构建一个既高效又可靠的微服务环境。我们将分析Docker和Kubernetes的核心功能,并展示它们如何协同工作以简化部署流程、增强服务发现机制以及实现无缝的服务伸缩。通过实际案例分析,本文旨在为开发者提供一套实用的微服务架构设计和实施指南。
|
2月前
|
KVM 虚拟化 Android开发
DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例Docker+KVM的部署
DP读书:鲲鹏处理器 架构与编程(十二)鲲鹏软件实战案例Docker+KVM的部署
52 1
|
2月前
|
开发者 Docker 微服务
深入浅出:使用Docker容器化部署微服务架构
在当今快速迭代的软件开发环境中,微服务架构因其高度解耦和独立性而成为企业首选。然而,微服务的管理和部署可能会变得复杂和繁琐。本文将探讨如何利用Docker,一个轻量级的容器化技术,来简化和加速微服务的部署。我们将从Docker的基础概念入手,详细介绍如何创建、配置和运行微服务容器,最后讨论Docker在微服务架构中的优势和挑战。本文旨在为开发者提供一条清晰的路径,通过容器化技术实现微服务架构的高效部署和管理。
86 0
|
2月前
|
Kubernetes 开发者 Docker
深入浅出:使用Docker容器化部署微服务架构
在当今快速演进的软件开发领域,微服务架构因其高度的模块化和可伸缩性而受到广泛欢迎。然而,微服务的部署和管理也带来了新的挑战。本文旨在通过深入浅出的方式,探讨如何利用Docker容器技术有效地部署和管理微服务架构。我们将从Docker的基本概念出发,逐步深入到如何构建、部署微服务,并讨论在此过程中可能遇到的常见问题及其解决策略。本文不仅适合刚接触Docker和微服务的新手,也为有经验的开发者提供了实用的参考。
55 1
|
2月前
|
JSON JavaScript Docker
深入浅出:使用Docker容器化部署微服务架构
本文旨在向读者展示如何利用Docker技术高效地构建和部署微服务架构。通过深入浅出的方式,我们将探索Docker的基本概念、容器化的优势以及如何将其应用于微服务架构中。此外,文章还将提供一个简单的示例,指导读者实践如何使用Docker将一个现有的后端应用容器化,并部署到本地开发环境中。不同于传统的摘要,这里我们强调实践操作的重要性,鼓励读者通过实际操作来加深对Docker和微服务架构的理解。
52 1
|
2月前
|
Java 开发者 Docker
深入浅出:使用Docker容器化部署微服务架构
在本文中,我们将探索Docker容器技术如何革新微服务架构的部署方式,提高开发效率和应用的可扩展性。不同于传统摘要的概述风格,我们将通过一个实际案例,步骤明晰地展示如何将一个简单的微服务应用容器化,并在Docker环境中部署运行。本文旨在为开发者提供一个清晰、易懂的指南,帮助他们理解容器化技术的基本原理和操作流程,无论是初学者还是有经验的开发人员都能从中获益。
|
2月前
|
存储 Kubernetes Docker
深入浅出:使用Docker容器化部署微服务架构
在当今快速迭代的软件开发周期中,微服务架构凭借其高度的模块化和灵活性成为了众多企业的首选。然而,随之而来的是对环境一致性和服务部署效率的挑战。本文将探讨如何利用Docker这一轻量级容器技术,实现微服务的快速、一致和可靠部署。通过深入浅出的方式,我们将介绍Docker的基本概念、容器化微服务的优势以及步骤详解,旨在为读者提供一个清晰的实践指南,帮助他们在微服务架构的部署过程中提升效率和可靠性。
66 0
|
2月前
|
设计模式 运维 Docker
深入浅出:使用Docker容器化部署微服务架构
本文旨在为读者提供一个全面且易于理解的指南,介绍如何使用Docker技术来容器化部署微服务架构。随着云计算和微服务架构的普及,Docker作为一种轻量级的容器解决方案,已经成为开发和运维领域的热门技术。本文将从Docker的基本概念出发,详细讲解如何将传统的应用服务转化为容器化的微服务,包括Dockerfile的编写、镜像构建、容器部署以及服务编排等关键步骤。此外,文章还会探讨使用Docker部署微服务架构的最佳实践和常见问题,帮助读者有效地管理和优化其微服务系统。
71 1
|
2月前
|
Kubernetes API Docker
深入浅出:使用Docker容器化部署微服务架构
在本文中,我们将探索如何利用Docker容器技术实现微服务架构的高效部署与管理。不同于传统的摘要方式,我们将采用一个故事化的场景引入,设想在一个快速发展的互联网公司中,随着业务的扩张,传统的单体应用逐渐变得难以维护和扩展。开发团队决定采用微服务架构来解决这一问题,而Docker作为容器化技术的佼佼者,被选为部署和管理微服务的关键工具。文章将详细介绍Docker的基本概念、微服务架构的优势,以及如何结合两者进行高效的应用部署和管理。
25 0
|
2月前
|
存储 运维 Docker
深入浅出:使用Docker容器化部署微服务架构
在快速迭代和高效部署的今天,Docker作为一种轻量级的容器化技术,已经成为开发和运维领域的热门话题。本文将从容器化技术的基础出发,详细介绍如何使用Docker来容器化部署微服务架构。我们不仅会探讨Docker的基本概念、核心优势以及与传统虚拟化技术的区别,还将通过一个实际的微服务应用示例,指导读者如何构建、部署并管理Docker容器。此外,文章还将涉及Docker Compose工具的使用,以简化多容器应用的管理。无论你是开发人员还是运维工程师,本文都将为你提供一条清晰的学习路径,助你掌握使用Docker容器化部署微服务架构的关键技能。