D- 버스 연결에 실패했습니다 : 작업이 허용되지 않습니다


29

Docker에서 실행중인 CentOS 이미지에 서비스를 나열하려고합니다.

systemctl list-units  

하지만이 오류 메시지가 나타납니다.

Failed to get D-Bus connection: Operation not permitted

문제가 무엇인지 제안 하시겠습니까?


1
사용하지 않았 sudo습니까?
Michael Hampton

필요하지 않은 경우 systemd를 사용하지 않아야합니다. CMD 또는 RUN에서 응용 프로그램을 시작하거나 랩퍼 스크립트를 사용하여 응용 프로그램을 시작하십시오.
nelaaro

systemdCentOS에 필요한 경우 다음 이미지를 사용하십시오. FROM centos/systemd
james.garriss

답변:


24

내 생각 엔 당신이 non-privileged 컨테이너를 합니다. systemd에는 CAP_SYS_ADMIN 기능이 필요하지만 Docker는 보안을 강화하기 위해 권한이없는 컨테이너에서 해당 기능을 삭제합니다.

systemd는 또한 컨테이너 내의 cgroup 파일 시스템에 대한 RO 액세스 권한이 필요합니다. 당신은 그것을 추가 할 수 있습니다–v /sys/fs/cgroup:/sys/fs/cgroup:ro

따라서 Docker 컨테이너 내부에서 systemd로 CentOS를 실행하는 방법에 대한 몇 가지 단계는 다음과 같습니다.

  1. 센토 이미지 가져 오기
  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. 그것을 구축- docker build --rm -t centos7-systemd - < mydockerfile
  2. 컨테이너를 실행 docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. 컨테이너에 시스템이 있어야합니다


꽤 깔끔한! 그러나 적어도 지금은 더 많은 정보를 얻고 있습니다. 내가 기록한 내용은 다음과 같습니다.[ 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
내가 명확하지 않은 경우! 여전히 오류가 발생합니다Failed to get D-Bus connection: Operation not permitted
Snowcrash

내 답변에 복사 된 Dockerfile에서 자신의 이미지를 작성하고 해당 이미지에서 컨테이너를 실행했는데 여전히 오류가 발생합니까?
13dimitar

4
빙고! /bin/bash쉘을 얻기 위해 컨테이너를 실행하고있었습니다 . 그러나 이것은 이전에 언급 한 오류를 주었다. 내가 /usr/sbin/init제안한대로 그것을 실행했을 때 껍질로 붙어 있으면 모든 것이 잘되었습니다. 분명히에 대한 뉘앙스가 빠져 /usr/sbin/init있습니다. 이 답변은 실질적인 찬사를받을 가치가 있습니다.
Snowcrash

나는 2 일 동안이 작업을 해왔지만 여전히 무엇 /sys/fs/cgroup:/sys/fs/cgroup이거나 어디에서 왔는지 알 수 없습니다 ... 게스트 폴더를 hist에 마운트하는 방법을 알고 있습니다. /src/:/var/www그러나 파일은 어디에서 왔습니까? 내가 코드를 붙여 있기 때문에 나는 그 곳 작성해야합니다 생각하고, 나에게 많은 오류를 일으키는
samayo

4

이것은 귀하의 질문에 대한 직접적인 대답은 아니지만 실제로 더 중요 할 수 있으며 여기에 다른 답변을 읽으 면서이 실현을 보았습니다.

복잡한 시스템을 Docker로 마이그레이션 한 경험이 있으며, 중요한 사실 중 하나는 응용 프로그램 / 서비스 당 또는 데몬 당 하나의 Docker 컨테이너가 이상적이라는 것입니다.

이것의 중요한 이유 중 하나는 Docker가 systemctl로 시작하는 서비스를 완전히 종료하지 않으며 실제로 예기치 않은 정전으로 인해 동일한 종류의 데이터베이스 손상이 발생할 수 있기 때문입니다.

Docker가 컨테이너에 "중지"명령을 발행하면 SIGTERM 신호는 CMD / ENTRYPOINT로 시작된 하나의 단일 프로세스 만 모든 서비스 및 데몬에 전송하지는 않습니다. 따라서 한 서비스는 완전히 종료하라는 경고가 표시되고 다른 서비스는 모두 실수로 종료됩니다.

동일한 컨테이너에 두 개의 서비스 (예 : 애플리케이션 및 PostgreSQL 데이터베이스 또는 이와 유사한 것)를 반드시 패키징해야하는 경우 CMD / ENTRYPOINT는 SIGTERM을 파악한 다음 알려진 서비스로 다시 브로드 캐스트하는 스크립트 여야합니다. 가능하지만 기회가 있다면 솔루션을 다시 생각하고 여러 컨테이너로 나누십시오.

부록

Docker 사이트 에는 동일한 컨테이너에서 여러 서비스를 실행 해야하는 경우 supervisord 사용 대한 흥미로운 메모 / 페이지 가 있습니다.


2

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/initDocker 컨테이너 내부의 첫 번째 프로세스 여야한다는 것입니다.

따라서을 실행하기 전에 일부 명령을 실행하는 사용자 정의 스크립트를 사용하려면 bash 스크립트를 /usr/sbin/init사용하여 스크립트 끝에서 실행하십시오 exec /usr/sbin/init.

예를 들면 다음과 같습니다.

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

System is booting up. See pam_nologin(8)경우 PAM 시스템을 사용하는 경우이 특정 오류를 생성 하는 파일 을 생성 하므로 삭제 /usr/lib/tmpfiles.d/systemd-nologin.conf해야 할 수 있습니다 .Dockerfile/var/run/nologin


systemd-nologin.conf/ nologinCentOS / RHEL 7 클레임 UsePAM no이 지원되지 않으므로 로그에 불만이 표시되므로 당첨 됩니다. RH가 휴대용 패치를 열어 놓았는지 확실하지 않거나 초보자 고객의 지원 범위를 낮추려고합니다.

1

init / PID 1로 systemd를 시작하고 싶지 않았습니다. 다른 사람들이 언급 한 정리 단계를 수행 한 후 시작 스크립트 내에서 systemd를 다음과 같이 시작했습니다. /usr/lib/systemd/systemd --system & .

이로 인해 systemd는 등록 된 서비스를 시작하고 시작할 수 있었지만 systemctl은 D-Bus 오류와 함께 실패했습니다.

나를 위해 누락 된 링크는 / run / systemd / system 디렉토리가 strace없기 때문에 systemctl을 통해이를 발견했습니다 .

systemctl을 실행하기 전에이 디렉토리를 수동으로 작성하면 systemctl이 작동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.