У меня есть программа на С++, работающая в док-контейнере. Я хочу перезагрузить контейнер через свою программу, но не могу.
Докерфайл:
FROM gcc
WORKDIR /client
COPY . .
RUN apt-get update && apt-get install qt5-qmake qtbase5-dev libmosquitto-dev -y
RUN qmake mainapp.pro && make
RUN chmod +x docker-entrypoint.sh
Докер-entrypoint.sh
#!/bin/bash
./mainapp -e
Вот моя функция перезагрузки (очищенная от ненужных кодов):
Logger::getInstance()->write(QString("Sync"));
sync();
Logger::getInstance()->write(QString("Setuid"));
setuid(0);
Logger::getInstance()->write(QString("RB_AUTOBOOT"));
reboot(RB_AUTOBOOT);
Logger::getInstance()->write(QString("Reboot"));
system("reboot");
Я вижу ВСЕ результаты, а затем печатает сообщение об ошибке. Вот сообщение об ошибке:
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Failed to talk to init daemon.
Я попытался перезагрузиться из контейнера, но это тоже не работает:
root@93501f6d7fc8:/client# reboot
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Failed to talk to init daemon.
root@93501f6d7fc8:/client# shutdown -r
System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down
Я искал эту проблему и пробовал большинство предложений, но они не решили мою проблему.
Я открыт для всех ваших идей и предложений.
Может быть, вы не знаете, чего хотите? Может быть, вы хотите сделать что-то вроде «перезапустить docker my_container» или «выйти» или что-то в этом роде?
Я хочу перезагрузить весь контейнер и снова запустить приложение.
Я не смогу запустить «контейнер перезапуска докеров». Доступ к этому приложению будет только с сообщениями MQTT. Я отправлю сообщение о перезагрузке через MQTT, а затем он должен перезапуститься.
Здесь может быть ответ: stackoverflow.com/questions/49713054/… (хотя похоже, что у него есть серьезные проблемы с безопасностью)
System("reboot") пытается использовать оболочку (которой может не быть в вашем док-контейнере) для запуска команды reboot (которой может не быть в вашем док-контейнере). Кроме того, «перезагрузка» не является четко определенным понятием. Вы не можете перезагрузить ядро, так как оно является общим. Docker-контейнер — это контейнер уровня приложения.
Чтобы перезапустить приложение и, соответственно, контейнер, просто используйте docker restart=always, а затем вызовите std::exit(0), чтобы выйти из приложения в обычном режиме.
Спасибо за ответы. Я добавил это в свой файл yaml для создания докеров:
privileged: true
restart: always
После этого reboot(RB_AUTOBOOT); перезагрузил мой контейнер и успешно запустил приложение.
Я ожидаю, что это перезагрузит весь хост. Это то, чего вы на самом деле хотите?
Да. Без «привилегированного» я не могу даже выполнить «перезагрузку» или «выключение» внутри контейнера.
Запуск Docker-контейнера — это просто набор процессов. Что вы хотите перезагрузить в наборе процессов?