From my reading of generateMacAddr
function (edit: answer concerned 1.3.0-dev
, but is still correct for 17.05
), MAC addresses generated by docker
are essentially the IPv4
address of the container's interface on the docker0
bridge: they are guaranteed to be consistent with the IP address.
The docker0
bridge's subnet you have to operate in, usually 255.255.0.0
as per this example of 172.17.42.1/16
, has 65,534 routable addresses. This does reduce entropy for UUID generation, but MAC address collision isn't possible as IPs must be unique, and the scenario of identical MAC, PID, time and counter in two containers on the same docker server/CoreOS host should not be a possibility.
However two CoreOS hosts (each running one docker
server) could potentially choose the same random subnet, resulting in the possibility of duplicated MACs for containers on different hosts. You could evade this by setting a fixed CIDR for the docker
server on each host:
--fixed-cidr=CIDR
— restrict the IP range from the docker0 subnet, using the standard CIDR notation like 172.167.1.0/28
. This range must be and IPv4 range for fixed IPs (ex: 10.20.0.0/16
) and must be a subset of the bridge IP range (docker0
or set using --bridge
). For example with --fixed-cidr=192.168.1.0/25
, IPs for your containers will be chosen from the first half of 192.168.1.0/24
subnet.
This should ensure unique MAC addresses across the cluster.
The original IEEE 802 MAC address comes from the original Xerox Ethernet addressing scheme. This 48-bit address space contains potentially 248 or 281,474,976,710,656 possible MAC addresses.
source
If you are concerned about lack of entropy (the IP to MAC mapping reduces it considerably), a better option may be to use a different mechanism for UUID generation. UUID versions 3, 4 and 5 do not take MAC address into account. Alternatively you could include the host machine's MAC in UUID generation.
Of course, whether this "considerable MAC space reduction" will have any impact of UUID generation should probably be tested before any code is changed.
Source linked to above:
// 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
}