75 votes

échec de la connexion D-Bus : Opération non autorisée

J'essaie de répertorier les services de mon image CentOS exécutée dans Docker en utilisant les éléments suivants

systemctl list-units  

mais je reçois ce message d'erreur :

Failed to get D-Bus connection: Operation not permitted

Avez-vous une idée de ce que pourrait être le problème ?

53voto

13dimitar Points 2310

Je pense que vous exécutez un non-privileged systemd requiert la capacité CAP_SYS_ADMIN, mais Docker supprime cette capacité dans les conteneurs non privilégiés, afin de renforcer la sécurité.

systemd nécessite également un accès RO au système de fichiers cgroup dans un conteneur. Vous pouvez l'ajouter avec –v /sys/fs/cgroup:/sys/fs/cgroup:ro

Voici donc quelques étapes pour exécuter CentOS avec systemd dans un conteneur Docker :

  1. Tirer l'image centos

  2. Configurez un fichier docker comme celui ci-dessous :

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

  3. Construisez-le - docker build -t centos7-systemd - < mydockerfile

  4. Exécuter un conteneur avec docker run --rm --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  5. Vous devriez avoir systemd dans votre conteneur

16voto

Patrick.V. Points 11

Ce n'est pas une réponse directe à votre question, mais c'est peut-être plus important, et je m'en suis rendu compte en lisant les autres réponses ici.

J'ai acquis une certaine expérience dans la migration de certains systèmes complexes vers Docker, et l'une des principales conclusions que j'en ai tirées est qu'il faudrait idéalement avoir un conteneur Docker par application/service ou "par démon".

Une raison très importante à cela est que Docker n'arrêtera pas proprement les services que vous démarrez avec systemctl et en fait, vous risquez de vous retrouver avec le même genre de corruptions de la base de données que lors d'une panne de courant inattendue.

Pour aller un peu plus loin : lorsque Docker envoie une commande " stop " à un conteneur, il envoie le signal SIGTERM uniquement au seul processus qui a été lancé avec le CMD/ENTRYPOINT, et non à tous les services et démons. Ainsi, ce seul service a la possibilité de s'arrêter proprement et tous les autres sont interrompus sans cérémonie.

Si vous devez absolument empaqueter deux services dans le même conteneur (c'est-à-dire votre application et une base de données PostgreSQL ou quelque chose comme ça), alors vous devez avoir votre CMD/ENTRYPOINT être un script qui attrape SIGTERM et le rediffuse ensuite à ces services connus. Cela peut être fait, mais si vous en avez l'occasion, repensez votre solution et essayez de la décomposer en plusieurs conteneurs.

Un addendum

Il y a une intéressante note/page sur le site de Docker d'utiliser supervisord si vous avez absolument besoin de faire tourner plusieurs services dans le même conteneur.

9voto

Zond Points 246

J'ai réussi à résoudre ce problème dans un conteneur Docker CentOS:7. J'ai suivi principalement le projet d'image Docker du Guide sur 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"]

Maintenant, construisez l'image, et exécutez-la en utilisant au moins les arguments suivants pour docker run commandement : -v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Ensuite, le point principal est que /usr/sbin/init doit être le premier processus à l'intérieur du conteneur Docker.

Donc, si vous voulez utiliser un script personnalisé qui exécute certaines commandes avant d'exécuter /usr/sbin/init lancez-le à la fin de votre script en utilisant exec /usr/sbin/init (dans un script bash).

Voici un exemple :

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

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

Et voici le contenu de 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

Vous auriez pu System is booting up. See pam_nologin(8) si vous utilisez le système PAM, dans ce cas, supprimez /usr/lib/tmpfiles.d/systemd-nologin.conf dans votre Dockerfile car il crée le fichier /var/run/nologin qui génère cette erreur spécifique.

2voto

Chaim Geretz Points 131

Je ne voulais pas avoir à lancer systemd comme init/PID 1. Après avoir effectué les étapes de nettoyage mentionnées par d'autres, je lance systemd à partir d'un script de démarrage en tant que /usr/lib/systemd/systemd --system & .

Cela a permis à systemd de démarrer et de lancer les services enregistrés, mais systemctl échouait avec l'erreur D-Bus.

Pour moi, le lien manquant était l'absence du répertoire /run/systemd/system, découvert par strace en utilisant systemctl.

Créer ce répertoire manuellement avant de lancer systemctl permet à systemctl de fonctionner pour moi.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X