daemon初始化network controller

daemon的配置,网络部分的内容在cmd/dockerd/config_common_unix.go中指定,默认设置一般都为空

// daemon/daemon_unix.go

1、func (daemon *Daemon) initNetworkController(config *config.Config, activeSandboxes map[string]interface{}) (libnetwork.NetworkController, error)

  • 调用netOptions, err := daemon.networkOptions(config, daemon.PluginStore, activeSandboxes)初始化netOptions
  • 调用controller, err := libnetwork.New(netOptions...)初始network controller
  • 如果"none"和"host"这两个network不存在,则分别调用controller.NewNetwork(...)进行创建
  • 如果"bridge"这个network存在,则先将其删除,最后调用initBridgeDriver()进行创建

2、daemon/daemon.go

func (daemon *Daemon) networkOptions(dconfig *config.Config, pg plugingetter.PluginGetter, activeSandboxes map[string]interface{}) ([]nwconfig.Option, error)

  • 设置默认的network mode和network
  • 对其它options进行设置

3、daemon/daemon_unix.go

func initBridgeDriver(controller libnetwork.NetworkController, config *config.Config) error

  • 设置netOptions,其中的内容包括BridgeName,DefaultBridge,DriverMTU等等
  • 调用controller.NewNetwork("bridge", "bridge", ...)创建bridge类型对网络

容器创建过程网络部分的内容

Container结构与网络相关的部分如下所示:

// container/container.go

type Container struct {

  ....

  NetworkSettings  *network.Settings

  HostConfig     *containertypes.HostConfig 

  ...

}

network.Setting结构如下所示:

// daemon/network/settings.go

type Settings struct {

  ...

  Networks  map[string]*EndpointSettings   ---> 它只是对docker/api/types/network中的EndpointSettings的封装

  ...

}

EndpointSettings的结构如下所示,其中存储了network endpoint的细节信息:

// api/types/network/network.go

type EndpointSettings struct {

  // Configurations

  IPAMConfig *EndpointIPAMConfig

  Links    []string

  Aliases    []string

  // Operational data

  NetworkID   string

  EndpointID   string

  Gateway    string

  IPAddress     string

  .....

}

// daemon/start.go

1、func (daemon *Daemon) containerStart(container *container.Container, ....) (err error)

  • 调用daemon.initializeNetworking(container)对启动容器的网络进行配置

// daemon/container_operations.go

2、func (daemon *Daemon) initializeNetworking(container *container.Container) error

  • 调用container.HostConfig.NetworkMode.IsContainer()判断是否为container类型的网络模式
  • 调用container.HostConfig.NetworkMode.IsHost()判断是否为host类型的网络模式
  • 调用daemon.allocateNetwork(container)创建network
  • 最后调用并返回container.BuildHostnameFile()

// daemon/container_operations.go

3、func (daemon *Daemon) allocateNetwork(container *container.Container) error

  • 首先通过controller := daemon.netController获取network controller
  • 做一些前期处理的工作,先调用controller.SandboxDestroy(container.ID)清理可能遗留的sandbox,并且如果网络模式为none或者container模式则直接返回
  • 如果len(container.NetworkSettings.Networks)为0,则调用daemon.updateContainerNetworkSettings(container, nil)
  • 确认container.NetworkSettings.Networks[defaultName]是否存在,存在的话,调用cleanOperationalData以及daemon.connectToNetwork(...)将容器加入网络
  • 再遍历container.NetworkSettings.Networks,同样调用daemon.connectToNetwork()加入
  • 如果network没有连接到任何网络,则调用daemon.netController.NewSandbox()创建对应的sandbox

// daemon/container_operations.go

4、func (daemon *Daemon) updateContainerNetworkSettings(container *container.Container, endpointsConfig map[string]*networktypes.EndpointSettings)

  • 调用networkName := mode.NetworkName()获取网络名,如果mode为default,则调用networkName = daemon.netController.Config().Daemon.DefaultNetwork
  • 如果container.NetworkSettings.Networks为nil,则创建分配container.NetworkSettings.Networks,并将container.NetworkSettings.Networks[networkName] = &network.EndpointSettings{EndpointSettings: &networktypes.EndpointSettings{},}
  • 如果是默认模式,则将container.NetworkSettings.Networks["default"]转化为container.NetworkSettings.Networks["bridge"]

// daemon/container_operations.go

