không nhận được kết nối D-Bus: Không được phép vận hành


29

Tôi đang cố gắng liệt kê các dịch vụ trên hình ảnh CentOS của mình đang chạy trong Docker bằng

systemctl list-units  

nhưng tôi nhận được thông báo lỗi này:

Failed to get D-Bus connection: Operation not permitted

Bất kỳ đề xuất vấn đề có thể là gì?


1
Bạn đã không sử dụng sudo?
Michael Hampton

Bạn không nên sử dụng systemd, nếu bạn không cần nó. Hãy thử khởi động ứng dụng với ứng dụng này trong CMD hoặc RUN hoặc sử dụng tập lệnh bao bọc.
nelaaro

Nếu bạn cần systemdtrên CentOS, hãy sử dụng hình ảnh này: FROM centos/systemd
james.garriss

Câu trả lời:


24

Tôi đoán là bạn đang chạy một non-privilegedcontainer. systemd yêu cầu khả năng CAP_SYS_ADMIN nhưng Docker bỏ khả năng đó trong các thùng chứa không có đặc quyền, để tăng thêm bảo mật.

systemd cũng yêu cầu truy cập RO vào hệ thống tệp cgroup trong một thùng chứa. Bạn có thể thêm nó với–v /sys/fs/cgroup:/sys/fs/cgroup:ro

Vì vậy, đây là một vài bước về cách chạy CentOS với systemd bên trong bộ chứa Docker:

  1. Kéo hình ảnh centos
  2. Thiết lập một tập tin docker như dưới đây:
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. Xây dựng nó - docker build --rm -t centos7-systemd - < mydockerfile
  2. Chạy một container với docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. Bạn nên có systemd trong container của bạn


Khá gọn gàng! Tuy nhiên, ít nhất bây giờ tôi đang nhận được nhiều thông tin hơn. Đây là những gì tôi đã đăng nhập:[ 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
Trong trường hợp tôi không rõ ràng! Tôi vẫn nhận được lỗiFailed to get D-Bus connection: Operation not permitted
Snowcrash

Bạn đã xây dựng hình ảnh của riêng mình từ Dockerfile được sao chép trong câu trả lời của tôi, bạn chạy một container từ hình ảnh đó và bạn vẫn gặp lỗi?
13dimitar

4
Chơi lô tô! Tôi đã chạy container với /bin/bashđể lấy vỏ. Tuy nhiên, điều này đã cho tôi các lỗi được đề cập trước đó. Khi tôi chạy nó /usr/sbin/initnhư được đề xuất sau đó gắn với một cái vỏ tất cả đều ổn. Rõ ràng tôi đang thiếu một sắc thái về /usr/sbin/init. Câu trả lời này xứng đáng được nâng cấp đáng kể.
Snowcrash

Tôi đã làm việc này được 2 ngày và tôi vẫn không thể biết /sys/fs/cgroup:/sys/fs/cgroupđược nó đến từ đâu và ... Tôi biết cách gắn thư mục khách vào hist như thế nào: /src/:/var/wwwnhưng tập tin của bạn đến từ đâu? Nó gây ra cho tôi rất nhiều lỗi vì tôi đã dán mã, tôi nghĩ rằng tôi nên tạo chúng ở một nơi nào đó
samayo

4

Đây không phải là câu trả lời trực tiếp cho câu hỏi của bạn, nhưng nó thực sự có thể quan trọng hơn, và tôi đã bắt gặp nhận thức này khi tôi đang đọc các câu trả lời khác ở đây.

Tôi đã có một số kinh nghiệm khi chuyển một số hệ thống phức tạp sang Docker và một trong những nhận thức quan trọng mà tôi có là bạn nên có một container Docker cho mỗi ứng dụng / dịch vụ hoặc "mỗi daemon".

Một lý do rất quan trọng cho việc này là Docker sẽ không tắt các dịch vụ mà bạn bắt đầu với systemctl và trên thực tế, bạn có thể gặp phải cùng một loại lỗi cơ sở dữ liệu xuất phát từ sự cố mất điện đột xuất.

Để tìm hiểu sâu hơn một chút: khi Docker đưa ra lệnh "dừng" cho một container, nó chỉ gửi tín hiệu SIGTERM cho một quy trình duy nhất được bắt đầu với CMD / ENTRYPOINT, không phải cho tất cả các dịch vụ và trình nền. Vì vậy, một dịch vụ có cảnh báo tắt máy sạch sẽ và tất cả các dịch vụ khác sẽ bị chấm dứt một cách bất thường.

Nếu bạn hoàn toàn phải đóng gói hai dịch vụ trong cùng một thùng chứa (tức là ứng dụng của bạn và cơ sở dữ liệu PostgreQuery hoặc một cái gì đó tương tự) thì bạn cần phải có CMD / ENTRYPOINT của bạn là một tập lệnh bắt SIGTERM và sau đó phát lại nó cho các dịch vụ đã biết. Nó có thể được thực hiện, nhưng nếu bạn có cơ hội, hãy suy nghĩ lại về giải pháp của bạn và cố gắng chia nó thành nhiều container.

Một phụ lục

Có một ghi chú / trang thú vị trên trang web Docker về việc sử dụng giám sát nếu bạn thực sự cần phải có nhiều dịch vụ chạy trong cùng một container.


2

Tôi đã cố gắng khắc phục sự cố này trong bộ chứa Dock của CentOS: 7. Tôi đã theo dõi chủ yếu Hướng dẫn về dự án hình ảnh Dock của 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"]

Bây giờ, xây dựng hình ảnh và chạy nó bằng cách sử dụng ít nhất các đối số sau đây để ra docker runlệnh:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Sau đó, điểm chính là /usr/sbin/initphải là quá trình đầu tiên bên trong container Docker.

Vì vậy, nếu bạn muốn sử dụng một tập lệnh tùy chỉnh thực thi một số lệnh trước khi chạy /usr/sbin/init, hãy khởi chạy nó ở cuối tập lệnh của bạn bằng cách sử dụng exec /usr/sbin/init(trong tập lệnh bash).

Đây là một ví dụ:

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

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

Và đây là nội dung của 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

Bạn có thể có System is booting up. See pam_nologin(8)nếu bạn sử dụng hệ thống PAM, trong trường hợp đó, hãy xóa /usr/lib/tmpfiles.d/systemd-nologin.conftrong Dockerfilevì bạn tạo tệp /var/run/nologintạo ra lỗi cụ thể này.


systemd-nologin.conf/ nologincho chiến thắng vì các UsePAM nokhiếu nại của CentOS / RHEL 7 không được hỗ trợ và sẽ khiếu nại trong nhật ký như vậy. Không chắc chắn nếu RH openssh di động vá / phá vỡ nó bằng cách nào đó hoặc họ đang cố gắng hạ thấp bề mặt hỗ trợ của họ từ khách hàng mới làm quen.

1

Tôi không muốn phải khởi chạy systemd dưới dạng init / PID 1. Sau khi thực hiện các bước dọn dẹp được đề cập bởi những người khác, tôi khởi chạy systemd từ trong tập lệnh khởi động như /usr/lib/systemd/systemd --system &.

Điều này cho phép systemd khởi động và khởi chạy các dịch vụ đã đăng ký, nhưng systemctl đã thất bại với lỗi D-Bus.

Đối với tôi, liên kết bị thiếu là sự vắng mặt của thư mục / run / systemd / system, đã phát hiện ra điều này bằng cách straceing systemctl.

Tạo thư mục này theo cách thủ công trước khi chạy systemctl cho phép systemctl hoạt động với tôi.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.