Docker에서 실행중인 CentOS 이미지에 서비스를 나열하려고합니다.
systemctl list-units
하지만이 오류 메시지가 나타납니다.
Failed to get D-Bus connection: Operation not permitted
문제가 무엇인지 제안 하시겠습니까?
systemd
CentOS에 필요한 경우 다음 이미지를 사용하십시오. FROM centos/systemd
Docker에서 실행중인 CentOS 이미지에 서비스를 나열하려고합니다.
systemctl list-units
하지만이 오류 메시지가 나타납니다.
Failed to get D-Bus connection: Operation not permitted
문제가 무엇인지 제안 하시겠습니까?
systemd
CentOS에 필요한 경우 다음 이미지를 사용하십시오. FROM centos/systemd
답변:
내 생각 엔 당신이 non-privileged
컨테이너를 합니다. systemd에는 CAP_SYS_ADMIN 기능이 필요하지만 Docker는 보안을 강화하기 위해 권한이없는 컨테이너에서 해당 기능을 삭제합니다.
systemd는 또한 컨테이너 내의 cgroup 파일 시스템에 대한 RO 액세스 권한이 필요합니다. 당신은 그것을 추가 할 수 있습니다–v /sys/fs/cgroup:/sys/fs/cgroup:ro
따라서 Docker 컨테이너 내부에서 systemd로 CentOS를 실행하는 방법에 대한 몇 가지 단계는 다음과 같습니다.
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"]
docker build --rm -t centos7-systemd - < mydockerfile
컨테이너를 실행 docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init
컨테이너에 시스템이 있어야합니다
[ 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.
Failed to get D-Bus connection: Operation not permitted
/bin/bash
쉘을 얻기 위해 컨테이너를 실행하고있었습니다 . 그러나 이것은 이전에 언급 한 오류를 주었다. 내가 /usr/sbin/init
제안한대로 그것을 실행했을 때 껍질로 붙어 있으면 모든 것이 잘되었습니다. 분명히에 대한 뉘앙스가 빠져 /usr/sbin/init
있습니다. 이 답변은 실질적인 찬사를받을 가치가 있습니다.
/sys/fs/cgroup:/sys/fs/cgroup
이거나 어디에서 왔는지 알 수 없습니다 ... 게스트 폴더를 hist에 마운트하는 방법을 알고 있습니다. /src/:/var/www
그러나 파일은 어디에서 왔습니까? 내가 코드를 붙여 있기 때문에 나는 그 곳 작성해야합니다 생각하고, 나에게 많은 오류를 일으키는
이것은 귀하의 질문에 대한 직접적인 대답은 아니지만 실제로 더 중요 할 수 있으며 여기에 다른 답변을 읽으 면서이 실현을 보았습니다.
복잡한 시스템을 Docker로 마이그레이션 한 경험이 있으며, 중요한 사실 중 하나는 응용 프로그램 / 서비스 당 또는 데몬 당 하나의 Docker 컨테이너가 이상적이라는 것입니다.
이것의 중요한 이유 중 하나는 Docker가 systemctl로 시작하는 서비스를 완전히 종료하지 않으며 실제로 예기치 않은 정전으로 인해 동일한 종류의 데이터베이스 손상이 발생할 수 있기 때문입니다.
Docker가 컨테이너에 "중지"명령을 발행하면 SIGTERM 신호는 CMD / ENTRYPOINT로 시작된 하나의 단일 프로세스 만 모든 서비스 및 데몬에 전송하지는 않습니다. 따라서 한 서비스는 완전히 종료하라는 경고가 표시되고 다른 서비스는 모두 실수로 종료됩니다.
동일한 컨테이너에 두 개의 서비스 (예 : 애플리케이션 및 PostgreSQL 데이터베이스 또는 이와 유사한 것)를 반드시 패키징해야하는 경우 CMD / ENTRYPOINT는 SIGTERM을 파악한 다음 알려진 서비스로 다시 브로드 캐스트하는 스크립트 여야합니다. 가능하지만 기회가 있다면 솔루션을 다시 생각하고 여러 컨테이너로 나누십시오.
Docker 사이트 에는 동일한 컨테이너에서 여러 서비스를 실행 해야하는 경우 supervisord 사용 에 대한 흥미로운 메모 / 페이지 가 있습니다.
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/init
Docker 컨테이너 내부의 첫 번째 프로세스 여야한다는 것입니다.
따라서을 실행하기 전에 일부 명령을 실행하는 사용자 정의 스크립트를 사용하려면 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
init / PID 1로 systemd를 시작하고 싶지 않았습니다. 다른 사람들이 언급 한 정리 단계를 수행 한 후 시작 스크립트 내에서 systemd를 다음과 같이 시작했습니다. /usr/lib/systemd/systemd --system &
.
이로 인해 systemd는 등록 된 서비스를 시작하고 시작할 수 있었지만 systemctl은 D-Bus 오류와 함께 실패했습니다.
나를 위해 누락 된 링크는 / run / systemd / system 디렉토리가 strace
없기 때문에 systemctl을 통해이를 발견했습니다 .
systemctl을 실행하기 전에이 디렉토리를 수동으로 작성하면 systemctl이 작동합니다.
sudo
습니까?