docker网络部分源码分析
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网络部分源码分析的更多相关文章
- ClearContainer 网络部分源码分析
// cc-oci-runtime/src/oci.c /*! * Create the state file, apply mounts and run hooks, but do not star ...
- Docker源码分析(五):Docker Server的创建
1.Docker Server简介 Docker架构中,Docker Server是Docker Daemon的重要组成部分.Docker Server最主要的功能是:接受用户通过Docker Cli ...
- Docker源码分析(三):Docker Daemon启动
1 前言 Docker诞生以来,便引领了轻量级虚拟化容器领域的技术热潮.在这一潮流下,Google.IBM.Redhat等业界翘楚纷纷加入Docker阵营.虽然目前Docker仍然主要基于Linux平 ...
- Docker源码分析(二):Docker Client创建与命令执行
1. 前言 如今,Docker作为业界领先的轻量级虚拟化容器管理引擎,给全球开发者提供了一种新颖.便捷的软件集成测试与部署之道.在团队开发软件时,Docker可以提供可复用的运行环境.灵活的资源配置. ...
- Docker源码分析(八):Docker Container网络(下)
1.Docker Client配置容器网络模式 Docker目前支持4种网络模式,分别是bridge.host.container.none,Docker开发者可以根据自己的需求来确定最适合自己应用场 ...
- docker 源码分析 四(基于1.8.2版本),Docker镜像的获取和存储
前段时间一直忙些其他事情,docker源码分析的事情耽搁了,今天接着写,上一章了解了docker client 和 docker daemon(会启动一个http server)是C/S的结构,cli ...
- docker 源码分析 一(基于1.8.2版本),docker daemon启动过程;
最近在研究golang,也学习一下比较火的开源项目docker的源代码,国内比较出名的docker源码分析是孙宏亮大牛写的一系列文章,但是基于的docker版本有点老:索性自己就git 了一下最新的代 ...
- Docker源码分析(九):Docker镜像
1.前言 回首过去的2014年,大家可以看到Docker在全球刮起了一阵又一阵的“容器风”,工业界对Docker的探索与实践更是一波高过一波.在如今的2015年以及未来,Docker似乎并不会像其他昙 ...
- Docker源码分析(七):Docker Container网络 (上)
1.前言(什么是Docker Container) 如今,Docker技术大行其道,大家在尝试以及玩转Docker的同时,肯定离不开一个概念,那就是“容器”或者“Docker Container”.那 ...
随机推荐
- openal 基础知识2
三枚举扩展包(enumeration extension,“ALC_ENUMERATION_EXT”) 开发者可以通过这个extension得到一个字符串列表,区分不同的渲染/捕捉设备.OpenALr ...
- 《开源框架那些事儿22》:UI框架设计实战
UI是User Interface的缩写.通常被觉得是MVC中View的部分,作用是提供跟人机交互的可视化操作界面. MVC中Model提供内容给UI进行渲染,用户通过UI框架产生响应,一般而言会由控 ...
- hadoop基础学习---数据管理策略
上图中的ABCDE都代表默认大小64M的数据块 nameNode与dataNode之间有一个心跳机制,datanode每隔多秒钟定期的发送心跳到nameNode
- SVN中Revert changes from this revision 跟Revert to this revision
譬如有个文件,有十个版本,假定版本号是1,2,3,4,5,6,7,8,9,10. Revert to this revision: 如果是在版本6这里点击“Revert to this revisio ...
- Linux 内核中 likely 与 unlikely 的宏定义解析
在 2.6 内核中,随处能够见到 likely() 和 unlikely() 的身影,那么为什么要用它们?它们之间有什么差别? 首先要明白: if(likely(value)) 等价于 if(valu ...
- laravel 使用 session
配置方面的不写了,请参考学院君的文章:http://laravelacademy.org/post/5898.html 在开始之前先说一下,使用 request 对象的 session() 方法,和直 ...
- HTML实体大全
HTML 4.01 支持 ISO 8859-1 (Latin-1) 字符集. ISO-8859-1 的较低部分(从 1 到 127 之间的代码)是最初的 7 比特 ASCII. ISO-8859-1 ...
- C++异常 异常机制
C++异常是丢程序运行过程中发生的异常情况(例如被0除)的一种响应.异常提供了将控制权从程序的一个部分传递到另一部分的途径.对异常的处理有3个组成部分:* 引发异常:* 使用处理程序捕获异常:* 使用 ...
- php数据访问之查询关键字
本文根据数据库中的car表做一个汽车查询页面,巩固php查询关键字操作,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了php查询操作的实现代码,供大家参考,具体内容如下 一.一个关键字查询 主 ...
- poj_2352 线段树
题目大意 对于二维平面上的n个点,给出点的坐标.定义一个点A覆盖的点的个数为满足以下条件的点B的个数:点B的x <= 点A的x坐标,点B的y坐标 <= 点A的y坐标. 给出N个点的 ...