ไม่สามารถรับการเชื่อมต่อ D-Bus: ไม่อนุญาตให้ใช้งาน


29

ฉันกำลังพยายามแสดงรายการบริการบนรูปภาพ CentOS ที่ใช้งาน Docker โดยใช้

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 แต่นักเทียบท่าจะลดความสามารถลงในคอนเทนเนอร์ที่ไม่ได้รับสิทธิพิเศษเพื่อเพิ่มความปลอดภัยมากขึ้น

systemd ยังต้องการการเข้าถึง RO ไปยังระบบไฟล์ cgroup ภายในคอนเทนเนอร์ คุณสามารถเพิ่มมันด้วย–v /sys/fs/cgroup:/sys/fs/cgroup:ro

ดังนั้นต่อไปนี้เป็นขั้นตอนวิธีเรียกใช้ CentOS ด้วย systemd ภายในคอนเทนเนอร์ Docker:

  1. ดึงภาพ centos
  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. คุณควรมี systemd ในคอนเทนเนอร์ของคุณ


ค่อนข้างเรียบร้อย! อย่างไรก็ตามอย่างน้อยฉันก็ได้รับข้อมูลเพิ่มเติมตอนนี้ นี่คือสิ่งที่ฉันได้รับการบันทึก:[ 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 ที่คัดลอกมาในคำตอบของฉันคุณเรียกใช้คอนเทนเนอร์จากรูปภาพนั้นและคุณยังคงได้รับข้อผิดพลาดหรือไม่
13

4
บิงโก! ฉันกำลังใช้คอนเทนเนอร์ด้วย/bin/bashเพื่อรับเชลล์ อย่างไรก็ตามสิ่งนี้ทำให้ฉันมีข้อผิดพลาดดังกล่าวก่อนหน้านี้ เมื่อฉันวิ่งไป/usr/sbin/initตามที่แนะนำจากนั้นก็แนบกับกระสุนทั้งหมดไปได้ด้วยดี เห็นได้ชัดว่าฉันคิดถึงความแตกต่าง/usr/sbin/initเล็กน้อย คำตอบนี้สมควรได้รับการยกตัวขึ้นอย่างมาก
Snowcrash

ฉันอยู่ที่นี่มา 2 วันแล้วและฉันก็ยังไม่สามารถเข้าใจได้ว่า/sys/fs/cgroup:/sys/fs/cgroupมันคืออะไรหรือมาจากไหน ... ฉันรู้วิธีติดตั้งโฟลเดอร์ผู้เยี่ยมชมเพื่อรับชมเช่น: /src/:/var/wwwแต่ไฟล์ของคุณมาจากไหน? มันทำให้ฉันมีข้อผิดพลาดมากมายเพราะฉันวางรหัสฉันคิดว่าฉันควรสร้างสิ่งเหล่านั้นที่ไหนสักแห่ง
samayo

4

นี่ไม่ใช่คำตอบที่ตรงกับคำถามของคุณ แต่จริง ๆ แล้วมันอาจจะสำคัญกว่าและฉันได้พบกับการรับรู้นี้เมื่อฉันอ่านคำตอบอื่น ๆ ที่นี่

ฉันเคยมีประสบการณ์ในการโยกย้ายระบบที่ซับซ้อนบางอย่างไปยังนักเทียบท่าและหนึ่งในการรับรู้ที่สำคัญที่ฉันมีคือคุณควรมีตัวเชื่อมต่อคอนเทนเนอร์หนึ่งตัวต่อแอปพลิเคชัน / บริการหรือ "ต่อ daemon"

เหตุผลสำคัญอย่างหนึ่งสำหรับเรื่องนี้ก็คือDocker จะไม่ปิดบริการที่คุณเริ่มต้นด้วย systemctl อย่างแท้จริงและในความเป็นจริงคุณอาจจบลงด้วยความเสียหายฐานข้อมูลประเภทเดียวกันที่มาจากไฟดับที่ไม่คาดคิด

ในการดำน้ำลึกลงไปอีกเล็กน้อย: เมื่อ Docker ออกคำสั่ง "หยุด" ไปยังคอนเทนเนอร์มันจะส่งสัญญาณ SIGTERM เพียงกระบวนการเดียวเดียวที่เริ่มต้นด้วย CMD / ENTRYPOINT ไม่ใช่บริการและ daemons ทั้งหมด เพื่อให้บริการหนึ่งมีคำเตือนให้ปิดอย่างสะอาดและบริการอื่น ๆ ทั้งหมดจะถูกยกเลิกโดยไม่ได้ตั้งใจ

หากคุณจำเป็นต้องทำแพ็กเกจบริการสองรายการในที่เก็บเดียวกัน (เช่นแอปพลิเคชันของคุณและฐานข้อมูล PostgreSQL หรืออะไรทำนองนั้น) คุณต้องมี CMD / ENTRYPOINT ของคุณเป็นสคริปต์ที่จับ SIGTERM แล้วทำการกระจายซ้ำไปยังบริการที่รู้จัก สามารถทำได้ แต่ถ้าคุณมีโอกาสให้คิดทบทวนวิธีแก้ปัญหาของคุณแล้วลองแบ่งมันออกเป็นหลาย ๆ ภาชนะ

ภาคผนวก

มีบันทึกย่อ / หน้าที่น่าสนใจในไซต์นักเทียบท่าเกี่ยวกับการใช้ supervisord หากคุณจำเป็นต้องมีบริการหลายอย่างที่ทำงานอยู่ในคอนเทนเนอร์เดียวกัน


2

ฉันจัดการเพื่อแก้ไขปัญหานี้ใน CentOS: 7 Docker container ฉันได้ติดตามโครงการภาพ 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

ดังนั้นหากคุณต้องการใช้สคริปต์ที่กำหนดเองซึ่งดำเนินการคำสั่งบางคำสั่งก่อน/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/ nologinสำหรับผู้ชนะเนื่องจากการเรียกร้อง CentOS / RHEL 7 UsePAM noไม่ได้รับการสนับสนุนและจะร้องเรียนในบันทึกเช่นนี้ ไม่แน่ใจว่า RH openssh portable patched / แตกมันอย่างใดหรือพวกเขากำลังพยายามลดพื้นผิวการสนับสนุนจากลูกค้ามือใหม่

1

ฉันไม่ต้องการให้มีการเปิดตัวเป็น systemd init / PID 1. หลังจากทำตามขั้นตอนการทำความสะอาดดังกล่าวโดยคนอื่น ๆ ฉันเปิด systemd /usr/lib/systemd/systemd --system &จากภายในสคริปต์เริ่มต้นเป็น

สิ่งนี้อนุญาตให้ systemd เริ่มและเรียกใช้บริการที่ลงทะเบียนแล้ว แต่ systemctl ล้มเหลวพร้อมข้อผิดพลาด D-Bus

สำหรับฉันลิงค์ที่ขาดหายไปคือการขาดไดเรกทอรี / run / systemd / system ค้นพบสิ่งนี้โดยstraceing systemctl

การสร้างไดเร็กทอรีนี้ด้วยตนเองก่อนที่จะรัน systemctl อนุญาตให้ systemctl ทำงานให้ฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.