(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. 在li元素中放入img图片时li的高度问题

    在li元素中放入img图片时li的高度会比img图片的高度多出几个像素,解决这个问题只需要将img元素的css设置成vertical-align: middle;就可以解决.

  2. oracle物化视图

    物化视图是一种特殊的物理表,“物化”(Materialized)视图是相对普通视图而言的.普通视图是虚拟表,应用的局限性大,任何对视图的查询,Oracle都实际上转换为视图SQL语句的查询. 这样对整 ...

  3. Using User-Named Triggers in Oracle Forms

    A user-named trigger is a trigger defined in a form by the developer. User-Named triggers do not aut ...

  4. Linux下环境变量设置

    分类 Linux下的环境变量按生存周期来划分,可以划分为两种: 1)永久的:需要修改配置文件, 变量永久生效 2)临时的:直接在终端使用export命令声明即可,但是关闭shell后失效. 设置方法 ...

  5. C++11在时空性能方面的改进

    C++11在时空性能方面的改进 这篇我们聊聊C++11在时间和空间上的改进点: 主要包括以下方面: 新增的高效容器:array.forward_list以及unordered containers: ...

  6. Install Google Pinyin on Ubuntu 14.04

    Install Google Pinyin on Ubuntu 14.04 I've been spending more and more time on Ubuntu and I'm not us ...

  7. 让IE7 IE8支持CSS3 background-size属性

    简介 CSS3 新增的 background-size 是一个很有用的属性,用于定义背景图片的尺寸,有了这个属性,你就可以任意指定背景图片的大小.其中最常用的值应该要数 cover 了,该值能让背景图 ...

  8. 关于Dagger 2 的使用方式

    什么是Dagger2 Dagger是为Android和Java平台提供的一个完全静态的,在编译时进行依赖注入的框架,原来是由Square公司维护,现在由Google维护. 我们知道Dagger是一个依 ...

  9. Deep Learning 15:RBM的学习

    RBM是深度学习的核心,所以必须彻底清楚地理解RBM原理.推导及其训练方法 1.读学位论文“基于深度学习的人脸识别研究”: 对RBM.DBN的介绍比较详细,可以作为基础阅读,再去读英文论文. 2.RB ...

  10. Ubuntu中设置静态IP和DNS

    在Ubuntu中设置静态IP共两步:1>设置IP:2>设置DNS1>设置IP    编辑 /etc/network/interface文件:       sudo vi /etc/n ...