Копия машины с чужим machine-id: общий адрес по DHCP и слипшийся журнал
Идентификатор машины ставится при установке и дальше не меняется — ни при смене имени, ни при замене оборудования. Именно на этом построены вещи, о которых при клонировании не думают: по нему называется каталог постоянного журнала, из него по умолчанию выводится идентификатор клиента DHCP. Поэтому копия машины, снятая вместе с заполненным файлом, борется с оригиналом за один адрес и пишет записи в каталог с тем же именем.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Образ снят вместе с заполненным файлом идентификатора
Для образов, которые разворачивают на многих машинах, файл полагается оставлять пустым или отсутствующим: тогда идентификатор создаётся при первой загрузке. Снятый «как есть» образ раздаёт всем копиям один и тот же.
-
Две копии просят один и тот же адрес
По умолчанию идентификатор клиента DHCP выводится из идентификатора машины. У копий он совпадает, и сервер выдаёт обеим одну и ту же привязку, а адрес начинает перескакивать между ними.
-
Старый идентификатор возвращается после очистки
Если в файле пусто, systemd берёт значение из запасных источников — файла шины сообщений, идентификатора виртуальной машины, и только потом создаёт случайное. Копия файла шины с прежним значением возвращает всё на круги своя.
-
Записи нескольких машин ложатся в один каталог
Каталог постоянного журнала называется идентификатором машины. При сборе журналов с нескольких машин в одно место записи копий складываются вместе, и по полю идентификатора их уже не разделить.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Действующий идентификатор и запасной источник, из которого он может вернуться после очистки.
cat /etc/machine-id; ls -l /var/lib/dbus/machine-idКаталоги журнала названы идентификатором машины: их несколько — значит идентификатор менялся.
ls -d /var/log/journal/*/С каким идентификатором прямо сейчас пишутся записи.
journalctl -n 1 -o verbose --no-pager | grep _MACHINE_IDКакой адрес выдан по DHCP: совпадение с адресом соседней копии и есть подтверждение беды.
networkctl status | grep -iE "Address|DHCP"Решение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Для образов, которые разворачивают на многих машинах, файл полагается оставлять пустым или отсутствующим: тогда идентификатор создаётся при первой загрузке. Снятый «как есть» образ раздаёт всем копиям один и тот же.
- Как проверить
-
Сравните идентификатор на копии и на оригинале.
cat /etc/machine-id hostnamectl | grep -i "Machine ID"
- Как исправить
-
Обнулите файл и создайте новый идентификатор, после чего перезагрузите копию. Для образов надёжнее оставлять пустой файл, а не удалять его: на образ только для чтения поверх пустого файла можно подмонтировать временный.
sudo truncate -s 0 /etc/machine-id sudo systemd-machine-id-setup sudo reboot
- Почему происходит
- По умолчанию идентификатор клиента DHCP выводится из идентификатора машины. У копий он совпадает, и сервер выдаёт обеим одну и ту же привязку, а адрес начинает перескакивать между ними.
- Как проверить
-
Посмотрите выданный адрес и настройки идентификатора клиента.
networkctl status 2>/dev/null | grep -iE "Address|DHCP" grep -rniE "DUID" /etc/systemd/networkd.conf /etc/systemd/network/*.network 2>/dev/null
- Как исправить
-
Переставьте идентификатор машины на копии. Если это почему-то невозможно, задайте вывод идентификатора клиента из адреса сетевой карты —
DUIDType=link-layerв настройках управления сетью.
- Почему происходит
- Если в файле пусто, systemd берёт значение из запасных источников — файла шины сообщений, идентификатора виртуальной машины, и только потом создаёт случайное. Копия файла шины с прежним значением возвращает всё на круги своя.
- Как проверить
-
Посмотрите, файл это или ссылка, и совпадает ли значение.
ls -l /var/lib/dbus/machine-id cat /var/lib/dbus/machine-id /etc/machine-id 2>/dev/null
- Как исправить
- Сделайте файл шины сообщений ссылкой на общий идентификатор, иначе очистка ничего не даст. На этой машине он ссылкой и является — проверить стоит именно на копии.
- Почему происходит
- Каталог постоянного журнала называется идентификатором машины. При сборе журналов с нескольких машин в одно место записи копий складываются вместе, и по полю идентификатора их уже не разделить.
- Как проверить
-
Посмотрите каталоги журнала и идентификатор в самих записях.
ls -d /var/log/journal/*/ journalctl -n 1 -o verbose --no-pager | grep _MACHINE_ID
- Как исправить
- Разведите идентификаторы до того, как настраивать сбор журналов, и различайте машины по имени узла. Несколько каталогов на одной машине означают, что идентификатор уже менялся — старые записи остались в прежнем каталоге.
Пример вывода
Две машины из одного образа с одинаковым идентификатором. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
host-a:~$ cat /etc/machine-id
9f0c1d2e4a5b47c8b3e1d6f70a2c9b45
host-b:~$ cat /etc/machine-id
9f0c1d2e4a5b47c8b3e1d6f70a2c9b45
host-b systemd-networkd[690]: enp1s0: DHCPv4 address 192.0.2.31/24 via 192.0.2.1
host-a systemd-networkd[688]: enp1s0: DHCP lease lost
host-b:~$ ls -d /var/log/journal/*/
/var/log/journal/9f0c1d2e4a5b47c8b3e1d6f70a2c9b45/
Связанные ошибки
- В журнале контейнера видны записи хоста Журнал внутри контейнера показывает не то, что ожидалось: каталог журнала хоста проброшен внутрь.
- Смена имени машины ломает работу служб После переименования часть служб отказывает: имя запомнено в настройках, сертификатах и кластерах.
- Адрес не получен: нет ответа от сервера DHCP Интерфейс поднят, адреса нет: нет ответов от сервера, не та подсеть, фильтрация в сети.
- Система загрузилась в состоянии degraded systemctl is-system-running возвращает degraded: часть служб не запустилась. Как найти их и что делать.
- Cannot assign requested address при привязке Ошибка 99 при привязке: адрес не принадлежит машине или ещё не поднят. Разбор с network-online.target и ip_nonlocal_bind.
- Temporary failure in name resolution в журнале службы Служба не может разрешить имя: не готова сеть, нет сервера имён, мешает изоляция. Разбор при загрузке и в работе.
- nginx: [emerg] host not found in upstream nginx не запускается: не разрешается имя узла из upstream или proxy_pass. Разбор порядка запуска и работы с именами.
- Интерфейс не настроен: systemd-networkd не применил описание Сеть не поднимается: файл описания не подхвачен, интерфейс под управлением другой службы, неверное совпадение по имени.
Источники
-
machine-id(5)
Идентификатор ставится при установке и постоянен; в образах для многих машин файл должен быть пустым или отсутствовать; запасные источники значения при пустом файле. -
systemd-machine-id-setup(1)
Создание нового идентификатора на машине или в смонтированном образе. -
systemd.networkd.conf(5)
DUIDType=vendor по умолчанию: идентификатор клиента DHCP выводится из идентификатора машины. -
Проверено на этой машине: systemd 255 (255.4-1ubuntu8.17), Ubuntu 24.04
Проверено на этой машине: каталог постоянного журнала назван идентификатором из /etc/machine-id, а /var/lib/dbus/machine-id — ссылка на него. Сообщение networkd о запасном источнике идентификатора клиента найдено в самом исполняемом файле. -
Журнал рабочего сервера, systemd 255
Само клонирование виртуальных машин не воспроизводилось: тут это следствие из документации и устройства файлов, а не опыт с двумя копиями.