Не удалось установить соединение D-Bus: соединение отклонено [дубликат]

Я пытаюсь перечислить службы в моем образе CentOS, запущенном в Docker, используя

systemctl list-units  

, но я получите это сообщение об ошибке:

Failed to get D-Bus connection: Operation not permitted

Есть предложения, в чем может быть проблема?

56
задан 21 June 2017 в 01:20
4 ответа

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

systemd также требует доступа RO к файловой системе cgroup внутри контейнера. Вы можете добавить его с помощью –v / sys / fs / cgroup: / sys / fs / cgroup: ro

Итак, вот несколько шагов по запуску CentOS с systemd внутри контейнера Docker:

  1. Pull centos image
  2. Создайте файл докера, как показано ниже:
FROM centos
MAINTAINER "Yourname" <youremail@address.com>
ENV container docker
RUN yum -y update; yum clean all
RUN yum -y install systemd; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
  1. Создайте его - сборка докера --rm -t centos7-systemd -
  2. Запустите контейнер с запуском докера - -privileged -ti -e container = docker -v / sys / fs / cgroup: / sys / fs / cgroup centos7-systemd / usr / sbin / init

  3. У вас должен быть systemd в вашем контейнере

39
ответ дан 4 January 2021 в 09:06

Мне удалось исправить эту проблему в контейнере CentOS: 7 Docker. В основном я следовал Руководству по проекту образа CentOS Docker .

FROM centos:7

ENV container docker
RUN (cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == \
systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;

# Install anything. The service you want to start must be a SystemD service.

CMD ["/usr/sbin/init"]

Теперь создайте образ и запустите его, используя по крайней мере следующие аргументы команды docker run : -v / run -v / sys / fs / cgroup: / sys / fs / cgroup: ro

Главное здесь то, что / usr / sbin / init должен быть первым процессом внутри Docker контейнер.

Итак, если вы хотите использовать собственный сценарий, который выполняет некоторые команды перед запуском / usr / sbin / init , запустите его в конце вашего сценария, используя exec / usr / sbin / init (в сценарии bash).

Вот пример:

ADD cmd.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/cmd.sh

CMD ["/usr/local/bin/cmd.sh"]

А вот содержимое cmd.sh :

#!/bin/bash

# Do some stuffs

exec /usr/sbin/init # To correctly start D-Bus thanks to https://forums.docker.com/t/any-simple-and-safe-way-to-start-services-on-centos7-systemd/5695/8

Вы могли бы Система загружается . См. Pam_nologin (8) , если вы используете систему PAM, в этом случае удалите /usr/lib/tmpfiles.d/systemd-nologin.conf в своем Dockerfile , потому что он создает файл / var / run / nologin , который генерирует эту конкретную ошибку.

8
ответ дан 4 January 2021 в 09:06

Это не Это прямой ответ на ваш вопрос, но на самом деле он может быть более важным, и я понял это, когда читал другие ответы здесь.

У меня был некоторый опыт миграции некоторых сложных систем на Docker, а еще одну из важных реалий, которые у меня были, это то, что в идеале у вас должен быть один контейнер Docker на приложение / службу или «на демона».

Одна очень важная причина этого заключается в том, что Docker не будет полностью завершать запускаемые вами службы с systemctl , и на самом деле вы можете столкнуться с такими же повреждениями базы данных, которые возникают из-за непредвиденного отключения электроэнергии.

Чтобы погрузиться в это немного глубже: когда Docker выдает команду «остановить» контейнеру, он отправляет сигнал SIGTERM только одному процессу, который был запущен с помощью CMD / ENTRYPOINT, а не всем службам и d эмоны. Чтобы одна служба имела предупреждение о полном завершении работы, а все остальные были бесцеремонно завершены.

Если вам абсолютно необходимо упаковать две службы в один и тот же контейнер (т.е. ваше приложение и базу данных PostgreSQL или что-то в этом роде), вам необходимо пусть ваш CMD / ENTRYPOINT будет сценарием, который улавливает SIGTERM и затем ретранслирует его в эти известные службы. Это можно сделать, но если у вас есть возможность, переосмыслите свое решение и попробуйте разбить его на несколько контейнеров.

Приложение

На сайте Docker есть интересная заметка / страница об использовании supervisord, если вам абсолютно необходимо, чтобы несколько служб работали в одном контейнере.

9
ответ дан 4 January 2021 в 09:06

Я не хотел запускать systemd как init / PID 1. После выполнения шагов очистки, упомянутых другими, я запускаю systemd из сценария запуска как / usr / lib / systemd / systemd --system & .

Это позволило systemd запускать и запускать зарегистрированные службы, но systemctl выдает ошибку D-Bus.

Для меня отсутствующим звеном было отсутствие каталога / run / systemd / system, это обнаружил strace ing systemctl.

Создание этого каталога вручную перед запуском systemctl позволяет systemctl работать на меня.

2
ответ дан 4 January 2021 в 09:06

Теги

Похожие вопросы