Как выключить хост (ubuntu) внутри контейнера докеров
Я хотел бы выключить машину (хост), когда контейнер докера завершит работу.
Моя основная ОС - Ubuntu.
Контейнер может работать как --privileged=true
. Это не проблема.
Мне удалось сделать это с помощью команды (найденной в ответе stackru):
subprocess.run("echo 1 > /proc/sys/kernel/sysrq; echo o > /proc/sysrq-trigger", shell=True, check=True)
Проблема с таким подходом - немедленное нечистое завершение работы Linux.
Если я попробую чистый путь как shutdown now
, Я получаю следующую ошибку: System has not been booted with systemd as init system (PID 1). Can't operate.
Как я могу использовать выключение, остановку или другую альтернативу в моем контейнере для выключения хоста?
2 ответа
Для вашего конкретного случая выполнить отключение после выхода из докера, решение Майки простое и элегантное.
В более общем случае, например, с набором докеризированных микросервисов, один из которых должен иметь возможность выключить или перезагрузить хост, можно использовать следующий подход:
В системах systemd, таких как недавние Debian или Ubuntu,
shutdown
//
poweroff
/
reboot
команды - это просто символические ссылки, и их можно запустить, например
systemctl halt
вместо того, чтобы просто
halt
.
Таким образом, проблема становится выполнять
systemctl
команды на хосте из док-контейнера. Этого можно добиться, сопоставив некоторые тома, как в следующей команде:
docker run -it --rm -v /bin/systemctl:/bin/systemctl -v /run/systemd/system:/run/systemd/system -v /var/run/dbus/system_bus_socket:/var/run/dbus/system_bus_socket -v /sys/fs/cgroup:/sys/fs/cgroup debian:10 systemctl --no-pager status
После сопоставления этих томов вы можете просто выполнить
systemctl poweroff
изнутри докера, и хост выключится и отключится.
Если я не пропущу неуказанное ограничение, я не понимаю, почему вы не могли сделать это на хосте из оболочки:
docker run image_name; shutdown now
Это потребовало бы, чтобы Dockerfile заканчивался на CMD
или ENTRYPOINT
команда, указывающая сценарий.
Как только сценарий в контейнере завершится, процесс запуска докера завершится, и оболочка может перейти к следующей команде, которая shutdown now
.