(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交互的更多相关文章

  1. Docker源码分析(二):Docker Client创建与命令执行

    1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...

  2. Docker源码分析(八):Docker Container网络(下)

    1.Docker Client配置容器网络模式 Docker目前支持4种网络模式,分别是bridge.host.container.none,Docker开发者可以根据自己的需求来确定最适合自己应用场 ...

  3. Docker源码分析(五):Docker Server的创建

    1.Docker Server简介 Docker架构中,Docker Server是Docker Daemon的重要组成部分.Docker Server最主要的功能是:接受用户通过Docker Cli ...

  4. Docker源码分析(六):Docker Daemon网络

    1. 前言 Docker作为一个开源的轻量级虚拟化容器引擎技术,已然给云计算领域带来了新的发展模式.Docker借助容器技术彻底释放了轻量级虚拟化技术的威力,让容器的伸缩.应用的运行都变得前所未有的方 ...

  5. Docker源码分析(三):Docker Daemon启动

    1 前言 Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍然主要基于Linux平 ...

  6. docker 源码分析 一(基于1.8.2版本),docker daemon启动过程;

    最近在研究golang,也学习一下比较火的开源项目docker的源代码,国内比较出名的docker源码分析是孙宏亮大牛写的一系列文章,但是基于的docker版本有点老:索性自己就git 了一下最新的代 ...

  7. docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储

    前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...

  8. Docker源码分析(九):Docker镜像

    1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...

  9. Docker源码分析(一):Docker架构

    1 背景 1.1 Docker简介 Docker是Docker公司开源的一个基于轻量级虚拟化技术的容器引擎项目,整个项目基于Go语言开发,并遵从Apache 2.0协议.目前,Docker可以在容器内 ...

随机推荐

  1. sql server2008 R2 生成带数据的脚本

    目前 sql server2008 R2 版本有这个功能 http://www.cnblogs.com/weisenz/archive/2013/03/20/2971334.html

  2. Cable TV Network-POJ1966图的连通度

    Cable TV Network Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 4404 Accepted: 2047 Desc ...

  3. pickle与shelve

    pickle Example 写入文件 import pickle integers = [1, 2, 3, 4, 5] with open('pickle-example.p', 'wb') as ...

  4. [SDN] What is SDN?

    本篇学习笔记写于 Sun Nov 13 15:08:02 2016, 可能有认识不全面的地方. 参考资料为ONF的官方网站中: Software-Defined Networking (SDN) De ...

  5. TortoiseGit 连接每次都要输入用户名和密码

    当你配置好git后,在C:\Documents and Settings\Administrator\ 或者  C:\Users\Administrator 目录下有一个 .gitconfig 的文件 ...

  6. 【Java】代处理?代理模式 - 静态代理,动态代理

    >不用代理 有时候,我希望在一些方法前后都打印一些日志,于是有了如下代码. 这是一个处理float类型加法的方法,我想在调用它前打印一下参数,调用后打印下计算结果.(至于为什么不直接用+号运算, ...

  7. Checkpoint--与lazy writer区别

    checkpoint目的是减少数据库的恢复时间(服务奔溃或重启服务后的恢复),而lazy writer的目的是保证SQL OS 有空闲缓存块和系统有一定可用内存. Checkpoint和lazyWri ...

  8. Windows Server 2008服务器配置FTP站点的方法教程

    1.首先,安装FTP服务   打开服务器管理器,点击角色,添加角色,如果安装过iis,角色摘要里面会有个Web服务器(IIS),点击后面的添加角色,滚动条拉到最后勾选FTP服务器,根据步骤安装. ww ...

  9. PHP 回调、匿名函数和闭包

    <?php class Product{ public $name; public $price; function __construct($name, $price){ $this-> ...

  10. Javascript学习笔记:9种创建对象的方式

    最基本的对象创建方式是通过Object构造函数或对象字面量的方式创建: ①通过Object构造函数的方式创建对象: var person=new Object();//或者写成var person={ ...