docker daemon启动
载体为daemon,调度管理engine,任务执行靠job
Engine是map[string]Handler,type Handler func(*Job) Status
Daemon的启动流程:
- 注册serve job、pull job、create job、start job等
- 构建serveapi job,并执行ServeApi handler,创建支持多种协议请求(tcp/socker fd/默认unix socket)的http Server,支持TLS,包含http路由规则”POST”:{“/images/create”: postImagesCreate}
- 初始化graphdriver、graphdb、 graph.TagStore、 execdriver、volumedriver、daemon网络环境
- 构建init_networkdriver job,创建docker0网桥,配置iptables对容器发出的数据包做snat地址转换,是否开启容器间的通信
镜像下载
Docker pull Ubuntu:14.04
Docker client流程
- 解析命令行获取镜像名和register地址,反射机制调用DockerCli.CmdPull,从dockercfg中读出用户认证信息,构建RESTful请求/images/create
Docker server流程
- http路由规则对应执行postImagesCreate,从url中解析出镜像名、register地址和用户认证信息,执行pull job与registry建立session
Session包含认证信息和主机环境信息的http请求的工厂模式,需要和register发起多次请求
和docker register的通信
- 请求获取指定镜像名的image所有tag信息,存到RepositoryData中
- 获得下载镜像的image_id后,通过TagStore.pullingPool检查是否该镜像正在下载,map[string]chan struct{}
- 请求获取指定image_id的所有parent的image_id
- 对每个待下载的image_id,通过graph.idIndex检查是否在本地的镜像仓库graph中
- 请求获取该image_id的image json和大小信息,构建Image对象
- 请求获取该image_id的内容
- 在graph文件系统aufs/overlayfs存储image
配置TagStore
- 将下载的所有image_id都写入TagStore.Repositories中
- TagStore持久化到path.Join(config.root, “repositories-{graphfs}”)
镜像存储
注册到Graph中(aufs)
- aufs在layers/diff/mnt中创建image_id目录layers保留每个镜像的所有祖先镜像列表diff存储每个镜像layer的内容mnt该层镜像上挂载的可读写layer
- Union mount先以只读方式mount该镜像的所有祖先镜像的diff目录到该镜像的mnt目录,再以读写方式mount该镜像的diff目录到其mnt目录
- 将压缩的镜像内容(http body)解压到layer目录,通过文件流开头的10字节来判断文件类型,文件流封装在ProcessReader带进度条的文件流
- path.Join(Graph.root, image_id)中保留image json和文件大小的layersize文件
- 注册镜像id,idIndex是基数树/前缀树image_id由64位字符组成