[docker 1.13 源码分析]第二章 Docker container创建
来源:互联网 发布:linux查看文件夹下文件 编辑:程序博客网 时间:2024/05/16 07:11
第一章 Container create源码分析
1.1 NewCreateCommand函数(cli/command/container/create.go)
1.2 ContainerCreate函数(client/container_create.go)
创建一个容器在客户端实现是在client/container_create.go这个文件唯一一个函数,传入的参数主要有容器基本配置container.Config,container.HostConfig,network.NetworkingConfig。
Config只要目的是基于容器的可移植性信息,与host相互独立,非可移植性在HostConfig结构体中。Config包括容器的基本信息,名字,输入输出流等,不解释结构体注释很清晰。
type Config struct {
Hostname string // Hostname
Domainname string // Domainname
User string // User that will run the command(s) inside the container, also support user:group
AttachStdin bool // Attach the standard input, makes possible user interaction
AttachStdout bool // Attach the standard output
AttachStderr bool // Attach the standard error
ExposedPorts nat.PortSet `json:",omitempty"` // List of exposed ports
Tty bool // Attach standard streams to a tty, including stdin if it is not closed.
OpenStdin bool // Open stdin
StdinOnce bool // If true, close stdin after the 1 attached client disconnects.
Env []string // List of environment variable to set in the container
Cmd strslice.StrSlice // Command to run when starting the container
Healthcheck *HealthConfig `json:",omitempty"` // Healthcheck describes how to check the container is healthy
ArgsEscaped bool `json:",omitempty"` // True if command is already escaped (Windows specific)
Image string // Name of the image as it was passed by the operator (e.g. could be symbolic)
Volumes map[string]struct{} // List of volumes (mounts) used for the container
WorkingDir string // Current directory (PWD) in the command will be launched
Entrypoint strslice.StrSlice // Entrypoint to run when starting the container
NetworkDisabled bool `json:",omitempty"` // Is network disabled
MacAddress string `json:",omitempty"` // Mac Address of the container
OnBuild []string // ONBUILD metadata that were defined on the image Dockerfile
Labels map[string]string // List of labels set to this container
StopSignal string `json:",omitempty"` // Signal to stop a container
StopTimeout *int `json:",omitempty"` // Timeout (in seconds) to stop a container
Shell strslice.StrSlice `json:",omitempty"` // Shell for shell-form of RUN, CMD, ENTRYPOINT
}
只要是通过http请求发送至server端使用POST方法
func (cli *Client) post(ctx context.Context, path string, query url.Values, obj interface{}, headers map[string][]string) (serverResponse, error) {
body, headers, err := encodeBody(obj, headers)
if err != nil {
return serverResponse{}, err
}
return cli.sendRequest(ctx, "POST", path, query, body, headers)
}
1.3 postContainerCreate函数
创建容器的操作对应在server端得实现在api/server/router/container/container_routes.go中的postContainersCreate()函数;
主要工作是校验工作,从body获取1.2中的配置container配置,host配置,network配置,最终用的方法是调用接口方法ContainerCreate,这个方法是daemon中实现。
ccr, err := s.backend.ContainerCreate(types.ContainerCreateConfig{
Name: name,
Config: config,
HostConfig: hostConfig,
NetworkingConfig: networkingConfig,
AdjustCPUShares: adjustCPUShares,
}, validateHostname)
1.4 ContainerCreate函数
Daemon中的方法daemon/create.go文件。
主要是校验工作,不解释了。看主要方法daemon.create在1.5中讲解
container, err := daemon.create(params, managed)
if err != nil {
return containertypes.ContainerCreateCreatedBody{Warnings: warnings}, daemon.imageNotExistToErrcode(err)
}
1.5 create函数
if params.Config.Image != "" {
img, err = daemon.GetImage(params.Config.Image)
if err != nil {
return nil, err
}
if runtime.GOOS == "solaris" && img.OS != "solaris " {
return nil, errors.New("Platform on which parent image was created is not Solaris")
}
imgID = img.ID()
}
if container, err = daemon.newContainer(params.Name, params.Config, imgID, managed); err != nil {
return nil, err
}
来new一个新的container;接下来的就是为启动容器所做的工作:
if err := daemon.setRWLayer(container); err != nil {
return nil, err
}
创建读写层,详细看1.6讲解
rootUID, rootGID, err := idtools.GetRootUIDGID(daemon.uidMaps, daemon.gidMaps)
if err != nil {
return nil, err
}
if err := idtools.MkdirAs(container.Root, 0700, rootUID, rootGID); err != nil {
return nil, err
}
if err := idtools.MkdirAs(container.CheckpointDir(), 0700, rootUID, rootGID); err != nil {
return nil, err
}
以root uid gid的属性创建目录
if err := daemon.setHostConfig(container, params.HostConfig); err != nil {
return nil, err
}
① daemon.registerMountPoints注册所有挂载到容器的数据卷(1.8讲解)
② daemon.registerLinks,load所有links(包括父子关系),写入host配置至文件( 注册互联容器,容器可以通过 ip:端口访问,可以通过--link互联。)
③ container.ToDisk将container持久化至disk。路径为如下所示
/var/lib/docker/containers/$containerID
1.6 CreateRWLayer函数
位于文件layer/layer_store.go文件,layerStore结构体如下所示:
MetadataStore为接口,主要为获得层基本信息的方法。 metadata是这个层的额外信息,不仅能够让Docker获取运行和构建的信息,也包括父层的层次信息(只读层和读写层都包含元数据)。
graphdriver.Driver也为接口,主要以aufs主要介绍,在daemon/graphdriver文件下有aufs,btrfs,devmapper,overlay等的实现。 除差别和改动等的方法,graphdriver最主要的功能是 Get、 Put、 Create 和 Remove 方法 。
Aufs层关系
type layerStore struct {
store MetadataStore
driver graphdriver.Driver
layerMap map[ChainID]*roLayer
layerL sync.Mutex
mounts map[string]*mountedLayer
mountL sync.Mutex
}
type roLayer struct {
chainID ChainID
diffID DiffID
parent *roLayer
cacheID string
size int64
layerStore *layerStore
descriptor distribution.Descriptor
referenceCount int
references map[Layer]struct{}
}
每一层都包括指向父层的指针。如果没有这个指针,说明处于最底层。
1.7 CreateReadWrite函数
文件位于daemon/gradphdriver/aufs/aufs.go。主要功能是创建三个目录mnt,layers,diff,在将父层id记录
if err := a.createDirsFor(id); err != nil {
return err
}
创建三个目录 mnt,layers,diff
f, err := os.Create(path.Join(a.rootPath(), "layers", id))
if err != nil {
return err
}
以层的metadata为后缀名创建文件
if parent != "" {
ids, err := getParentIDs(a.rootPath(), parent)
if err != nil {
return err
}
if _, err := fmt.Fprintln(f, parent); err != nil {
return err
}
for _, i := range ids {
if _, err := fmt.Fprintln(f, i); err != nil {
return err
}
}
}
获得该层的父层,存在将所有父层id记录该文件
1.8 registerMountPoints函数
位于daemon/volumes.go,注册所有挂载到容器的数据卷,bind挂载。主要有三种方式和来源:
(1)容器本身自带的挂载的数据卷,容器的json镜像文件中 "Volumes"这个key对应内容;
(2)其他容器(--volumes-from)挂载的数据卷;
(3)命令行参数(-v)挂载与主机绑定的数据卷,与主机绑定得数据卷在docker中叫做bind-mounts;
- [docker 1.13 源码分析]第二章 Docker container创建
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(八):Docker Container网络(下)
- Docker源码分析(七):Docker Container网络 (上)
- Docker源码分析(八):Docker Container网络(下)
- 【docker 17 源码分析】 docker run container 源码分析二 docker start
- [docker 1.13 源码分析]第三章 docker pull image
- [docker 1.13 源码分析]第一章 Docker Daemon
- docker container DNS配置介绍和源码分析
- docker container DNS配置介绍和源码分析
- Docker remote api 创建container
- Docker源码分析(二):Docker Client创建与命令执行
- Docker源码分析(五):Docker Server的创建
- Docker源码分析(二):Docker Client创建与命令执行
- Docker源码分析(五):Docker Server的创建
- Docker源码分析(二):Docker Client创建与命令执行
- github 更新
- debugfs
- dev_dbg dynamic dbg使用
- 关于做事
- Taglist安装 ctags直接用apt-…
- [docker 1.13 源码分析]第二章 Docker container创建
- Git中.gitignore文件的使用
- idea和eclipse的快捷键
- 内核升级
- 内存泄露实例(整理)
- linux网络配置
- 菜鸟第一次接触虚拟机及菜鸟的第一个类
- 修复grub
- Object-c 中截取包含(中、英文、表情符号emojiicon)混合字符串的每个字符并获取此字符的unicode值