ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:41.28KB ,
资源ID:11922771      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/11922771.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(docker分析.docx)为本站会员(b****4)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

docker分析.docx

1、docker分析该文为Docker源码分析系列第二篇,在Docker架构篇的基础上,继续从源码的角度出发,分析用户如何创建Docker Client,以及如何通过Docker Client发送用户具体请求。可以说,发挥Docker最大魅力,从使用Docker做起,使用Docker,从精通Docker Client入手1. 前言如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖、便捷的软件集成测试与部署之道。在团队开发软件时,Docker可以提供可复用的运行环境、灵活的资源配置、便捷的集成测试方法以及一键式的部署方式。可以说,Docker的优势在简化持续集成、运

2、维部署方面体现得淋漓尽致,它完全让开发者从前者中解放出来,把精力真正地倾注在开发上。然而,把Docker的功能发挥到极致,并非一件易事。在深刻理解Docker架构的情况下,熟练掌握Docker Client的使用也非常有必要。前者可以参阅Docker源码分析系列之Docker架构篇,而本文主要针对后者,从源码的角度分析Docker Client,力求帮助开发者更深刻的理解Docker Client的具体实现,最终更好的掌握Docker Client的使用方法。即本文为Docker源码分析系列的第二篇Docker Client篇。2. Docker Client源码分析章节安排本文从源码的角度,

3、主要分析Docker Client的两个方面:创建与命令执行。前四章安排如下:第一章为前言,介绍Docker的作用以及研究Docker Client的必要性。第二章介绍部分章节安排。第三章从Docker Client的创建入手,进行源码分析,主要分为三小节。在3.1节中,分析如何通过docker命令,解析出命令行flag参数,以及docker命令中的请求参数。在3.2节中,分析如何处理具体的flag参数信息,并收集Docker Client所需的配置信息。在3.3节中,分析如何创建一个Docker Client。第四章在已有Docker Client的基础上,分析如何执行docker命令,分为

4、两小节。在4.1节中,分析如何解析docker命令中的请求参数,获取请求的类型。在4.2节中,分析Docker Client如何将执行具体的请求命令,最终将请求发送至Docker Server。3. Docker Client的创建Docker Client的创建,实质上是Docker用户通过可执行文件docker,与Docker Server建立联系的客户端。以下分三个小节分别阐述Docker Client的创建流程。以下为整个docker源代码运行的流程图:上图通过流程图的方式,使得读者更为清晰的了解Docker Client创建及执行请求的过程。其中涉及了诸多源代码中的特有名词,在下文中

5、会一一解释与分析。3.1. Docker命令的flag参数解析众所周知,在Docker的具体实现中,Docker Server与Docker Client均由可执行文件docker来完成创建并启动。那么,了解docker可执行文件通过何种方式区分两者,就显得尤为重要。对于两者,首先举例说明其中的区别。Docker Server的启动,命令为docker -d或docker daemon=true;而Docker Client的启动则体现为docker daemon=false ps、docker pull NAME等。可以把以上Docker请求中的参数分为两类:第一类为命令行参数,即docke

6、r程序运行时所需提供的参数,如: -D、daemon=true、daemon=false等;第二类为docker发送给Docker Server的实际请求参数,如:ps、pull NAME等。对于第一类,我们习惯将其称为flag参数,在go语言的标准库中,同时还提供了一个flag包,方便进行命令行参数的解析。交待以上背景之后,随即进入实现Docker Client创建的源码,位于./docker/docker/docker.go,在该go文件中,包含了整个Docker的main函数,也就是整个Docker(不论Docker Daemon还是Docker Client)的运行入口。部分main函

7、数代码如下: func main() if reexec.Init() return flag.Parse() / FIXME: validate daemon flags here 在以上代码中,首先判断reexec.Init()方法的返回值,若为真,则直接退出运行,否则的话继续执行。查看位于./docker/reexec/reexec.go中*reexec.Init()*的定义,可以发现由于在docker运行之前没有任何的Initializer注册,故该代码段执行的返回值为假。紧接着,main函数通过调用flag.Parse()解析命令行中的flag参数。查看源码可以发现Docker在*.

