Вопрос или проблема
Я установил LXD в Ubuntu через Snap Store и затем подключил его к клиенту Windows, но для того, чтобы запускать контейнеры из Windows, приложение Ubuntu должно быть открыто. Есть ли способ запустить сервер LXD в фоновом режиме или мне придется держать Ubuntu открытой, чтобы это работало?
wsl --status
возвращает:
Default Distribution: Ubuntu
Default Version: 2
wsl --version
возвращает:
WSL version: 0.70.0.0
Kernel version: 5.15.68.1
WSLg version: 1.0.45
MSRDC version: 1.2.3575
Direct3D version: 1.606.4
DXCore version: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows version: 10.0.22000.1098
и cmd /c ver
возвращает:
Microsoft Windows [Version 10.0.22000.1098]
Это, честно говоря, замечательный вопрос, поскольку я осознал это, пройдя через различные сценарии ниже. В том, как работает WSL, я вынужден согласиться, есть некая путаница. Существует ряд “проблем”, связанных с этим, на репозитории WSL на GitHub, но реальность такова, что это поведение “преднамеренно”.
Также важно отметить, что с этими изменениями службы systemd НЕ будут поддерживать вашу WSL-инстанцию в активном состоянии. Ваша WSL-инстанция будет оставаться активной так же, как и раньше, о чем вы можете [узнать подробнее здесь](https://devblogs.microsoft.com/commandline/background-task-support-in-wsl/).
Другими словами, WSL разработан так, чтобы завершать Ubuntu в определенных ситуациях, но связанное сообщение не совсем ясно, что это за сценарии. Чтобы лучше понять их (и как ведет себя WSL), давайте начнем с (по крайней мере) четырех различных способов, как вы можете запустить фоновую задачу или службу (также известную как демон) в Ubuntu на WSL:
-
Интерактивно, из командной строки через саму команду или с помощью вспомогательной программы
service
. Например:sudo service cron start # или даже sudo /usr/sbin/cron
Это, конечно, будет работать на любой версии WSL, но SysVInit
service
может работать только для определенных дистрибутивов (таких как Ubuntu) и служб.(Важно) обратите внимание, что команды, выполняемые внутри сценариев запуска вашего шелла, считаются “интерактивными” для этой цели. Это пригодится в моем окончательном (не очень аккуратном) решении.
-
Интерактивно, как фоновая задача из шелла. Например:
nohup sleep 100000 &
-
В Windows 11 вы можете автоматически запустить демон при запуске WSL через
/etc/wsl.conf
. Например:[boot] command = service cron start
-
И начиная с WSL 0.67.6, используя Systemd. Это может происходить либо интерактивно (
sudo systemctl cron start
), автоматически через ссылки/etc/systemd
, либо как зависимость другой службы. Например:sudo systemctl cron start
Обратите внимание, что демон Snap (
snapd
) запускается автоматически через Systemd, как только он включен в WSL.
С учетом этих сценариев, мы должны рассмотреть когда WSL завершит Ubuntu. Как я уже говорил, это “путаница”. Мне бы хотелось сформулировать резюме, чтобы описать поведение, но мне это дается с трудом. Лучшее, что я могу сделать, это привести примеры:
Резюме
- Не завершит
- Не завершит
- Завершит
- Завершит
Детали и примеры
-
Служба, запущенная интерактивно через командную строку, предотвратит завершение Ubuntu WSL. Мы можем продемонстрировать это следующим образом:
- Временно отключив Systemd в
/etc/wsl.conf
- Выйдя из Ubuntu
- Запустив PowerShell
wsl --shutdown
- Перезапустив Ubuntu через
wsl ~
(если нужно,wsl ~ -d Ubuntu-22.04
и т. д.) sudo service cron start
- Выйдя из шелла
- Подождав минуту (25 секунд по умолчанию, этого должно быть достаточно) и проверив
wsl -l -v
, чтобы показать, что Ubuntu все еще находится в состоянии Работающие. wsl -e ps axjff
должно показать, чтоcron
все еще работает, даже если ни один шелл не работает.
- Временно отключив Systemd в
-
Фоновая задача, запущенная интерактивно через командную строку, также предотвратит завершение Ubuntu WSL. Следуя предыдущему примеру:
- При отключенном Systemd, из PowerShell,
wsl --shutdown
- Запустите Ubuntu (например,
wsl ~
) - Выполните
nohup sleep 100000 &
- Нажмите Enter один раз дополнительно, чтобы закрыть сообщение
nohup
- Выйдите из шелла/Ubuntu обратно в PowerShell.
- Подождите 30 секунд до минуты и выполните
wsl -l -v
, чтобы показать, что Ubuntu все еще работает. wsl -e ps axjff
должно показать, что командаsleep
все еще работает, даже если ни один шелл не работает.
- При отключенном Systemd, из PowerShell,
-
Служба/процесс, запущенный через
/etc/wsl.conf
, с другой стороны, не предотвратит завершение Ubuntu WSL.-
Начинаем с предыдущего примера (Systemd отключен)
-
В Ubuntu выполните
sudo -e /etc/wsl.conf
и добавьте следующее:[boot] command = service cron start
-
Выйдите из Ubuntu и из PowerShell выполните
wsl --shutdown
-
Перезапустите Ubuntu через
wsl ~
-
ps axjff
покажет, чтоcron
работает как подсистема одного из/init
родительских процессов. -
Выйдите из шелла/Ubuntu
-
Через 30 секунд до минуты
wsl -l -v
покажет, что Ubuntu больше не работает. Она была завершена.
-
-
Служба/процесс, запущенный через Systemd, также не позволит WSL завершить Ubuntu. Демонстрация (хотя вы уже это переживаете):
-
Отредактируйте
/etc/wsl.conf
и повторно включите Systemd, отключив (закомментировав или удалив)command
. -
Выйдите из Ubuntu
-
В PowerShell выполните
wsl --shutdown
-
wsl ~
для запуска Ubuntu. -
ps axjff
покажет, что службы Systemd запущены и/или запускаются. -
Через минуту:
sudo systemctl stop cron sudo systemctl start cron
Это, очевидно, имеет эффект простого остановки cron, а затем его перезапуска. Суть в том, чтобы показать, что даже если мы явно запустили
cron
интерактивно, это не предотвратит завершение Ubuntu WSL. -
Выйдите из шелла/Ubuntu
-
Через 30 секунд до минуты
wsl -l -v
покажет, что Ubuntu была Остановлена.
Что касается вашего конкретного вопроса, поскольку
lxd
– это просто Snap, который работает в контейнеризированной среде, запущенной Systemd, он также завершается. Вот так, к сожалению … -
Решение
Надеюсь, вскоре будет более постоянное решение, так как один из разработчиков WSL действительно выразил желание поддерживать работающие дистрибутивы.
Тем временем решение (и, конечно, может быть больше) заключается в том, чтобы запустить длительный процесс через ваши файлы запуска оболочки. В моем случае я обычно использую keychain
.
Есть несколько особенностей Keychain, которые позволяют ему хорошо работать в этом случае:
- Он доступен в стандартных репозиториях Ubuntu
- Он уже запускает единичный экземпляр
ssh-agent
. Другими словами, еслиssh-agent
уже работает, он прикрепляется к нему, а не запускает новый. - Он может работать тихо и без взаимодействия, если ключи не добавляются
Чтобы настроить это:
sudo apt update && sudo apt install keychain -y
sudo -e /etc/profile.d/keep_wsl_running.sh
И добавьте следующее:
#!/usr/bin/env sh
eval $(keychain -q)
Этот скрипт:
-
Запускается, когда вы запускаете свою оболочку (предполагая, что это большинство оболочек, таких как Bash и Zsh). Обратите внимание, что он не сработает, если вы используете Fish в качестве своей оболочки. Если вы (или любой будущий читатель) хотите использовать Fish (или другую оболочку, которая не обрабатывает
/etc/profile.d
), задайте отдельный вопрос о том, как обработать этот сценарий. У меня есть решение, но этот ответ (как обычно) уже достаточно длинный ;-). -
Оценивает вывод
keychain
, чтобы найти любой существующийssh-agent
(или запустить новый, если не найден) и установить переменные окружения для оболочки, чтобы они указывали на него. -
-q
, как вы, вероятно, уже догадались, просто запускаетkeychain
тихо, без вывода
Наличие работающего ssh-agent
(который был запущен через /etc/profile.d
) предотвратит завершение дистрибутива/инстанции/контейнера Ubuntu WSL. Ubuntu будет продолжать работать после закрытия окна терминала, и ваш lxd
(и другие демоны/службы, установленные Snap) также останутся активными.
Чтобы позволить Ubuntu завершиться корректно, просто избавьтесь от ssh-agent
. Это можно сделать несколькими способами, в том числе:
keychain -k all
Конечно, убедитесь, что все другие службы, которые вы запускали интерактивно, также отсутствуют. Как только это условие будет выполнено, WSL корректно завершит Systemd и его юниты/службы.
Есть один крайний случай, и это когда вы начнете сессию wsl -u root
. В этом случае ssh-agent
также будет запущен от имени root, и вам нужно будет выполнить sudo keychain -k all
.
Запустите этот vbs-скрипт при запуске Windows. Просто положите его в папку автозагрузки Windows (crl+r -> shell:startup
)
wsl-startup.vbs:
# измените '<Distro>' на название используемого вами дистрибутива.
set ws=wscript.CreateObject("wscript.shell")
ws.run "wsl -d <Distro>", 0
источник: https://github.com/microsoft/WSL/issues/8854#issuecomment-1421910739
После этого каждый раз, когда вы запускаете свой компьютер и входите в систему, он будет запускать wsl и ждать ввода. Экземпляр wsl будет оставаться активным.
Затем вы можете использовать systemd, чтобы запускать что угодно в фоновом режиме.
Не забудьте снова запустить vbs, если вы вручную перезапустите экземпляр wsl с помощью wsl -t <distro> / wsl --shutdown
обновление 2024/10/25:
Или вы можете просто добавить это в ~/.bashrc
if ! ps a | grep '[s]leep 1h' > /dev/null; then
nohup sleep 1h > /dev/null 2>&1 &
fi
Измените время сна по вашему желанию. Когда есть процесс сна, WSL будет продолжать работать.
Ответ или решение
Вопрос: Возможно ли запускать приложение WSL в фоновом режиме?
С учетом того, что вы установили LXD на Ubuntu и подключили его к клиенту Windows, становится очевидным, что вопрос о том, может ли сервер LXD работать в фоновом режиме без активного окна Ubuntu, – это важный аспект для обеспечения непрерывной работы контейнеров. Ваша текущая версия WSL и другие конфигурации значительно влияют на это.
Основы работы WSL
WSL (Windows Subsystem for Linux) обеспечивает совместимость операций Linux непосредственно в Windows, но его поведение в контексте фоновых процессов и служб требует понимания. Согласно последним изменениям в WSL, включая поддержку systemd, становится понятно, что службы, запущенные в WSL, не будут поддерживать активное состояние дистрибутива, если окно терминала будет закрыто.
Как работают фоновые процессы в WSL
В WSL есть несколько способов запуска фоновых задач, но ключевым аспектом является то, что не все из них сохраняют состояние дистрибутива. Рассмотрим некоторые способы:
-
Интерактивный запуск из командной строки:
Команда, запущенная в терминале, будет удерживать WSL активной, пока эта команда выполняется.sudo service cron start
-
Запуск фонового процесса:
Можно использоватьnohup
для запуска задачи в фоновом режиме, и это также будет удерживать WSL активной:nohup sleep 100000 &
-
Автоматический запуск служб через
wsl.conf
:
Настройка вwsl.conf
может не удерживать состояние WSL активным, поскольку такие команды исполняются лишь при инициализации дистрибутива и не препятствуют его завершению.[boot] command = service cron start
-
Использование systemd:
Службы, запущенные через systemd, также не предотвращают завершение работы WSL после закрытия терминала.
Поведение WSL при завершении
Важно понимать, что WSL имеет свои условия, когда он закрывает дистрибутив:
- Если была выполнена интерактивная команда или фоновая задача из терминала, то WSL останется активным.
- Если службы были запущены через
wsl.conf
или systemd, WSL может быть завершен после закрытия терминала.
Решение проблемы: как запустить WSL в фоновом режиме
Для обеспечения постоянной работы вашего LXD-сервера и других сервисов в WSL можно использовать несколько методов:
-
Применение
Systemd
:
Вы можете активироватьsystemd
в вашем дистрибутиве. Это позволит управлять службами более эффективно. -
Использование VBS-скрипта:
Написание VBS-скрипта для автоматического запуска WSL при старте Windows:set ws=wscript.CreateObject("wscript.shell") ws.run "wsl -d Ubuntu", 0
Сохраните скрипт в папке автозагрузки Windows, чтобы запускать WSL при каждом входе в систему.
-
~/.bashrc
для удержания WSL:
Добавьте проверку и команду в~/.bashrc
, чтобы запускатьsleep
, это будет удерживать экземпляр WSL активным.if ! ps a | grep '[s]leep 1h' > /dev/null; then nohup sleep 1h > /dev/null 2>&1 & fi
Заключение
Ваша конкретная конфигурация и способ выполнения команд имеют решающее значение для работы LXD и других служб в фоновом режиме. Использование различных методов для удержания дистрибутивов WSL активными поможет вам избежать необходимости держать окно Ubuntu открытым. Применяйте предложенные решения, чтобы оптимизировать работу ваших контейнеров и приложений под управлением WSL.