根据我对generateMacAddr
函数的阅读(编辑:有关答案1.3.0-dev
,但仍然正确17.05
),生成的 MAC 地址docker
本质上是网桥上容器接口IPv4
的地址:它们保证与 IP 地址一致。docker0
docker0
您必须在其中操作的网桥子网,通常255.255.0.0
根据这个示例,172.17.42.1/16
有 65,534 个可路由地址。这确实减少了 UUID 生成的熵,但 MAC 地址冲突是不可能的,因为 IP 必须是唯一的,并且同一 docker 服务器/CoreOS 主机上的两个容器中相同的 MAC、PID、时间和计数器的情况应该是不可能的.
然而,两台 CoreOS 主机(每台运行一台docker
服务器)可能会选择相同的随机子网,从而导致不同主机上的容器的 MAC 重复。您可以通过为每个主机上的服务器设置固定 CIDR来规避这一点:docker
--fixed-cidr=CIDR
— 使用标准 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 地址。
来源
如果您担心缺乏熵(IP 到 MAC 的映射大大减少了它),更好的选择可能是使用不同的 UUID 生成机制。UUID 版本 3、4 和 5不考虑 MAC 地址。或者,您可以在 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
}