根据我对generateMacAddr function 的阅读(编辑:答案关注1.3.0-dev,但对于17.05 仍然正确), docker生成的MAC地址本质上就是container's interface在docker0桥上的IPv4地址:保证与IP地址一致。
您必须操作的docker0 网桥的子网,通常是255.255.0.0,根据172.17.42.1/16 的this example,有65,534 个可路由地址。这确实减少了 UUID 生成的熵,但 MAC 地址冲突是不可能的,因为 IP 必须是唯一的,并且同一 docker 服务器/CoreOS 主机上的两个容器中相同的 MAC、PID、时间和计数器的情况应该是不可能的.
但是,两台 CoreOS 主机(每台运行一个 docker 服务器)可能会选择相同的随机子网,从而导致不同主机上的容器的 MAC 重复的可能性。您可以通过为每个主机上的docker 服务器设置fixed CIDR 来避免这种情况:
--fixed-cidr=CIDR — 限制来自 docker0 子网的 IP 范围,使用标准 CIDR 表示法,如 172.167.1.0/28。此范围必须是固定 IP 的 IPv4 范围(例如:10.20.0.0/16),并且必须是网桥 IP 范围的子集(docker0 或使用--bridge 设置)。例如--fixed-cidr=192.168.1.0/25,容器的 IP 将从192.168.1.0/24 子网的前半部分中选择。
这应该确保整个集群的 MAC 地址是唯一的。
原始 IEEE 802 MAC 地址来自原始 Xerox 以太网寻址方案。这个 48 位地址空间可能包含 248 或 281,474,976,710,656 个可能的 MAC 地址。
source
如果您担心缺少熵(IP 到 MAC 的映射大大减少了它),更好的选择可能是使用不同的 UUID 生成机制。 UUID 版本 3、4 和 5 do not take MAC address 考虑在内。或者,您可以在 UUID 生成中包含主机的 MAC。
当然,这种“显着减少 MAC 空间”是否会对 UUID 生成产生任何影响,应该在更改任何代码之前进行测试。
以上链接来源:
// Generate a IEEE802 compliant MAC address from the given IP address.
//
// The generator is guaranteed to be consistent: the same IP will always yield the same
// MAC address. This is to avoid ARP cache issues.
func generateMacAddr(ip net.IP) net.HardwareAddr {
hw := make(net.HardwareAddr, 6)
// The first byte of the MAC address has to comply with these rules:
// 1. Unicast: Set the least-significant bit to 0.
// 2. Address is locally administered: Set the second-least-significant bit (U/L) to 1.
// 3. As "small" as possible: The veth address has to be "smaller" than the bridge address.
hw[0] = 0x02
// The first 24 bits of the MAC represent the Organizationally Unique Identifier (OUI).
// Since this address is locally administered, we can do whatever we want as long as
// it doesn't conflict with other addresses.
hw[1] = 0x42
// Insert the IP address into the last 32 bits of the MAC address.
// This is a simple way to guarantee the address will be consistent and unique.
copy(hw[2:], ip.To4())
return hw
}