8、/docker/docker/flag.go*中定义了多个flag参数,并通过init函数进行初始化。代码如下:var ( flVersion = flag.Bool(stringv, -version, false, Print version information and quit) f lDaemon = flag.Bool(stringd, -daemon, false, Enable daemon mode) flDebug = flag.Bool(stringD, -debug, false, Enable debug mode) flSocketGroup = flag.Str

9、ing(stringG, -group, docker, Group to assign the unix socket specified by -H when running in daemon mode use (the empty string) to disable setting of a group) flEnableCors = flag.Bool(string#api-enable-cors, -api-enable-cors, false, Enable CORS headers in the remote API)flTls = flag.Bool(string-tls,

10、 false, Use TLS; implied by tls-verify flags) flTlsVerify = flag.Bool(string-tlsverify, false, Use TLS and verify the remote (daemon: verify client, client: verify daemon)/ these are initialized in init() below since their default values depend on dockerCertPath which isnt fully initialized until in

11、it() runs flCa *string flCert *string flKey *string flHosts string ) func init() flCa = flag.String(string-tlscacert, filepath.Join(dockerCertPath, defaultCaFile), Trust only remotes providing a certificate signed by the CA given here) flCert = flag.String(string-tlscert, filepath.Join(dockerCertPat

12、h, defaultCertFile), Path to TLS certificate file) flKey = flag.String(string-tlskey, filepath.Join(dockerCertPath, defaultKeyFile), Path to TLS key file) opts.HostListVar(&flHosts, stringH, -host, The socket(s) to bind to in daemon modenspecified using one or more tcp:/host:port, unix:/path/to/sock

13、et, fd:/* or fd:/socketfd.) 这里涉及到了Golang的一个特性,即init函数的执行。在Golang中init函数的特性如下:init函数用于程序执行前包的初始化工作,比如初始化变量等;每个包可以有多个init函数;包的每一个源文件也可以有多个init函数;同一个包内的init函数的执行顺序没有明确的定义;不同包的init函数按照包导入的依赖关系决定初始化的顺序;init函数不能被调用,而是在main函数调用前自动被调用。因此,在main函数执行之前,Docker已经定义了诸多flag参数,并对很多flag参数进行初始化。定义的命令行flag参数有:flVersio

14、n、flDaemon、flDebug、flSocketGroup、flEnableCors、flTls、flTlsVerify、flCa、flCert、flKey、flHosts等。以下具体分析flDaemon:定义:flDaemon = flag.Bool(string“d”, “-daemon”, false, “Enable daemon mode”)flDaemon的类型为Bool类型flDaemon名称为”d”或者”-daemon”,该名称会出现在docker命令中flDaemon的默认值为falseflDaemon的帮助信息为”Enable daemon mode”访问flDaem

15、on的值时,使用指针* flDaemon解引用访问在解析命令行flag参数时,以下的语言为合法的:-d, daemon-d=true, daemon=true-d=”true”, daemon=”true”-d=true, daemon=true当解析到第一个非定义的flag参数时,命令行flag参数解析工作结束。举例说明,当执行docker命令docker daemon=false version=false ps时,flag参数解析主要完成两个工作:完成命令行flag参数的解析,名为-daemon和-version的flag参数flDaemon和flVersion分别获得相应的值,均为fa

16、lse;遇到第一个非flag参数的参数ps时,将ps及其之后所有的参数存入flag.Args(),以便之后执行Docker Client具体的请求时使用。如需深入学习flag的解析,可以参见源码命令行参数flag的解析。3.2. 处理flag信息并收集Docker Client的配置信息有了以上flag参数解析的相关知识,分析Docker的main函数就变得简单易懂很多。通过总结,首先列出源代码中处理的flag信息以及收集Docker Client的配置信息,然后再一一对此分析:处理的flag参数有:flVersion、flDebug、flDaemon、flTlsVerify以及flTls;为

17、Docker Client收集的配置信息有:protoAddrParts(通过flHosts参数获得,作用为提供Docker Client与Server的通信协议以及通信地址)、tlsConfig(通过一系列flag参数获得,如flTls、flTlsVerify,作用为提供安全传输层协议的保障)。随即分析处理这些flag参数信息,以及配置信息。在flag.Parse()之后的代码如下: if *flVersion showVersion() return 不难理解的是,当经过解析flag参数后,若flVersion参数为真时,调用showVersion()显示版本信息,并从main函数退出;否

18、则的话,继续往下执行。if *flDebug os.Setenv(DEBUG, 1)若flDebug参数为真的话,通过os包的中Setenv函数创建一个名为DEBUG的系统环境变量,并将其值设为”1”。继续往下执行。 if len(flHosts) = 0 defaultHost := os.Getenv(DOCKER_HOST) if defaultHost = | *flDaemon / If we do not have a host, default to unix socket defaultHost = fmt.Sprintf(unix:/%s, api.DEFAULTUNIXSO

19、CKET) if _, err := api.ValidateHost(defaultHost); err != nil log.Fatal(err) flHosts = append(flHosts, defaultHost) 以上的源码主要分析内部变量flHosts。flHosts的作用是为Docker Client提供所要连接的host对象,也为Docker Server提供所要监听的对象。分析过程中,首先判断flHosts变量是否长度为0,若是的话,通过os包获取名为DOCKER_HOST环境变量的值,将其赋值于defaultHost。若defaultHost为空或者flDaemon为

20、真的话,说明目前还没有一个定义的host对象,则将其默认设置为unix socket,值为api.DEFAULTUNIXSOCKET,该常量位于*./docker/api/common.go*,值为”/var/run/docker.sock”,故defaultHost为”unix:/var/run/docker.sock”。验证该defaultHost的合法性之后,将defaultHost的值追加至flHost的末尾。继续往下执行。if *flDaemon mainDaemon() return若flDaemon参数为真的话,则执行mainDaemon函数,实现Docker Daemon的启动

21、,若mainDaemon函数执行完毕,则退出main函数,一般mainDaemon函数不会主动终结。由于本章节介绍Docker Client的启动,故假设flDaemon参数为假,不执行以上代码块。继续往下执行。 if len(flHosts) 1 log.Fatal(Please specify only one -H) protoAddrParts := strings.SplitN(flHosts0, :/, 2)以上,若flHosts的长度大于1的话,则抛出错误日志。接着将flHosts这个string数组中的第一个元素,进行分割,通过”:/”来分割,分割出的两个部分放入变量proto

22、AddrParts数组中。protoAddrParts的作用为解析出与Docker Server建立通信的协议与地址,为Docker Client创建过程中不可或缺的配置信息之一。var ( cli *client.DockerCli tlsConfig tls.Config)tlsConfig.InsecureSkipVerify = true由于之前已经假设过flDaemon为假,则可以认定main函数的运行是为了Docker Client的创建与执行。在这里创建两个变量:一个为类型是client.DockerCli指针的对象cli,另一个为类型是tls.Config的对象tlsConfi

23、g。并将tlsConfig的InsecureSkipVerify属性设置为真。TlsConfig对象的创建是为了保障cli在传输数据的时候,遵循安全传输层协议(TLS)。安全传输层协议(TLS) 用于两个通信应用程序之间保密性与数据完整性,该协议有两层组成:TLS记录协议和TLS握手协议。tlsConfig是Docker Client创建过程中可选的配置信息。 / If we should verify the server, we need to load a trusted ca if *flTlsVerify *flTls = true certPool := x509.NewCertP

24、ool() file, err := ioutil.ReadFile(*flCa) if err != nil log.Fatalf(Couldnt read ca cert %s: %s, *flCa, err) certPool.AppendCertsFromPEM(file) tlsConfig.RootCAs = certPool tlsConfig.InsecureSkipVerify = false 若flTlsVerify这个flag参数为真的话,则说明需要验证server端的安全性,tlsConfig对象需要加载一个受信的ca文件。该ca文件的路径为*flCA参数的值,最终完成

25、tlsConfig对象中RootCAs属性的赋值,并将InsecureSkipVerify属性置为假。/ If tls is enabled, try to load and send client certificates ifflTls | *flTlsVerify _, errCert := os.Stat(flCert) _, errKey := os.Stat(flKey) if errCertnil & errKeynil *flTls = true cert, err := tls.LoadX509KeyPair(flCert, *flKey) if err != nil log

26、.Fatalf(Couldnt load X509 key pair: %s. Key encrypted?, err) tlsConfig.Certificates = tls.Certificatecert 如果flTls和flTlsVerify两个flag参数中有一个为真,则说明需要加载以及发送client端的证书。最终将证书内容交给tlsConfig的Certificates属性。至此,flag参数已经全部处理,并已经收集完毕Docker Client所需的配置信息。之后的内容为Docker Client如何实现创建并执行。3.3. Docker Client的启动Docker Cli

27、ent的创建其实就是在已有配置参数信息的情况,通过Client包中的NewDockerCli方法创建一个实例cli,源码实现如下: if *flTls | *flTlsVerify cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts0, protoAddrParts1, &tlsConfig) else cli = client.NewDockerCli(os.Stdin, os.Stdout, os.Stderr, protoAddrParts0, protoAddrParts1, nil) 如果f

28、lag参数flTls为真或者flTlsVerify为真的话,则说明需要使用TLS协议来保障传输的安全性,故创建Docker Client的时候,将TlsConfig参数传入;否则的话,同样创建Docker Client,只不过TlsConfig为nil。关于Client包中的NewDockerCli函数的实现,可以具体参见*./docker/api/client/cli.go*(func NewDockerCli(in io.ReadCloser, out, err io.Writer, proto, addr string, tlsConfig *tls.Config) *DockerCli

29、 var ( isTerminal = false terminalFd uintptr scheme = http ) if tlsConfig != nil scheme = https if in != nil if file, ok := out.(*os.File); ok terminalFd = file.Fd() isTerminal = term.IsTerminal(terminalFd) if err = nil err = out return &DockerCli proto: proto, addr: addr, in: in, out: out, err: err

30、, isTerminal: isTerminal, terminalFd: terminalFd, tlsConfig: tlsConfig, scheme: scheme, 总体而言,创建DockerCli对象较为简单,较为重要的DockerCli的属性有proto:传输协议;addr:host的目标地址,tlsConfig:安全传输层协议的配置。若tlsConfig为不为空,则说明需要使用安全传输层协议,DockerCli对象的scheme设置为“https”,另外还有关于输入,输出以及错误显示的配置,最终返回该对象。通过调用NewDockerCli函数,程序最终完成了创建Docker Client,并返回main函数继续执行。4. Docker命令执行main函数执行到目前为止,有以下内容需要为Docker命令的执行服务:创建完毕的Docker Client,docker命令中的请求参数(经flag解析后存放于flag.Arg())。也就是说,需要使用Docker Client来分析docker 命令中的请求参数,并最终发送相应请求给Docker Server。4.1. Docker Client解析请求命令Dock

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1