Сценарий: Linux‑ВМ (обычно Ubuntu/Debian) в Proxmox перестала пускать в систему — на консоли через VNC видно ошибки вида:
[FAILED] Failed to start D-Bus System Message Bus- ошибки PAM при логине (
PAM Failure, aborting,Error in service module)
По SSH и сети попасть на гостевую систему нельзя, но на той же ноде Proxmox есть рабочая ВМ (rescue‑ВМ), куда можно зайти по SSH.
Ниже — пошаговая инструкция, как:
- Полностью восстановить систему, примонтировав диск сломанной ВМ к рабочей.
- Если это не нужно — просто спасти Docker‑контейнеры и их данные, а старую ВМ оставить/удалить.
Примеры команд:
- сломанная ВМ:
7000 - рабочая / rescue‑ВМ:
8000 - нода Proxmox:
pve - хранилище LVM:
local-lvm
Подставьте свои ID и storage.
Бэкап и поиск диска ВМ
На хосте Proxmox:
# 1. Сделать бэкап ВМ (ОБЯЗАТЕЛЬНО)
vzdump 7000 --storage local --mode snapshot
# 2. Найти диск ВМ
qm config 7000 | grep -E 'scsi|virtio|sata'
Типичный вывод:
bootdisk: scsi0
scsi0: local-lvm:vm-7000-disk-0,size=100G
Запоминаем local-lvm:vm-7000-disk-0.
Отцепить диск от 7000 и прицепить к 8000
На Proxmox‑хосте:
# Остановить сломанную ВМ
qm stop 7000
# Отвязать диск от 7000 (НЕ удаляет данные на storage)
qm set 7000 --delete scsi0
# Прицепить диск к рабочей ВМ 8000 как scsi1
qm set 8000 --scsi1 local-lvm:vm-7000-disk-0
# Запустить рабочую ВМ
qm start 8000
Аналог через веб‑интерфейс:
- для 7000:
Hardware → Disk → Detach(НЕ Remove); - для 8000:
Hardware → Add → Existing disk → vm-7000-disk-0(например какscsi1).
Смонтировать диск сломанной ВМ в рабочей
Внутри ВМ 8000 (по SSH):
lsblk
Пример:
sda ... 22G
├─sda1 ... /
└─sda15... /boot/efi
sdb ... 98G
├─sdb1 ... 82G
├─sdb14
└─sdb15
Чаще всего корневая ФС сломанной ВМ — это sdb1:
mkdir -p /mnt/vm7000
mount /dev/sdb1 /mnt/vm7000
ls /mnt/vm7000
# должны увидеть стандартные каталоги: bin, etc, var, usr, home, ...
Если вместо обычных разделов там LVM (видны LVM2_member, vg-.../lv-...), последовательность:
pvscan
vgscan
vgchange -ay # активировать VG
lvdisplay # найти LV с корнем, например /dev/vgname/root
mount /dev/vgname/root /mnt/vm7000
Вариант А: /etc живой — chroot и переустановка dbus/systemd/login
Если ls /mnt/vm7000/etc показывает нормальное дерево (passwd, apt, pam.d, куча файлов), /etc не разрушен. Тогда достаточно chroot и переустановки критичных служб.
В рабочей ВМ (8000):
mount --bind /dev /mnt/vm7000/dev
mount --bind /proc /mnt/vm7000/proc
mount --bind /sys /mnt/vm7000/sys
chroot /mnt/vm7000 /bin/bash
Внутри chroot:
mount -o remount,rw /
df -h
apt update
apt install --reinstall dbus systemd-sysv login
# по желанию обновить пароль root
passwd root
exit
Снаружи (в 8000):
umount /mnt/vm7000/dev
umount /mnt/vm7000/proc
umount /mnt/vm7000/sys
umount /mnt/vm7000
После этого можно возвращать диск в 7000 (см. 1.6).
Вариант Б: /etc почти пустой — восстанавливаем из рабочей ВМ
Типичная ситуация после повреждения диска: в /mnt/vm7000/etc только systemd, lvm и пара каталогов, а apt, passwd, pam.d и т.д. отсутствуют.
В рабочей ВМ (не в chroot):
ls -la /mnt/vm7000/etc
# видим 2–4 каталога, почти ничего нет
Сначала делаем бэкап того, что есть:
mkdir -p /mnt/vm7000/etc-broken-backup
cp -a /mnt/vm7000/etc/* /mnt/vm7000/etc-broken-backup/ 2>/dev/null || true
Теперь копируем из рабочей ВМ базовый набор конфигов:
# APT
cp -a /etc/apt /mnt/vm7000/etc/
# Пользователи и группы (root и юзеры будут как на рабочей ВМ)
cp /etc/passwd /mnt/vm7000/etc/passwd
cp /etc/shadow /mnt/vm7000/etc/shadow
cp /etc/group /mnt/vm7000/etc/group
cp /etc/gshadow /mnt/vm7000/etc/gshadow
# NSS и PAM
cp /etc/nsswitch.conf /mnt/vm7000/etc/nsswitch.conf
cp -a /etc/pam.d /mnt/vm7000/etc/pam.d
# hosts и DNS
cp /etc/hosts /mnt/vm7000/etc/hosts
cp /etc/resolv.conf /mnt/vm7000/etc/resolv.conf
Проверяем:
ls -la /mnt/vm7000/etc | head
# теперь видим apt/, passwd, shadow, pam.d, hosts и т.д.
Дальше — полноценный chroot и переустановка сервисов:
mount --bind /dev /mnt/vm7000/dev
mount --bind /proc /mnt/vm7000/proc
mount --bind /sys /mnt/vm7000/sys
chroot /mnt/vm7000 /bin/bash
Внутри:
mount -o remount,rw /
df -h
apt update
apt install --reinstall dbus systemd-sysv login
passwd root # задать новый понятный пароль
exit
Снаружи:
umount /mnt/vm7000/dev
umount /mnt/vm7000/proc
umount /mnt/vm7000/sys
umount /mnt/vm7000
Важно: после копирования
/etc/passwdи/etc/shadowлокальные пользователи/пароли на восстановленной ВМ будут такими же, как на рабочей ВМ. После успешного логина имеет смысл привести их в порядок.
Вернуть диск обратно в исходную ВМ
На Proxmox‑хосте:
# Остановить рабочую ВМ, чтобы безопасно убрать диск
qm stop 8000
qm set 8000 --delete scsi1
qm start 8000
# Вернуть диск в 7000
qm set 7000 --scsi0 local-lvm:vm-7000-disk-0
# Запустить восстановленную ВМ
qm start 7000
Дальше подключаемся к 7000 по VNC и логинимся под root с паролем, который задавали в chroot. Проверяем:
df -h
systemctl status dbus
systemctl status ssh
ip a
Если ошибки Failed to start D-Bus System Message Bus и PAM Failure исчезли, а логин и сеть работают — ВМ спасена.
Восстановление только Docker‑контейнеров и данных
Бывает, что сам гостевой Linux уже не важен: проще поднять новую чистую ВМ и просто «переехать» туда со всеми контейнерами и томами Docker.
Идея:
- смонтировать диск старой ВМ в новую;
- скопировать
/var/lib/dockerи нужные bind‑mount‑каталоги; - запустить Docker на новой ВМ — контейнеры и данные окажутся на месте.
Подключить диск старой ВМ к новой Docker‑ВМ
На Proxmox‑хосте:
qm stop 7000
qm set 7000 --delete scsi0
qm set 8000 --scsi1 local-lvm:vm-7000-disk-0
qm start 8000
Смонтировать диск и проверить наличие Docker‑данных
Внутри новой Docker‑ВМ (8000):
lsblk # ищем новый диск, чаще всего /dev/sdb
mkdir -p /mnt/vm7000
mount /dev/sdb1 /mnt/vm7000
ls /mnt/vm7000/var/lib/docker
# должны увидеть: containers, overlay2, volumes, image, tmp, ...
Остановить Docker на новой ВМ и сделать бэкап его текущих данных
systemctl stop docker docker.socket containerd 2>/dev/null || true
# бэкап существующего /var/lib/docker
mv /var/lib/docker /var/lib/docker.empty-$(date +%F-%H%M) 2>/dev/null || true
mkdir -p /var/lib/docker
Скопировать Docker‑данные со старой ВМ
rsync -a /mnt/vm7000/var/lib/docker/ /var/lib/docker/
(слэш в конце пути важен — копируется содержимое, а не вложенный каталог docker.)
Перенести bind‑mount‑каталоги (если были)
Если в docker run / docker compose использовались bind‑mount’ы (например /home/es_index/data, /opt/..., /srv/...), их тоже нужно перенести.
Посмотреть монтирования конкретного контейнера:
docker inspect <container_name> --format '{{ range .Mounts }}{{ .Source }} -> {{ .Destination }}{{ printf "\n" }}{{ end }}'
Пример:
/home/es_index/data -> /usr/share/elasticsearch/data
Тогда копируем данные с диска старой ВМ:
rsync -a /mnt/vm7000/home/es_index/ /home/es_index/
(Аналогично для других путей /opt/..., /srv/... и т.п.)
Запустить Docker и проверить контейнеры
systemctl start docker
systemctl status docker --no-pager
docker ps
docker ps -a
docker volume ls
Если всё сделано правильно, вы увидите те же контейнеры и тома, что и на старой ВМ.
Частые проблемы с Elasticsearch в контейнере
Не хватает памяти (Java heap / mmap failed)
Лог:
There is insufficient memory for the Java Runtime Environment to continue.
Native memory allocation (mmap) failed to map 2147483648 bytes.
Решения:
- увеличить RAM ВМ и/или лимит памяти контейнера;
- уменьшить heap через
ES_JAVA_OPTS:
docker stop es_port5418
docker rm es_port5418
docker run -d \
--name es_port5418 \
-e ES_JAVA_OPTS="-Xms1g -Xmx1g" \
-e discovery.type=single-node \
-p 9200:9200 \
-v /home/es_index/data:/usr/share/elasticsearch/data \
docker.elastic.co/elasticsearch/elasticsearch:8.15.0
Ошибка failed to obtain node locks / проблемы с node.lock
Лог:
failed to obtain node locks, tried [/usr/share/elasticsearch/data]
maybe these locations are not writable or multiple nodes were started on the same data path
Шаги:
- Смотрим, куда смонтированы данные ES:
docker inspect es_port5418 --format '{{ range .Mounts }}{{ .Source }} -> {{ .Destination }}{{ printf "\n" }}{{ end }}' # пример: /home/es_index/data -> /usr/share/elasticsearch/data - Чиним права на Source‑каталог:
chown -R 1000:0 /home/es_index/data chmod -R u+rwX,g+rX,o-rwx /home/es_index/data docker restart es_port5418 docker logs -f es_port5418
Пользователь Elasticsearch в образе — uid 1000, поэтому владельцем data‑директории на хосте должен быть именно он.
Включить автозапуск контейнеров после ребута
Чтобы контейнеры автоматически стартовали после перезагрузки ВМ:
docker update --restart=always es_port5418 RabbitMQ paradedb portainer
Или в docker-compose.yml:
services:
elasticsearch:
restart: always
rabbitmq:
restart: always
# ...
Безопасно отцепить диск старой ВМ от новой
Когда убедились, что Docker на новой ВМ работает без зависимости от старого диска, его можно отцепить.
Внутри 8000:
umount /mnt/vm7000
На Proxmox‑хосте:
qm stop 8000
qm set 8000 --delete scsi1
qm start 8000
Старая ВМ 7000 и её диск больше не участвуют в проде. Их можно:
- либо оставить как холодный бэкап;
- либо, после ещё одного vzdump‑бэкапа, полностью удалить.