impossibile ottenere la connessione D-Bus: operazione non consentita


29

Sto cercando di elencare i servizi sulla mia immagine CentOS in esecuzione in Docker utilizzando

systemctl list-units  

ma ricevo questo messaggio di errore:

Failed to get D-Bus connection: Operation not permitted

Qualche suggerimento quale potrebbe essere il problema?


1
Non hai usato sudo?
Michael Hampton

Non dovresti usare systemd, se non ti serve. Prova ad avviare l'applicazione senza che sia presente in CMD o RUN o utilizzando uno script wrapper.
nelaaro,

Se hai bisogno systemdsu CentOS, usa questa immagine: FROM centos/systemd
james.garriss il

Risposte:


24

La mia ipotesi è che stai gestendo un non-privilegedcontainer. systemd richiede la funzionalità CAP_SYS_ADMIN ma Docker rilascia tale funzionalità nei contenitori non privilegiati, al fine di aggiungere maggiore sicurezza.

systemd richiede anche l'accesso RO al file system cgroup all'interno di un contenitore. Puoi aggiungerlo con–v /sys/fs/cgroup:/sys/fs/cgroup:ro

Quindi, ecco alcuni passaggi su come eseguire CentOS con systemd all'interno di un contenitore Docker:

  1. Pull centos image
  2. Imposta un file docker come quello qui sotto:
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. Costruiscilo - docker build --rm -t centos7-systemd - < mydockerfile
  2. Esegui un contenitore con docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. Dovresti avere systemd nel tuo contenitore


Piuttosto pulito! Tuttavia, almeno adesso sto ricevendo ulteriori informazioni. Ecco cosa mi viene registrato:[ 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
Nel caso non fossi chiaro! Ricevo ancora l'erroreFailed to get D-Bus connection: Operation not permitted
Snowcrash

Hai creato la tua immagine dal Dockerfile copiato nella mia risposta, esegui un contenitore da quell'immagine e ricevi ancora un errore?
dicembre,

4
Bingo! Stavo facendo funzionare il container /bin/bashper ottenere una shell. Tuttavia, questo mi ha dato l'errore menzionato in precedenza. Quando l'ho eseguito /usr/sbin/initcome suggerito, quindi attaccato con una shell tutto è andato bene. Chiaramente mi manca una sfumatura /usr/sbin/init. Questa risposta merita un sostanziale apprezzamento.
Snowcrash,

Sono stato su questo per 2 giorni, e non riesco ancora a capire da che cosa /sys/fs/cgroup:/sys/fs/cgroupprovenga o da dove provenga ... So come montare la cartella guest in modo che sia: /src/:/var/wwwma da dove proviene il tuo file? Mi sta causando molti errori perché ho incollato il codice, sto pensando che dovrei crearli da qualche parte
samayo,

4

Questa non è una risposta diretta alla tua domanda, ma in realtà potrebbe essere più importante e mi sono imbattuto in questa realizzazione mentre leggevo le altre risposte qui.

Ho avuto esperienza nella migrazione di alcuni sistemi complicati su Docker e una delle realizzazioni significative che ho avuto è che dovresti idealmente avere un contenitore Docker per applicazione / servizio o "per demone".

Una ragione molto significativa per questo è che Docker non arresterà in modo pulito i servizi che si avvia con systemctl e in effetti si potrebbe finire con lo stesso tipo di corruzioni del database che derivano da un'interruzione di corrente imprevista.

Per approfondire un po 'più a fondo: quando Docker invia un comando "stop" a un container, invia il segnale SIGTERM solo al singolo processo avviato con CMD / ENTRYPOINT, non a tutti i servizi e demoni. In modo che un servizio abbia l'avvertimento di chiudere in modo pulito e tutti gli altri vengano terminati senza tante cerimonie.

Se devi assolutamente impacchettare due servizi nello stesso contenitore (ad es. La tua applicazione e un database PostgreSQL o qualcosa del genere), devi avere CMD / ENTRYPOINT come uno script che cattura SIGTERM e lo reindirizza a quei servizi noti. Può essere fatto, ma se ne hai la possibilità, ripensare la soluzione e provare a suddividerla in più contenitori.

Un addendum

C'è una nota / pagina interessante sul sito Docker sull'uso di supervisord se hai assolutamente bisogno di avere più servizi in esecuzione nello stesso contenitore.


2

Sono riuscito a risolvere questo problema in un contenitore DockOS CentOS: 7. Ho seguito principalmente la Guida al progetto di immagine Docker di CentOS .

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"]

Ora, crea l'immagine ed eseguila usando almeno i seguenti argomenti per docker runcomandare:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Quindi il punto principale è che /usr/sbin/initdeve essere il primo processo all'interno del contenitore Docker.

Quindi, se si desidera utilizzare uno script personalizzato che esegue alcuni comandi prima dell'esecuzione /usr/sbin/init, avviarlo alla fine dello script utilizzando exec /usr/sbin/init(in uno script bash).

Ecco un esempio:

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

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

Ed ecco il contenuto di 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

Si potrebbe avere System is booting up. See pam_nologin(8)se si utilizza il sistema PAM, in tal caso, eliminare /usr/lib/tmpfiles.d/systemd-nologin.confnel proprio Dockerfileperché crea il file /var/run/nologinche genera questo errore specifico.


systemd-nologin.conf/ nologinper la vittoria perché CentOS / RHEL 7 UsePAM nonon è supportato e si lamenterà nei registri in quanto tali. Non sono sicuro se RH openssh sia stato riparato / rotto in qualche modo portatile o se stiano cercando di abbassare la superficie di supporto dei clienti inesperti.

1

Non volevo avviare systemd come init / PID 1. Dopo aver eseguito i passaggi di pulizia menzionati da altri, lancio systemd da uno script di avvio come /usr/lib/systemd/systemd --system &.

Ciò ha permesso a systemd di avviare e avviare i servizi registrati, ma systemctl non riusciva con l'errore D-Bus.

Per me, il collegamento mancante era l'assenza della directory / run / systemd / system, scoperta da straceingctctctl.

La creazione manuale di questa directory prima di eseguire systemctl consente a systemctl di funzionare per me.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.