Вопрос или проблема
Я пытаюсь запустить контейнер Docker с systemd в качестве процесса инициализации, чтобы запускать несколько сервисов из этого контейнера, и получаю следующую странную ошибку:
Systemd указан как PID 1, когда я запускаю top, но ни один из сервисов, которые я включил через systemctl, не работает, и попытка проверить их статус через systemctl вызывает сообщение system has not been booted with systemd as init process (PID 1)
Вот мой dockerfile:
FROM ubuntu:20.04
ENV container docker
ENV LC_ALL C
ENV DEBIAN_FRONTEND noninteractive
RUN sed -i 's/# deb/deb/g' /etc/apt/sources.list
RUN apt-get update \
&& apt-get install -y systemd systemd-sysv \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
RUN cd /lib/systemd/system/sysinit.target.wants/ \
&& ls | grep -v systemd-tmpfiles-setup | xargs rm -f $1
RUN rm -f /lib/systemd/system/multi-user.target.wants/* \
/etc/systemd/system/*.wants/* \
/lib/systemd/system/local-fs.target.wants/* \
/lib/systemd/system/sockets.target.wants/*udev* \
/lib/systemd/system/sockets.target.wants/*initctl* \
/lib/systemd/system/basic.target.wants/* \
/lib/systemd/system/anaconda.target.wants/* \
/lib/systemd/system/plymouth* \
/lib/systemd/system/systemd-update-utmp*
... assorted aptget installs ...
ENV LOCAL="yes"
... assorted utils scripts ...
RUN useradd --create-home fractal \
&& usermod -aG sudo fractal \
&& echo 'fractal:password1234567.' | chpasswd
... assorted utils scripts ...
ADD bootstrap.sh /home/fractal
ADD entry.sh /home/fractal
ADD fractal-input.rules home/fractal
RUN chmod +x /home/fractal/bootstrap.sh \
&& chown -v -R fractal:fractal /home/fractal
RUN chown root:root /run/user
RUN chmod +x /home/fractal/entry.sh
... adding assorted services ...
VOLUME [ "/sys/fs/cgroup" ]
RUN systemctl set-default multi-user.target
ENV init /lib/systemd/systemd
... assorted services enabled ...
CMD ["/lib/systemd/systemd"]
Вы не можете использовать systemd в контейнере Docker без значительных усилий. Большинство людей используют что-то вроде supervisord вместо этого.
Ответ или решение
Использование systemd внутри контейнера Docker — это достаточно сложная задача, требующая детального подхода и дополнительных настроек, поскольку Docker по своей природе не поддерживает его в полном объеме. Однако, если ваша задача заключается в том, чтобы реализовать многосервисное окружение внутри Docker-контейнера и использовать systemd как init-процесс, рекомендуется рассмотреть следующие аспекты:
Контекст и подготовка
-
Основа проблемы: Ваша ошибка, заключающаяся в сообщении "system has not been booted with systemd as init process (PID 1)", свидетельствует о том, что, хоть systemd и запускается в контейнере (как показывает
top
), он не работает должным образом. Это может быть связано с тем, что контейнер не запущен с соответствующими правами или важные компоненты системы не монтированы. -
Ограничения Docker: Docker контейнеры задуманы как изолированные процессы, а не виртуализированные машины, поэтому многие функции, такие как key socket аспектов systemd, могут быть отключены по умолчанию.
Пошаговое решение
-
Подготовка Host-системы:
- Убедитесь, что ваш Docker-демон настроен так, чтобы выполнять команды с соответствующими привилегиями, необходимыми для монтирования cgroup.
-
Обновление Dockerfile:
- Ваш Dockerfile должен предусматривать объемы для /sys/fs/cgroup и дополнительные опции запуска контейнера.
- Прописать сервисы в отдельные слои для упрощения отладки.
-
Запуск контейнера:
- Используйте следующее команду для запуска контейнера:
docker run --privileged -v /sys/fs/cgroup:/sys/fs/cgroup:ro -itd your-image-name
Здесь
--privileged
необходим для предоставления более широких привилегий, а монтирование/sys/fs/cgroup
обеспечивают скрытые зависимости systemd.
- Используйте следующее команду для запуска контейнера:
-
Проверка и отладка:
- Убедитесь, что все необходимые зависимости находятся в порядке, и доступ к z обеспечивает systemd корректную работу.
-
Рассмотрите альтернативы:
- Если сложности с systemd преобладают, Supervisor может служить отличной альтернативой, предоставляя гибкое управление процессами.
SEO Оптимизация
- Ключевые слова: Docker, systemd, Ubuntu контейнер, несколько сервисов, отладка.
- Описание: Использование systemd в Docker, как обойти ограничения Docker, управление многосервисной архитектурой.
- Заголовок статьи: Как правильно использовать systemd в контейнере Docker на базе Ubuntu: пошаговое руководство.
Заключение
Несмотря на то, что использование systemd внутри Docker-контейнеров требует значительных усилий и понимания архитектурных особенностей обеих технологий, соблюдение данных рекомендаций поможет вам настроить многосервисное окружение. Всегда имейте в виду, что Docker больше предназначен для развертывания отдельных служб, а не в качестве полноценной замены виртуальной машины. Если ваши требования не могут быть удовлетворены существующим окружением, возможно, стоит пересмотреть архитектурное решение в сторону контейнерных оркестраторов или гипервизоров.