前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[docker](三)docker-client模式和daemon模式

[docker](三)docker-client模式和daemon模式

原创
作者头像
baron
修改2019-11-19 17:36:05
2.3K0
修改2019-11-19 17:36:05
举报
文章被收录于专栏:和baron一起学习TKE

docker项目GitHub源码

client模式

Docker命令对应的源文件是docker/docker.go,它的使用方式如下:

代码语言:txt
复制
docker [OPTIONS] COMMAND [arg ...]

其中OPTIONS参数称为flag,任何时候执行一个docker命令,Docker都需要先解析这些flag,然后按照用户声明的COMMAND向子命令执行对应的操作。

如果子命令为daemon,Docker就会创建一个运行在宿主机的daemon进程(docker/daemon.go#mainDaemon),即执行daemon模式。其余子命令都会执行client模式。处于client模式下的docker命令工作流程包含如下几个步骤。

1、解析flag信息

这里列出几个client模式比较重要的OPTIONS

  • Debug,对应-D和--debug参数,这个flag用于启动调试模式
  • LogLevel,对应-l和--log-level参数,默认等级是info,可选参数有:panic、error、warn、info、debug。
  • Hosts,对应-H和--host=[]参数,对于client模式,就是指本次操作需要连接的Docker daemon位置,而对于daemon模式,则提供所要监听的地址。若Hosts变量或者系统环境变量DOCKER_HOST不为空,说明用户指定了host对象;否则使用默认设定,默认情况下Linux系统设置为unix:///var/run/docker.sock.
  • protoAddrParts,这个信息来自于-H参数中://前后的两部分组合,即与Docker daemon建立通信的协议方式与socket地址。

2、创建client实例

client的创建就是在已有配置参数信息的基础上,调用api/client/cli.go#NewDockerCli,需要设置好proto(传输协议)、addr(host的目标地址)和tlsConfig(安全传输层协议的配置),另外还会配置标准输入输出及错误输出。

3、执行具体的命令

Docker client对象创建成功后,剩下的执行具体命令的过程就交给cli/cli.go来处理。

daemon模式

Docker运行时如果使用docker daemon 子命令,就会运行Docker daemon。一旦docker进入了daemon模式,剩下的初始化和启动工作就都由Docker的docker/daemon.go#CmdDaemon来完成。

Docker daemon通过一个server模块(api/server/server.go)接收来自client的请求,然后根据请求类型,交由具体的方法去执行。

下面是Docker daemon启动与初始化过程的详细解析

1、API Server的配置和初始化过程

首先,在docker/daemon.go#CmdDaemon中,Docker会继续按照用户的配置完成server的初始化并启动它。这个server为API Server,就是专门负责响应用户请求并将请求交给daemon具体方法去处理的进程。它的启动过程如下。

(I)整理解析用户指定的各项参数。

(2)创建PID文件。

(3)加载所需的serve峭助配置,包括日志、是否允许远程访问、版本以及TLS认证信息等。

(4)根据上述server配置,加上之前解析出来的用户指定的server配置(比如Hosts ),通过goroutine的方式启动API Server。这个server监听的socket位置就是Hosts的值。

(5)创建一个负责处理业务的daemon对象(对应daemon/damone.go)作为负责处理用户请求的

逻辑实体。

(6)对APIserver中的路由表进行初始化,即将用户的请求和对应的处理函数相对应起来。

(7)设置一个channel,保证上述goroutine只有在server出错的情况下才会退出。

(8)设置信号捕获,当Docker daemon进程收到INT, TERM, QUIT信号时,关闭API Server,调用shutdownDaemon停止这个daemon。

(9)如果上述操作都成功,API ServergjG会与上述daemon绑定,并允许接受来自client的连接。

(10)最后,Docker daemon进程向宿主机的init守护进程发送“READY=1”信号,表示这个Docker daemon已经开始正常工作了。

2、daemon对象的创建与初始化过程

这个过程需要完成的配置至少包括了如下功能点:Docker容器的配置信息、检测系统支持及用户权限、配置工作路径、加载并配置graphdriver、创建Docker网络环境、创建并初始化镜像数据库、创建容器管理驱动、检测DNS配置和加载已有Docke溶器等。

  • Docker容器的配置信息
代码语言:txt
复制
 - 设置默认的网络最大传输单元:当用户没有对一mt参数进行指定时,则将其设置为1500。
 - 检测网桥配置信息:此部分配置为进一步配置Docker网络提供铺垫。
  • 检测系统支持及用户权限

初步处理完Docker的配置信息之后,Docker对自身运行的环境进行了一系列的检测,主要包括3个方面。

代码语言:txt
复制
 - 操作系统类型对Docker daemon的支持,目前Docker daemon只能运行在Linux系统上。
 - 用户权限的级别,必须是root权限。
 - 内核版本与处理器的支持,只支持amd64架构的处理器,且内核版本必须升至3.10.0及以上。
  • 配置工作路径

配置Docker daemon的工作路径,主要是创建Docker daemon运行中所在的工作目录,默认为/var/lib/docker。若该目录不存在,则会创建,并赋予0700权限。

  • 配置Docker容器所需的文件环境
代码语言:txt
复制
 - 第一,创建容器配置文件目录。Docker daemon在创建Docker容器之后,需要将容器内的配置文件放到这个目录下统一管理。目录默认位置为:/var/lib/docker/containers,它下面会为每个具体容器保存如下几个配置文件,其中xxx为容器ID,这些配置文件里包含了这个容器的所有元数据。
代码语言:txt
复制
 - 第二,配置graphdriver目录。它用于完成Docker容器镜像管理所需的底层存储驱动层。所以,在这一步的配置工作就是加载并配置镜像存储驱动graphdriver,创建存储驱动管理镜像层文件系统所需的目录和环境,初始化镜像层元数据存储。
代码语言:txt
复制
 - 第三,配置镜像目录。主要工作是在Docker主目录下创建一个image目录,来存储所有镜像和镜像层管理数据,默认目录为‘`/var/lib/docker/image/"。在image目录下,每一个graphdriver都有一个具体的目录用于存储使用该graphdrive存储的镜像相关的元数据。
代码语言:txt
复制
 - 第四,调用volume/local/local.go#New创建volume驱动目录(默认为/lvar/lib/docker/volumes ),Docker中volume是宿主机上挂载到Docke溶器内部的特定目录。
代码语言:txt
复制
 - 第五,准备“可信镜像”所需的工作目录。在Docker工作根目录下创建trust目录。这个存储目录可以根据用户给出的可信url加载授权文件,用来处理可信镜像的授权和验证过程。
代码语言:txt
复制
 - 第六,创建distributionMetadataStore和referenceStoreoreferenceStore用于存储镜像的仓库列表。记录镜像仓库的持久化文件位于Docker根目录下的image/[graphdriver]/repositories.json中,主要用于做镜像ID与镜像仓库名之间的映射。distributionMetadataStore存储与第二版镜像仓库registry有关的元数据,主要用于做镜像层的diff id与registry中镜像层元数据之间的映射。
代码语言:txt
复制
 - 第七,将持久化在Docker根目录中的镜像、镜像层以及镜像仓库等的元数据内容恢复到daemon的imageStore, layerStore和referenceStore中。
代码语言:txt
复制
 - 第八,执行镜像迁移。

综上,这里Docker daemon需要在Docker根目录(/var/lib/docker)下创建并初始化一系列跟容器文件系统密切相关的目录和文件。这些文件和目录的具体作用为:

docker文件作用.png
docker文件作用.png
  • 创建Docker网络环境

创建Docker daemon运行环境的时候,创建网络环境是极为重要的一个部分。这不仅关系着容器对外的通信,同样也关系着容器间的通信。网络部分早已被抽离出来作为一个单独的模块,称为libnetworko libnetwork通过插件的形式为Docker提供网络功能,使得用户可以根据自己的需求实现自己的driver来提供不同的网络功能。

  • 初始化execdriver

execdrive提Docker中用来管理Docker容器的驱动。Docker调用execdrivers中的NewDriver()函数来创建新的execdriver。

在创建execdriver的时候,需要注意以下5部分信息。

代码语言:txt
复制
 - 运行时中指定使用的驱动类别,在默认配置文件中默认使用native,即其对应的容器运行时为libcontainer;
 - 用户定义的execdriver选项,即-exec-opt参数值;
 - 用户定义的-exec-root参数值,Docker execdriver运行的root路径,默认为/var/run/docker;
 - Docker运行时的root路径,默认为/var/lib/docker ;
 - 系统功能信息,包括容器的内存限制功能、交换区内存限制功能、数据转发功能以及AppArmo按全功能等。
  • 创建容器管理驱动

Docker daemon进程在经过以上诸多设置以及创建对象之后,最终创建出了daemon对象实例,其属性总结如下。

代码语言:txt
复制
 - ID:根据传人的证书生成的容器ID,若没有传人则自动使用ECDSA加密算法生成。
 - repository:部署所有Docke溶器的路径。
 - containers:用于存储具体Docke溶器信息的对象。
 - execCommands: Docker容器所执行的命令。
 - referenceStore:存储Docker像仓库名和镜像D的映射。
 - distributionMetadata5tore:v2版registry相关的元数据存储。
 - trustKey:可信任证书。
 - idIndex:用于通过简短有效的字符串前缀定位唯一的镜像。
 - sysInfo: Docker所在宿主机的系统信息。
 - configStore: Docker}h需要的配置信息。
 - execDriver: Docker容器执行驱动,默认为native类型。
 - statsCollector:收集容器网络及cgroup状态信息。
 - defaultLogConfig:提供日志的默认配置信息。
 - registryService:镜像存储服务相关信息。
 - EventsService:事件服务相关信息。
 - volumes: volume所使用的驱动,默认为local类型。
 - root : Docker运行的工作根目录。
 - uidMaps: uid的对应图。
 - gidMaps: gid的对应图。
 - seccompEnabled:是否使用seccomputeo
 - nameIndex:记录键和其名字的对应关系。
 - linkIndex:容器的link目录.记录容器的link关系。
  • 恢复已有的Docker容器

当Docker daemon启动时,会去查看在daemon.repository也就是在/var/lib/docker/containers中的内容。若有已经存在的Docker容器,则将相应信息收集并进行维护,同时重启restart policy为always的容器。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • client模式
  • daemon模式
相关产品与服务
容器镜像服务
容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档