nie udało się uzyskać połączenia D-Bus: Operacja niedozwolona


29

Próbuję wyświetlić listę usług na moim obrazie CentOS uruchomionym w Dockerze przy użyciu

systemctl list-units  

ale pojawia się ten komunikat o błędzie:

Failed to get D-Bus connection: Operation not permitted

Wszelkie sugestie na temat problemu?


1
Nie używałeś sudo?
— Michael Hampton

Nie powinieneś używać systemd, jeśli go nie potrzebujesz. Spróbuj uruchomić aplikację bez użycia CMD lub RUN, lub użyj skryptu opakowania.
— nelaaro,

Jeśli potrzebujesz systemdna CentOS, użyj tego obrazu: FROM centos/systemd
— james.garriss

Odpowiedzi:


24

Domyślam się, że prowadzisz non-privilegedkontener. systemd wymaga zdolności CAP_SYS_ADMIN, ale Docker upuszcza tę możliwość w nieuprzywilejowanych kontenerach, aby zwiększyć bezpieczeństwo.

systemd wymaga również dostępu RO do systemu plików cgroup w kontenerze. Możesz to dodać za pomocą–v /sys/fs/cgroup:/sys/fs/cgroup:ro

Oto kilka kroków, jak uruchomić CentOS z systemd wewnątrz kontenera Docker:

  1. Wyciągnij obraz centos
  2. Skonfiguruj plik dokera, taki jak ten poniżej:
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. Zbuduj to - docker build --rm -t centos7-systemd - < mydockerfile
  2. Uruchom kontener z docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. Powinieneś mieć system w swoim kontenerze


Całkiem schludnie! Przynajmniej teraz otrzymuję więcej informacji. Oto, co mnie zaloguje:[ INFO ] Update UTMP about System Boot/Shutdown is not active. [DEPEND] Dependency failed for Update UTMP about System Runlevel Changes. Job systemd-update-utmp-runlevel.service/start failed with result 'dependency'. [ OK ] Started Journal Service. [ OK ] Reached target System Initialization. [ OK ] Reached target Timers. [ OK ] Listening on D-Bus System Message Bus Socket.
— Snowcrash,

1
W przypadku gdybym nie był jasny! Nadal Failed to get D-Bus connection: Operation not permitted
— pojawia się

Zbudowałeś własny obraz z pliku Docker skopiowanego w mojej odpowiedzi, uruchamiasz kontener z tego obrazu i nadal pojawia się błąd?
— 13dimitar

4
Bingo! Uruchomiłem kontener /bin/bash, aby uzyskać powłokę. Dało mi to jednak wspomniany wcześniej błąd. Kiedy uruchomiłem go /usr/sbin/initzgodnie z sugestią, a następnie przymocowałem do skorupy wszystko poszło dobrze. Najwyraźniej brakuje mi niuansu na temat /usr/sbin/init. Ta odpowiedź zasługuje na znaczną poprawę.
— Snowcrash

Pracuję nad tym od 2 dni i nadal nie mogę się dowiedzieć, co to /sys/fs/cgroup:/sys/fs/cgroupjest i skąd pochodzi ... Wiem, jak zamontować folder gościa w taki sposób: /src/:/var/wwwale skąd pochodzi twój plik? Powoduje to wiele błędów, ponieważ
— wkleiłem

4

To nie jest bezpośrednia odpowiedź na twoje pytanie, ale w rzeczywistości może być ważniejsza i natknąłem się na to, czytając inne odpowiedzi tutaj.

Miałem trochę doświadczenia z migracją skomplikowanych systemów do Dockera, a jedną z ważniejszych realizacji, jakie miałem, jest to, że najlepiej mieć jeden kontener Docker na aplikację / usługę lub „na demona”.

Jednym z bardzo ważnych powodów jest to, że Docker nie zamknie czysto usług, które rozpoczynasz od systemctl aw rzeczywistości może dojść do tego samego rodzaju uszkodzeń bazy danych, które wynikają z nieoczekiwanego zaniku zasilania.

Aby zagłębić się w to nieco głębiej: kiedy Docker wydaje polecenie „stop” do kontenera, wysyła sygnał SIGTERM tylko jeden proces rozpoczęty za pomocą CMD / ENTRYPOINT, a nie do wszystkich usług i demonów. Tak więc jedna usługa ma ostrzeżenie, aby zamknąć w sposób czysty, a wszystkie pozostałe zostają bezceremonialnie zakończone.

Jeśli absolutnie musisz spakować dwie usługi w tym samym kontenerze (tj. Twoją aplikację i bazę danych PostgreSQL lub coś w tym rodzaju), musisz mieć CMD / ENTRYPOINT jako skrypt, który łapie SIGTERM, a następnie ponownie nadaje go do tych znanych usług. Można to zrobić, ale jeśli masz okazję, ponownie przemyśl swoje rozwiązanie i spróbuj rozbić je na wiele pojemników.

Dodatek

Na stronie Docker znajduje się interesująca notatka / strona o używaniu superwizora, jeśli absolutnie potrzebujesz mieć wiele usług działających w tym samym kontenerze.


2

Udało mi się naprawić ten problem w kontenerze dokującym CentOS: 7. Śledziłem głównie Przewodnik po projekcie obrazu 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"]

Teraz skompiluj obraz i uruchom go, używając przynajmniej następujących argumentów docker run:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Zatem głównym punktem jest to, że /usr/sbin/initmusi to być pierwszy proces w kontenerze Docker.

Jeśli więc chcesz użyć niestandardowego skryptu, który wykonuje niektóre polecenia przed uruchomieniem /usr/sbin/init, uruchom go na końcu skryptu za pomocą exec /usr/sbin/init(w skrypcie bash).

Oto przykład:

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

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

A oto treść 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

Można mieć System is booting up. See pam_nologin(8), jeśli używasz systemu PAM, w takim przypadku należy usunąć /usr/lib/tmpfiles.d/systemd-nologin.confw twojej Dockerfileponieważ tworzy plik /var/run/nologin, który generuje ten konkretny błąd.


systemd-nologin.conf/ nologinza wygraną, ponieważ roszczenia CentOS / RHEL 7 UsePAM nonie są obsługiwane i będą narzekać na dzienniki jako takie. Nie jestem pewien, czy RH openssh portable załatał / zepsuł się w jakiś sposób, czy starają się obniżyć powierzchnię wsparcia od początkujących klientów.

1

Nie chciałem uruchamiać systemd jako init / PID 1. Po wykonaniu kroków czyszczenia wspomnianych przez innych, uruchamiam systemd ze skryptu startowego as /usr/lib/systemd/systemd --system &.

To pozwoliło systemd na uruchomienie i uruchomienie zarejestrowanych usług, ale systemctl zawiódł z powodu błędu D-Bus.

Dla mnie brakującym linkiem był brak katalogu / run / systemd / system, który odkryłem, wprowadzając stracesystemctl.

Ręczne utworzenie tego katalogu przed uruchomieniem systemctl pozwala systemctl pracować dla mnie.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.