5、func (daemon *Daemon) connectToNetwork(container *container.Container,  idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error)

  • 调用n, config, err := daemon.findAndAttachNetwork(container, idOrName, endpointConfig)找到network
  • 调用sb := daemon.getNetworkSandbox(container)获取sandbox,如果sb为空,则调用sb, err = controller.NewSandbox(container.ID, options...)创建sandbox
  • 调用ep, err := n.CreateEndpoint(endpointName, createOptions...)创建endpoint
  • 调用joinOptions, err := container.BuildJoinOptions(n)和ep.Join(sb, joinOptions...)将endpoint加入sandbox

network命令创建网络

// api/types/types.go

NetworkCreateRequest结构如下所示:

type NetworkCreateRequest struct {

  NetworkCreate

  Name  string

}

type NetworkCreate struct {

  CheckDuplicate  bool

  Driver      string

  Scope      string

  EnableIPv6    bool

  IPAM        *network.IPAM

  Internal       bool

  Attachable    bool

  Ingress      bool

  ConfigOnly    bool

  ConfigFrom    *network.ConfigReference

  Options     map[string]string

  Labels      map[string]string

}

// daemon/network.go

1、func (daemon *Daemon) CreateNetwork(create types.NetworkCreateRequest) (*types.NetworkCreateResponse, error)

  • 该函数仅仅调用resp, err := daemon.createNetwork(create, "", false)

// daemon/network.go

2、func (daemon *Daemon) createNetwork(create types.NetworkCreateRequest, id string, agent bool) (*types.NetworkCreateResponse, error)

  • 首先调用runconfig.IsPreDefinedNetwork(create.Name)判断其是否为预定义的network
  • 再调用daemon.GetNetworkByName(create.Name)判断该名字的network是否已存在,如果存在且CheckDuplicate为true,则报错
  • 如果driver为空,获取controller的DefaultDriver
  • 根据create中的字段创建nwOptions
  • 调用n, err := c.NewNetwork(driver, create.Name, id, nwOptions...)创建network

network命令连接到网络

// daemon/network.go

1、func (daemon *Daemon) ConnectToNetwork(container, networkName string, endpointConfig *network.EndpointSettings) error

  • 调用container, err := daemon.GetContainer(containerName)获取容器信息
  • 调用daemon.ConnectToNetwork(container, networkName, endpointConfig)进行连接

// daemon/container_operations.go

2、func (daemon *Daemon) ConnectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings) error

  • 如果容器不在运行,则先调用n, err := daemon.FindNetwork(idOrName)找到network,如果n不为空,则调用daemon.updateNetworkConfig(container, n, endpointConfig, true)进行更新,否则将endpointConfig加入container.NetworkSettings.Networks[idOrName]
  • 如果容器在运行,则调用daemon.connectToNetwork(container, idOrName, endpointConfig, true)加入network

// daemon/container_operations.go

3、func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName string, endpointConfig *networktypes.EndpointSettings, updateSettings bool) (err error)

  • 调用n, config, err := daemon.findAndAttachNetwork(container, idOrName, endpointConfig)

networktypes.NetworkingConfig结构如下所示

// api/types/network/network.go

// NetworkingConfig represents the container's networking configuration for each of its interfaces
// Carries the networking configs specified in the `docker run` and `docker network connect` commands
type NetworkingConfig struct {
EndpointsConfig map[string]*EndpointSettings // Endpoint configs for each connecting network
}

  

// daemon/container_operations.go

4、func (daemon *Daemon) findAndAttachNetwork(container *container.Container, idOrName string, epConfig *networktypes.EndpointSettings) (libnetwork.Network, *networktypes.NetworkingConfig, error)

  • 首先调用n, err := daemon.FindNetwork(idOrName)找到network
  • 调用err = daemon.updateNetworkConfig(container, n, endpointConfig, updateSettings)
  • 接着获取sb := daemon.getNetworkSandbox(container),再调用ep, err := n.CreateEndpoint(endpointName, createOptions...)创建endpoint
  • 再调用daemon.updateEndpointNetworkSettings(container, n, ep)
  • 如果sb为nil,则先调用sb, err = controller.NewSandbox(container.ID, options...)创建sandbox,再调用container.UpdateSandboxNetworkSettings(sb)
  • 最后,调用ep.Join(sb, joinOptions...)加入网络

// container/container.go

