Как запустить программу в контейнере как сервис с помощью systemd-nspawn, systemd-run?

Вопрос или проблема

Как запустить программу слушателя (в частности, unoconv в качестве слушателя) внутри контейнера с помощью systemd-nspawn, так чтобы она могла работать в фоновом режиме (без консоли) и была доступна другим процессам? Например, в идеальном мире это было бы так же просто:

# что-то подобное для запуска контейнера и программы в фоновом режиме
systemd-nspawn -D <путь к контейнеру> --background <unoconv --listener> 

# что-то подобное для подключения к контейнеру и выполнения команды
systemd-run --machine <имя машины> <unoconv -f pdf file.txt>

На данный момент я добрался только до использования Управление systemd-nspawn для запуска контейнеров, что позволяет запускать контейнер в фоновом режиме с machinectl. Однако,

sudo systemd-run --machine <имя машины> ls

не удается с ошибкой:

Не удалось создать соединение с шиной: Доступ запрещён.

У меня два вопроса. Во-первых, можете ли вы решить эту ошибку? Или, во-вторых (предпочтительнее), можете ли вы предложить более простой способ запуска и подключения к контейнеру и выполнения команд?

(Я запускаю Ubuntu Xenial на защищенной машине без доступа к интернету)

Я думаю, это зависит от того, как часто вы хотите запускать контейнер и когда.

Если это то, что вы хотите, чтобы запускалось каждый раз при загрузке Ubuntu, каждый раз при запуске компьютера, то я бы рекомендовал попробовать настройки Автозагрузка приложений. Вы можете добавить всё, что функционирует как команда терминала, в качестве процесса автозагрузки “приложения”. В качестве альтернативы, вы можете собрать скрипт, а затем запустить этот скрипт как процесс автозагрузки, что даст вам более тонкий контроль. (Учтите, что элементы в списке Автозагрузка приложений выполняются в алфавитном порядке по полю Имя, так что если порядок выполнения важен, либо назовите его соответственно, либо просто создайте стартовый скрипт и сделайте его единственным вызовом.)

Если вы хотите запустить программу в конкретное повторяющееся время/дату, я бы рекомендовал создать задачу cron для выполнения того же.

Если вы хотите запускать её по запросу… не уверен насчёт этого. Я не слишком знаком с systemd-nspawn; возможно, эта статья или эта статья помогут.

По первому вопросу я в затруднении. Ошибка в имени машины, возможно? Несоответствие между правами доступа контейнера и параметрами аутентификации systemd-run? Вы могли бы попробовать sshd или контейнер docker, если ничего другого не сработает.

Признаю, если вы на самом деле вводите это как “--machine <имя машины>“, изменение на “--machine=<имя машины>” может просто решить проблему. 😛

Ответ или решение

Запуск программы, такой как unoconv, в контейнере с использованием systemd-nspawn и systemd-run может показаться сложной задачей, особенно в условиях отсутствия интернет-доступа и специфических ограничений безопасности. В этом ответе мы рассмотрим шаги, необходимые для настройки контейнера и запуска вашей программы, а также разберем ваш текущий опыт и предложим пути решения возникших проблем.

Шаги для запуска приложения в контейнере с использованием systemd-nspawn и systemd-run

  1. Создание контейнера:
    Убедитесь, что у вас установлен пакет systemd-container, который предоставляет утилиты systemd-nspawn.

    sudo apt install systemd-container
  2. Настройка контейнера:
    Создайте директорию для вашего контейнера и установите в нее минимальную файловую систему. Например, можно использовать debootstrap:

    sudo debootstrap --variant=minbase xenial /var/lib/machines/my-container http://archive.ubuntu.com/ubuntu/
  3. Запуск контейнера с systemd-nspawn:
    Чтобы запустить unoconv в контейнере, необходимо сначала запустить сам контейнер в фоновом режиме. Для этого используйте:

    sudo systemd-nspawn -D /var/lib/machines/my-container --register=yes --network-bridge=mybridge --service=listener &

    Где --network-bridge=mybridge создает мост для сетевого взаимодействия, а --register=yes позволяет системе автоматически регистрировать контейнер.

  4. Запуск unoconv в контейнере:
    Для запуска unoconv в фоновом режиме внутри контейнера воспользуйтесь следующим образом:

    sudo systemd-run --machine=my-container /usr/bin/unoconv --listener

    Если вам нужно, чтобы unoconv работал как служба, рассмотрите вариант создания системного юнита для него.

  5. Работа с контейнером:
    Чтобы выполнять команды внутри контейнера, используйте systemd-run:

    sudo systemd-run --machine=my-container /usr/bin/unoconv -f pdf file.txt

Устранение ошибок и проблемы с подключением

Ваше сообщение об ошибке Failed to create bus connection: Permission denied может возникнуть по нескольким причинам. Вот некоторые из них и способы их устранения:

  1. Проблемы с правами доступа:
    Убедитесь, что вы используете команду с привилегиями суперпользователя (например, с sudo), так как systemd-run требует прав на создание подключения к bus.

  2. Правила безопасности:
    Если у вас включены ограничения AppArmor или SELinux, убедитесь, что они не блокируют подключение к системному шине пользователя (bus).

  3. Настройка имени машины:
    Убедитесь, что имя машины (machine name) корректно указано и совпадает с тем, что указано в конфигурации systemd-nspawn.

Альтернативные способы запуска контейнеров

Если указанные шаги вызывают сложности или вам нужно более гибкое решение, рассмотрите возможность использования Docker или LXD, которые также поддерживают работу с контейнерами и могут быть более интуитивными для пользователей, которые не знакомы с systemd-nspawn.

Заключение

Использование systemd-nspawn и systemd-run для работы с контейнерами представляет собой мощный инструмент, который позволяет эффективно управлять приложениями в изолированных средах. Однако важно учитывать все нюансы работы с системными службами и правами доступа. Если возникнут дополнительные сложности, всегда можно обратиться к документации systemd или специализированным форумам.

Оцените материал
Добавить комментарий

Капча загружается...