docker 源码分析 二(基于1.8.2版本),docker client与daemon交互
(2) 那我们通过docker客户端发送一个命令,docker是怎样接收到并处理的呢,我们就举个例子来看一下,比如docker pull 命令;
我们回到 docker/docker.go 中,在上一章中我们讲了docker daemon的启动,代码讲到了handleGlobalDaemonFlag()的位置。我们接着继续看:
c := cli.New(clientCli, daemonCli)
if err := c.Run(flag.Args()...); err != nil {
if sterr, ok := err.(cli.StatusError); ok {
if sterr.Status != "" {
fmt.Fprintln(os.Stderr, sterr.Status)
os.Exit(1)
}
os.Exit(sterr.StatusCode)
}
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
cli 在cli/cli.go文件中,
func New(handlers ...Handler) *Cli {
// make the generic Cli object the first cli handler
// in order to handle `docker help` appropriately
cli := new(Cli)
cli.handlers = append([]Handler{cli}, handlers...)
return cli
}
这里的handler就是各种处理方法的结合;
然后是c.Run()方法,Run方法是调用了command方法,实质就是通过反射机制在handlers中找到args中名称相同的命令来执行:
func (cli *Cli) command(args ...string) (func(...string) error, error) {
for _, c := range cli.handlers {
if c == nil {
continue
}
camelArgs := make([]string, len(args))
for i, s := range args {
if len(s) == 0 {
return nil, errors.New("empty command")
}
camelArgs[i] = strings.ToUpper(s[:1]) + strings.ToLower(s[1:])
}
methodName := "Cmd" + strings.Join(camelArgs, "")
method := reflect.ValueOf(c).MethodByName(methodName)
if method.IsValid() {
// type assert
if c, ok := c.(Initializer); ok {
if err := c.Initialize(); err != nil {
return nil, initErr{err}
}
}
return method.Interface().(func(...string) error), nil
}
}
return nil, errors.New("command not found")
}
比如我们运行docker pull,实际去查找的命令就是CmdPull。
pull命令的实现是在 api/client 下面,这个目录下还有其他命令,我们只举pull的例子来看:
pull.go中最主要的一句话是
_, _, err = cli.clientRequestAttemptLogin("POST", "/images/create?"+v.Encode(), nil, cli.out, repoInfo.Index, "pull")
clientRequestAttemptLogin在同目录的utils.go目录下;
POST 是方法, /images.create? 这个是url,回想起上一章我们在apiserver(api/server/server.go)中看到的, 这url对应的是 s.postImagesCreate
postImagesCreate的定义在api/server/image.go 中;
现在大致了解了docker的c/s架构和docker客户端怎样给docker daemon发命令;下一篇来分析一下docker daemon的启动过程,也就是daemon.NewDaemon(cli.Config, registryService)函数的实现过程;
因为docker daemon的启动过程涉及很多操作,包括网络环境初始化,存储初始化等等,先了解一下daemon的总体启动过程,然后再分每一项各个击破;
docker 源码分析 二(基于1.8.2版本),docker client与daemon交互的更多相关文章
- Docker源码分析(二):Docker Client创建与命令执行
1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...
- Docker源码分析(八):Docker Container网络(下)
1.Docker Client配置容器网络模式 Docker目前支持4种网络模式,分别是bridge.host.container.none,Docker开发者可以根据自己的需求来确定最适合自己应用场 ...
- Docker源码分析(五):Docker Server的创建
1.Docker Server简介 Docker架构中,Docker Server是Docker Daemon的重要组成部分.Docker Server最主要的功能是:接受用户通过Docker Cli ...
- Docker源码分析(六):Docker Daemon网络
1. 前言 Docker作为一个开源的轻量级虚拟化容器引擎技术,已然给云计算领域带来了新的发展模式.Docker借助容器技术彻底释放了轻量级虚拟化技术的威力,让容器的伸缩.应用的运行都变得前所未有的方 ...
- Docker源码分析(三):Docker Daemon启动
1 前言 Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍然主要基于Linux平 ...
- docker 源码分析 一(基于1.8.2版本),docker daemon启动过程;
最近在研究golang,也学习一下比较火的开源项目docker的源代码,国内比较出名的docker源码分析是孙宏亮大牛写的一系列文章,但是基于的docker版本有点老:索性自己就git 了一下最新的代 ...
- docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储
前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...
- Docker源码分析(九):Docker镜像
1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...
- Docker源码分析(一):Docker架构
1 背景 1.1 Docker简介 Docker是Docker公司开源的一个基于轻量级虚拟化技术的容器引擎项目,整个项目基于Go语言开发,并遵从Apache 2.0协议.目前,Docker可以在容器内 ...
随机推荐
- Java虚拟机学习(2):垃圾收集算法
跟踪收集器 跟踪收集器采用的为集中式的管理方式,全局记录对象之间的引用状态,执行时从一些列GC Roots的对象做为起点,从这些节点向下开始进行搜索所有的引用链,当一个对象到GC Roots 没有 ...
- JavaScript高级程序设计 读书笔记 第一章
JavaScript是一种专门为与网页交互而设计的脚本语言 JavaScript实现 ECMAscript---核心 DOM---文档对象模型 BOM---浏览器对象模型
- 【转】 #1451 - Cannot delete or update a parent row: a foreign key constraint fails 问题的解决办法
转载地址:http://blog.csdn.net/donglynn/article/details/17056099 错误 SQL 查询: DELETE FROM `zmax_lang` WHERE ...
- PetaPoco入门(二)
1. Petapoco基本用法 1.1. 创建示例工程 首先创建一个工程文件,为了便于展示数据这里创建一个类型为:WindowsApplication的工程文件.命名为:PetapocoTest. 程 ...
- testng依赖,顺序,跳过
依赖测试@test(dependsOnMethods = {"open"})@testpublic static void open{ System.out.println( ...
- 设置MySQL自动增长从某个指定的数开始
自增字段,一定要设置为primary key. 以指定从1000开始为例.1 创建表的时候就设置: CREATE TABLE `Test` ( `ID` int(11) NOT NULL AUTO_I ...
- Windows Internals学习笔记(八)IO系统
参考资料: 1. <Windows Internals> 知识点: ● 当一个进
- Rails,uva 514
题目:铁轨 题目链接:UVa514链接 题目描述: 某城市有一个火车站,有n节车厢从A方向驶入车站,按进站的顺序编号为1-n.你的任务是判断是否能让它们按照某种特定的顺序进入B方向的铁轨并驶入车站.例 ...
- DuiLib 自定义识别控件
遇到一个断点无法识别自定义的控件,运气比较好,一搜就搜出来了: 参考地址:http://www.bkjia.com/ASPjc/992050.html 主要是这个函数: CControlUI* CDi ...
- ThreadLocal的分享
最开始的时候打算自己写点什么,但是看了这些博客以后感觉真的不知道应该写点什么了,全部都是好文章,只做分享了,链接如下: 1.http://www.cnblogs.com/dolphin0520/p/3 ...