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?

Snowcrash
źródło
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" <[email protected]>
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

13dimitar
źródło
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.

Murray Todd Williams
źródło
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.

Anthony O.
źródło
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.

Chaim Geretz
źródło