5、func (container *Container) UpdateSandboxNetworkSettings(sb libnetwork.Sandbox) error

  • 设置container.NetworkSettngs.SandboxID = sb.ID()
  • 设置container.NetworkSettings.SandboxKey = sb.Key()

docker网络部分源码分析的更多相关文章

  1. ClearContainer 网络部分源码分析

    // cc-oci-runtime/src/oci.c /*! * Create the state file, apply mounts and run hooks, but do not star ...

  2. Docker源码分析(五):Docker Server的创建

    1.Docker Server简介 Docker架构中,Docker Server是Docker Daemon的重要组成部分.Docker Server最主要的功能是:接受用户通过Docker Cli ...

  3. Docker源码分析(三):Docker Daemon启动

    1 前言 Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍然主要基于Linux平 ...

  4. Docker源码分析(二):Docker Client创建与命令执行

    1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...

  5. Docker源码分析(八):Docker Container网络(下)

    1.Docker Client配置容器网络模式 Docker目前支持4种网络模式,分别是bridge.host.container.none,Docker开发者可以根据自己的需求来确定最适合自己应用场 ...

  6. docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储

    前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...

  7. docker 源码分析 一(基于1.8.2版本),docker daemon启动过程;

    最近在研究golang,也学习一下比较火的开源项目docker的源代码,国内比较出名的docker源码分析是孙宏亮大牛写的一系列文章,但是基于的docker版本有点老:索性自己就git 了一下最新的代 ...

  8. Docker源码分析(九):Docker镜像

    1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...

  9. Docker源码分析(七):Docker Container网络 (上)

    1.前言(什么是Docker Container) 如今,Docker技术大行其道,大家在尝试以及玩转Docker的同时,肯定离不开一个概念,那就是“容器”或者“Docker Container”.那 ...

随机推荐

  1. c++ __int64

    C++的64位整数[原]by 赤兔 在做ACM题时,经常都会遇到一些比较大的整数.而常用的内置整数类型常常显得太小了:其中long 和 int 范围是[-2^31,2^31),即-2147483648 ...

  2. Ubuntu 14.04 Server i386 安装 Oracle11g_11.2.0.3 RAC

    文档地址:doc 文档地址:doc

  3. CWorkBooks、CWorkBook、CWorkSheets、CWorkSheet、CRange

    我们使用VC++操作Excel,对于Excel编程来说肯定少不了要遇到六个最基本的类: CApplication.CWorkBook.CWorkBooks.CWorkSheet.CWorkSheets ...

  4. downtown uptown

    Downtown is a term primarily used in North America by English speakers to refer to a city's core (or ...

  5. 【Android开发】如何设计开发一款Android App

    本文从开发工具选择,UI界面.图片模块.网络模块.数据库产品选择.性能.安全性等几个方面讲述了如果开发一个Android应用.现在整理出来分享给广大的Android程序员. 开发工具的选择 开发工具我 ...

  6. android 应用能够安装在什么地方

    眼下我们仅仅能做到将应用安装在例如以下组合中:   1.关闭MTK_2SDCARD_SWAP,能够将应用安装在以下两个路径上      1)手机内存(internal storage)      2) ...

  7. MySQL<多表操作>

    多表操作 外键 什么是外键 外键是指引用另一个表中的一列或多列,被引用的列应该具有主键约束或唯一性约束. 外键用于建立和加强两个表数据之间的链接. 为表添加外键约束 想要真正连接两个表的数据,就需要为 ...

  8. Mac下,如何把项目托管到Github上(Github Desktop的使用)

    在上一篇中,详细讲解了使用X-code和终端配合上传代码的方法,这种方法比较传统,中间会有坑,英文看起来也费劲,不过Github官方提供了一个Mac版的客户端,如下图:

  9. 京东云擎提供了免费的wordpress一键安装功能了

    1. 京东云擎(http://jae.jd.com)提供了免费的个人博客WordPress一键安装功能了,如下图,给开发者分享福利! 免费的应用,提供了源码,提供了数据库: 我之前把文章发到首页,遭到 ...

  10. day7_直播_网络编程篇(元昊老师著)

    网络编程篇计算机网络: 多台独立的计算机用网络通信设备连接起来的网络.实现资源共享和数据传递. 比如,我们之前的学过的知识可以将D盘的一个文件传到C盘,但如果你想从你的电脑传一个文件到我的电脑上目前是 ...