Генерация MAC-адресов Docker
У меня был вопрос о приложениях, работающих в контейнерах Docker и генерации UUID.
вот:в настоящее время наши приложения с помощью событийная основа.
для событий, которые мы генерируем UUID на основе mac-адреса, pid,
отметка времени и счетчик.для запуска контейнеров в распределенной системе, такой как CoreOS (в то время как очень очень низкий шанс), нет никакой гарантии, что все параметры, используемые для создания UUID, будут уникальными для каждого контейнера, поскольку один контейнер на одном сервере в кластере может генерировать UUID, используя тот же mac, pid, отметку времени и счетчик, что и другой контейнер в кластере.
по сути, если бы эти два UUID должны были генерировать событие и отправлять его на нашу шину обмена сообщениями, то, очевидно, был бы конфликт.
в нашем анализе этот сценарий кажется, сводится к уникальности mac-адресов в каждом контейнере Docker.
Так что будем откровенны:
- насколько уникальны mac-адреса в контейнерах?
- как создаются MAC-адреса, если они не заданы вручную?
1 ответов
из моего чтения generateMacAddr
функции (редактировать: ответ касался 1.3.0-dev
, но по-прежнему правильно для 17.05
), MAC-адреса, генерируемые docker
по существу IPv4
адрес интерфейс контейнера на docker0
мост: они гарантированы, что будут последовательны с IP-адресом.
на docker0
подсеть моста, в которой вы должны работать, обычно 255.255.0.0
согласно of 172.17.42.1/16
, имеет 65 534 маршрутизируемых адреса. Это уменьшает энтропию для генерации UUID, но столкновение MAC-адресов невозможно, поскольку IP-адреса должны быть уникальными, а сценарий идентичных MAC, PID, time и counter в двух контейнерах на одном сервере docker/хосте CoreOS не должен быть возможен.
однако два хоста CoreOS (каждый работает один docker
сервер) потенциально может выбрать одну и ту же случайную подсеть, что приводит к возможности дублированные Mac для контейнеров на разных хостах. Вы можете избежать этого, установив исправлено CIDR на docker
сервер на каждом хосте:
--fixed-cidr=CIDR
- ограничьте диапазон IP от подсети docker0, используя стандартную нотацию CIDR, как172.167.1.0/28
. Этот диапазон должен быть и диапазон IPv4 для фиксированных IPs (например:10.20.0.0/16
) и должно быть подмножеством диапазона IP моста (docker0
через--bridge
). Например, с--fixed-cidr=192.168.1.0/25
, IPs для ваших контейнеров будет выбран из первой половины192.168.1.0/24
подсети.
это должно обеспечить уникальные MAC-адреса по всему кластеру.
исходный MAC-адрес IEEE 802 получен из оригинальной схемы адресации Xerox Ethernet. Это 48-разрядное адресное пространство содержит потенциально 248 или 281,474,976,710,656 возможных MAC-адресов.
если вы обеспокоены отсутствием энтропии (сопоставление IP с MAC значительно уменьшает его), лучшим вариантом может быть использование другого механизма для генерации UUID. UUID версии 3, 4 и 5 не принимать MAC-адрес в расчет. В качестве альтернативы вы можете включить MAC хост-машины в генерацию UUID.
конечно, будет ли это "значительное сокращение пространства 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
}