docker如果构建bridge网络
如果在docker daemon启动参数中指定了-b选项,那么Container默认会使用bridge方式的网络。
docker客户端运行run命令,解析命令行参数后发起post start消息给docker server,docker server启动"start" job
, "start" job
的具体实现在daemon/container.go
的Start
方法中。
在建立Container的DNS和挂在basesfs之后做了初始化网络,具体实现在container的initializeNetworking
方法中。
initializeNetworking
主要做了以下几部分:
1 判断Container使用的网络类型,此次分析bridge模式。
根据container.hostConfig.NetworkMode判断Container使用的网络模式。
IsHost
Container使用主机网络IsContainer
Container使用其他Container的网络DisableNetwork
仅使用loopback设备- 不是以上三种中的一种,那么Container使用bridge网络
2 分配bridge模式的网络
bridge模式的实现在Container的AllocateNetwork
方法中。
AllocateNetwork功能如下:
2.1 分配birdge网络接口
使用allocate_interface
job分配Container网络接口IP、MAC信息。allocate_interface
对应的方法在daemon/networkdriver/driver.go
中初始化。
for name, f := range map[string]engine.Handler{
"allocate_interface": Allocate,
"release_interface": Release,
"allocate_port": AllocatePort,
"link": LinkContainers,
} {
if err := job.Eng.Register(name, f); err != nil {
return job.Error(err)
}
}
在Allocate
中,获取job中的RequestedIP
。如果有,使用此IP;如果没有,在bridge的网络地址划分中选取新的IP地址,最后检查IP是否合法。Container使用的bridge网络记录在bridgeIPv4Network
中。同样也是在InitDriver
中初始化。docker使用的bridge网络如下:
addrs = []string{
// Here we don't follow the convention of using the 1st IP of the range for the gateway.
// This is to use the same gateway IPs as the /24 ranges, which predate the /16 ranges.
// In theory this shouldn't matter - in practice there's bound to be a few scripts relying
// on the internal addressing or other stupid things like that.
// They shouldn't, but hey, let's not break them unless we really have to.
"172.17.42.1/16", // Don't use 172.16.0.0/16, it conflicts with EC2 DNS 172.16.0.23
"10.0.42.1/16", // Don't even try using the entire /8, that's too intrusive
"10.1.42.1/16",
"10.42.42.1/16",
"172.16.42.1/24",
"172.16.43.1/24",
"172.16.44.1/24",
"10.0.42.1/24",
"10.0.43.1/24",
"192.168.42.1/24",
"192.168.43.1/24",
"192.168.44.1/24",
}
接下来分配接口的MAC地址。此MAC地址是有分配的IP地址产生的。使用generateMac
生成。
IPv6不做分析重点,但和IPv4的很相似。
2.2 端口处理
主要处理Container和host之间的端口分配和绑定。不做重点。