您的位置:网站首页 > 源码环境 > 正文

源码环境Docker源码分析五:Docker Server的创建

类别:源码环境 日期:2014-12-12 18:03:19 人气: 来源:
青海卫视青年汇,z360拆机,阿霞第二部全集,重生之一路荆棘,皇瓜结局,王哲林个人资料,邪王的宠婢,坦克轰小人,逆境无赖3,飞向别人的床mp3,沸点网络电视官网,qq天堂岛图标,公开的反义词是什么,用情组词,安阳义工网,混沌祖神,聚沙成塔造句,批评的反义词是什么,费玉清模仿陈小云,利齿青鱼,九狐网,宫燕,机巧魔神第二季,历史上的马馥雅,水煮鹿顶鸡第三季,八阿哥的传奇一生,李红勃,总裁的临时娇妻,sao73.com,穿回古代做王妃,异界炮狂,樱花草钢琴简谱,伊丽莎白瓜的热量,黄一飞谈周星驰,heatseek,金毛狻,济宁郑媛媛ed2k,汪涵北大演讲,doublelift是哪,msn怎么加人,叶坦扮演者,小姐威克网,科舟求健,异体我的绯色天空,王志才母亲,ca1386,鬼在你后面,爱的阶梯之永远,胡惊涛的儿子

  【编者按】在《深入浅出Docker》系列文章的基础上,InfoQ推出了《Docker源码分析》系列文章。《深入浅出Docker》系列文章更多的是从使用角度出发,帮助读者了解Docker的来龙去脉,而《Docker源码分析》系列文章通过分析解读Docker源码,来让读者了解Docker的内部实现,以更好的使用Docker。总之,我们的目标是促进Docker在国内的发展以及。另外,欢迎加入InfoQ Docker技术交流群,QQ群号:272489193。

  Docker架构中,Docker Server是Docker Daemon的重要组成部分。Docker Server最主要的功能是:接受用户通过Docker Client发送的请求,并按应的由规则实现由分发。

  同时,Docker Server具备十分优秀的用户友好性,多种通信协议的支持大大降低Docker用户使用Docker的门槛。除此之外,Docker Server设计实现了详尽清晰的API接口,以供Docker用户选择使用。通信安全方面,Docker Server可以提供安全传输层协议(TLS),数据的加密传输。并发处理方面,Docker Daemon大量使用了Golang中的goroutine,大大提高了服务端的并发处理能力。

  本文为《Docker源码分析》系列的第五篇Docker Server的创建。

  《Docker源码分析(三):Docker Daemon启动》主要分析了Docker Daemon的启动,而在mainDaemon()运行的最后环节,实现了创建并运行名为”serveapi”的job。这一环节的作用是:让Docker Daemon提供API访问服务。实质上,这正是实现了Docker架构中Docker Server的创建与运行。

  从流程的角度来说,Docker Server的创建并运行,代表了”serveapi”这个job的整个生命周期:创建Job实例job,配置job变量,以及最终执行该job。本章分三节具体分析这三个不同的阶段。

  Job是Docker架构中Engine内部最基本的任务执行单位,故创建Docker Server这一任务的执行也不例外,需要表示为一个可执行的Job。换言之,需要创建Docker Server,则必须创建一个相应的Job。具体的Job创建形式位于,如下:

  创建完Job实例job之后,Docker Daemon为job配置参数。在Job实现过程中,为Job配置参数有两种方式:第一,创建Job实例时,用指定参数直接初始化Job的Args属性;第二,创建完Job后,给Job添加指定的变量。以下代码则实现了为创建的job配置变量:

  本章将深入分析Docker Server提供API服务的部分,从源码的角度剖析Docker Server的架构设计与实现。

  作为一个请求、处理请求的服务端,Docker Server首先明确自身需要为多少种通信协议提供服务,在Docker这个C/S模式的架构中,可以使用的协议无外乎三种:TCP协议,Unix Socket形式,以及fd的形式。随后,Docker Server根据协议的不同,分别创建不同的服务端实例。最后,在不同的服务端实例中,创建相应的由模块,模块,以及处理请求的Handler,形成一个完备的server。

  ”serveapi”这个job在运行时,将执行api.ServeApi函数。ServeApi的功能是:循环检查所有Docker Daemon当前支持的通信协议,并对于每一种协议都创建一个goroutine,在这个goroutine内部配置一个服务于HTTP请求的server端。ServeApi的代码实现位于:

  第一,判断job.Args的长度是否为0,由于通过flHosts来初始化job.Args,故job.Args的长度若为0的话,说明没有Docker Server没有的协议与地址,参数有误,返回错误信息。代码如下:

  ListenAndServe的功能是:使Docker Server某一指定地址,接受该地址上的请求,并对以上请求由转发至相应的处理函数Handler处。从实现的角度来看,ListenAndServe主要实现了设置一个服务于HTTP的server,该server将指定地址上的请求,并对请求做特定的协议检查,最终完成请求的由与分发。代码实现位于。

  ListenAndServe的实现可以分为以下4个部分:

  (1) 创建router由实例;

  (2) 创建listener实例;

  (3) 创建http.Server;

  (4) 启动API服务。

  ListenAndServe的执行流程如下图:

  图5.1 ListenAndServer执行流程图

  下文将按照ListenAndServe执行流程图一一深入分析各个部分。

  createRouter的实现位于。

  创建router由实例是一个重要的环节,由实例的作用是:负责Docker Server对请求进行由以及分发。实现过程中,主要两个步骤:第一,创建全新的router由实例;第二,为router实例添加由记录。

  可见,以上代码返回的类型为mux.Router。mux.Router会通过一系列已经注册过的由记录,来为接受的请求做匹配,首先通过请求的URL或者其他条件,找到相应的由记录,并调用这条由记录中的执行Handler。mux.Router有以下这些特性:

  Router由实例r创建完毕,下一步工作是为Router实例r添加所需要的由记录。由记录存储着用来匹配请求的信息,包括对请求的匹配规则,以及匹配之后的Handler执行入口。

  回到createRouter实现代码中,首先判断Docker Daemon的启动过程中有没有DEBUG模式。通过docker可执行文件启动Docker Daemon,解析flag参数时,若flDebug的值为lse,则说明不需要配置DEBUG;若flDebug的值为true,则说明需要为Docker Daemon添加DEBUG功能。具体的代码实现如下:

  分析以上源码,可以发现Docker Server使用两个包来完成DEBUG相关的工作:expvar和pprof。包expvar为公有变量提供标准化的接口,使得这些公有变量可以通过HTTP的形式在”/debug/vars”这个URL下被访问,传输时格式为JSON。包pprof将Docker Server运行时的分析数据通过”/debug/pprof/”这个URL向外。这些运行时信息包括以下内容:可得的信息列表、正在运行的命令行信息、CPU信息、程序函数引用信息、ServeHTTP这个函数三部分信息使用情况(堆使用、goroutine使用和thread使用)。

  回到createRouter函数实现中,完成DEBUG功能的所有工作之后,Docker Docker创建了一个map类型的对象m,用于初始化由实例r的由记录。简化的m对象,代码如下:

  以上代码,在第一层循环中,按HTTP请求方法划分,获得请求方法各自的由记录,第二层循环,按匹配请求的URL进行划分,获得与URL相对应的执行Handler。在嵌套循环中,通过makeHttpHandler返回一个执行的函数f。在返回的这个函数中,涉及了logging信息,CORS信息(跨域资源共享协议),以及版本信息。以下举例说明makeHttpHandler的实现,从对象m可以看到,对于”GET”请求,请求URL为”/info”,则请求Handler为”getInfo”。执行makeHttpHandler的具体代码实现如下:

  以上makeHttpHandler的执行已经完毕,返回func函数,作为指定URL对应的执行Handler。

  创建完处理函数Handler,需要向由实例中添加新的由记录。如果URL信息为空,则直接为该HTTP请求方法类型添加由记录;若URL不为空,则为请求URL径添加新的由记录。需要额外注意的是,在URL不为空,为由实例r添加由记录时,考虑了API版本的问题,通过thods(localMethod).HandlerFunc(f)来实现。

  至此,mux.Router实例r的两部分工作工作已经全部完成:创建空的由实例r,为r添加相应的由记录,最后返回由实例r。

  现I时er由记录。需要额外的利次循环中,都有不同的组合1083lla/mux/mux.go,

  由模块,完成了请求的由与分发这一重要部分,属于ListenAndServe实现中的第一个重要工作。对于请求的功能,同样需要模块来完成。而在ListenAndServe实现中,第二个重要的工作就是创建Listener。Listener是一种面向流协议的通用网络模块。

  在创建Listener之前,先判断Docker Server允许的协议,若协议为fd形式,则直接通过ServeFd来服务请求;若协议不为fd形式,则继续往下执行。

  在程序执行过程中,需要判断”serveapi”这个job的中”BufferRequests”的值,是否,若,则通过包listenbuffer创建一个Listener的实例l,否则的话直接通过包net创建Listener实例l。具体的代码位于,如下:

  由于在mainDaemon()中创建”serveapi”这个job之后,给job添加变量时,已经给”BufferRequets”赋值为true,故使用包listenbuffer创建listener实例。

  Listenbuffer的作用是:让Docker Server可以立即指定协议地址上的请求,但是将这些请求暂时先缓存下来,等Docker Daemon全部启动完毕之后,才让Docker Server开始接受这些请求。这样设计有一个很大的好处,那就是可以在Docker Daemon还没有完全启动完毕之前,接收并缓存尽可能多的用户请求。

  若协议的类型为TCP,另外job中变量Tls或者TlsVerify有一个,则说明Docker Server需要支持HTTPS服务,需要为Docker Server配置安全传输层协议(TLS)的支持。为实现TLS协议,首先需要建立一个tls.Config类型实例tlsConfig,然后在tlsConfig中加载证书,认证信息等,最终通过包tls中的NewListener函数,创建出适应于接收HTTPS协议请求的Listener实例l,代码如下:

  创建http.Server实例之后,Docker Server立即启动API服务,使Docker Server开始在Listener实例l上接受请求,并对于每一个请求都生成一个新的goroutine来做专属服务。对于每一个请求,goroutine会读取请求,查询由表中的由记录项,找到匹配的由记录,最终调用由记录中的执行Handler,执行完毕后,goroutine对请求返回响应信息。代码如下:

  Docker Server作为Docker Daemon架构中请求的入口,接管了所有Docker Daemon对外的通信。通信API的规范性,通信过程的安全性,服务请求的并发能力,往往都是Docker用户最为关心的内容。本文基于源码,分析了Docker Server大部分的细节实现。希望Docker用户可以初探Docker Server的设计,并且可以更好的利用Docker Server创造更大的价值。

  孙宏亮,初创团队,软件工程师,浙江大学VLIS实验室应届研究生。读研期间活跃在PaaS和Docker开源社区,对Cloud Foundry有深入研究和丰富实践,擅长底层平台代码分析,对分布式平台的架构有一定经验,撰写了大量有深度的技术博客。2014年末以合伙人身份加入DaoCloud团队,致力于以Docker为主的容器的技术,推动互联网应用的容器化步伐。邮箱:

关键词:源码环境
0
0
0
0
0
0
0
0
下一篇:没有资料

网友评论 ()条 查看

姓名: 验证码: 看不清楚,换一个

推荐文章更多

热门图文更多

最新文章更多

关于联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助

CopyRight 2002-2012 技术支持 源码吧 FXT All Rights Reserved

赞助合作: