创建一个新容器但是不运行它
接着上面的r.initRoutes()
initRoutes() #里面有多个操作,以创建为例
-> r.postContainersCreate() [container_routes.go]
-> s.backend.ContainerStart () #ContainerStart为一个接口
-> containerCreate() [create.go]
-> daemon.create()
1. daemon.GetImage()
2. 校验配置
3. daemon.newContainer()
4. daemon.setSecurityOptions()
5. daemon.setRWLayer()
6. daemon.setHostConfig()
7. daemon.createContainerPlatformSpecificSettings()
8. daemon.updateContainerNetworkSettings()
9. daemon.Register()
容器的定义
type Container struct {
CommonContainer
// Fields below here are platform specific.
AppArmorProfile string
HostnamePath string
HostsPath string
ShmPath string
ResolvConfPath string
SeccompProfile string
NoNewPrivileges bool
}
type CommonContainer struct {
StreamConfig *stream.Config
// embed for Container to support states directly.
*State `json:"State"` // Needed for remote api version <= 1.11
Root string `json:"-"` // Path to the "home" of the container, including metadata.
BaseFS string `json:"-"` // Path to the graphdriver mountpoint
RWLayer layer.RWLayer `json:"-"`
ID string
Created time.Time
Managed bool
Path string
Args []string
Config *containertypes.Config
ImageID image.ID `json:"Image"`
NetworkSettings *network.Settings
LogPath string
Name string
Driver string
// MountLabel contains the options for the 'mount' command
MountLabel string
ProcessLabel string
RestartCount int
HasBeenStartedBefore bool
HasBeenManuallyStopped bool // used for unless-stopped restart policy
MountPoints map[string]*volume.MountPoint
HostConfig *containertypes.HostConfig `json:"-"` // do not serialize the host config in the json, otherwise we'll make the container unportable
ExecCommands *exec.Store `json:"-"`
// logDriver for closing
LogDriver logger.Logger `json:"-"`
LogCopier *logger.Copier `json:"-"`
restartManager restartmanager.RestartManager
attachContext *attachContext
}
containerStart()
-> 先判断容器状态是否为RemovalInProgress或者Dead,如果是则退出
-> conditionalMountOnStart 挂载镜像
-> Mount()
-> initializeNetworking(container) 初始化容器网络
-> 先判断是host模式还是容器,读取主机配置
-> allocateNetwork()
-> SandboxDestroy(container.ID)
-> 如果container.NetworkSettings.Networks为空,则updateContainerNetworkSettings更新
-> 循环container.NetworkSettings.Networks,调用connectToNetwork()
-> updateNetworkConfig()
-> getNetworkSandbox() 得到sb
-> BuildCreateEndpointOptions() 构建ep配置
-> CreateEndpoint() 创建ep
->
-> defer 退出时候删除endpoint
-> 把endpointConfig赋值给container.NetworkSettings.Networks[n.Name()]
-> updateEndpointNetworkSettings()
-> 如果sandbox为空则新建一个
-> ep.Join把endpoint加到sandbox中
-> 设置锁
-> ep.sbJoin
-> 去store里面拿了ep和network
-> 获取driver,然后Join到ep中
-> 设置一个defer,把driver从ep中移出
-> 获取了IP(ep.iface.addr.IP)
-> 更新sb和把ep塞入controller的store
-> sb.getGatewayEndpoint()为sb提供外部连接
-> sb.populateNetworkResources()
-> ep.iface和ep.iface.srcName 不为空, 把部分参数赋值到sb里面
-> 更新sb的gateway
->
-> getPortMapInfo获取sb的端口表,赋值给container.NetworkSettings.Ports
->
->
postContainersRestart() [\api\server\router\container\container_routes.go]
-> ContainerRestart()
-> GetContainer()
-> containerRestart()
-> Mount()
-> containerStop()
-> containerStart()
接着上面的r.initRoutes()
r.deleteContainers()
-> 解析参数,创建删除参数ContainerRmConfig
-> ContainerRm() [\container\container.go]
-> daemon.GetContainer(name)获取容器,如果出错直接退出
-> SetRemovalInProgress()设置容器状态为removed,避免重复
-> daemon.containers.Get(ID)
-> 如果config.RemoveLink为真,则调用daemon.rmLink()并直接退出
-> cleanupContainer()
-> 如果容器正在运行,config.ForceRemove为假,则退出,为真则kill容器
-> stopCollection() 关闭订阅,并从度量收集中删除
-> containerStop()
-> SetDead() 把容器标记为dead,防止别的启动
-> ToDiskLocking() 保存容器状态到磁盘
->