gagal mendapatkan koneksi D-Bus: Operasi tidak diizinkan

29

Saya mencoba mendaftar layanan pada gambar CentOS saya yang berjalan di Docker menggunakan

systemctl list-units  

tapi saya mendapatkan pesan kesalahan ini:

Failed to get D-Bus connection: Operation not permitted

Ada saran apa masalahnya?

Snowcrash
sumber
1
Kamu tidak menggunakan sudo?
Michael Hampton
Anda seharusnya tidak menggunakan systemd, jika Anda tidak membutuhkannya. Cobalah memulai aplikasi tanpa CMD atau RUN, atau menggunakan skrip wrapper.
nelaaro
Jika Anda membutuhkan systemdCentOS, gunakan gambar ini: FROM centos/systemd
james.garriss

Jawaban:

24

Dugaan saya adalah Anda menjalankan sebuah non-privilegedwadah. systemd membutuhkan kemampuan CAP_SYS_ADMIN tetapi Docker menjatuhkan kemampuan itu dalam wadah yang tidak diistimewakan, untuk menambah keamanan.

systemd juga membutuhkan akses RO ke sistem file cgroup dalam sebuah wadah. Anda dapat menambahkannya dengan–v /sys/fs/cgroup:/sys/fs/cgroup:ro

Jadi, berikut beberapa langkah tentang cara menjalankan CentOS dengan systemd di dalam wadah Docker:

  1. Tarik gambar centos
  2. Siapkan file buruh pelabuhan seperti di bawah ini:
FROM centos
MAINTAINER "Yourname" <[email protected]>
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. Bangun itu - docker build --rm -t centos7-systemd - < mydockerfile
  2. Jalankan wadah dengan docker run --privileged -ti -e container=docker -v /sys/fs/cgroup:/sys/fs/cgroup centos7-systemd /usr/sbin/init

  3. Anda harus memiliki systemd di wadah Anda

13ditarik
sumber
Cukup rapi! Namun, setidaknya saya mendapatkan lebih banyak info sekarang. Inilah yang saya dapat login:[ 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
Jika saya tidak jelas! Saya masih mendapatkan kesalahanFailed to get D-Bus connection: Operation not permitted
Snowcrash
Anda telah membangun gambar Anda sendiri dari Dockerfile yang disalin dalam jawaban saya, Anda menjalankan wadah dari gambar itu, dan Anda masih mendapatkan kesalahan?
Desember
4
Bingo! Saya sedang menjalankan wadah dengan /bin/bashuntuk mendapatkan shell. Namun, ini memberi saya kesalahan yang disebutkan sebelumnya. Ketika saya menjalankannya dengan /usr/sbin/initseperti yang disarankan maka terpasang dengan shell semua berjalan dengan baik Jelas saya kehilangan nuansa tentang /usr/sbin/init. Jawaban ini layak mendapatkan peningkatan substansial.
Snowcrash
Saya telah melakukan ini selama 2 hari, dan saya masih tidak tahu dari /sys/fs/cgroup:/sys/fs/cgroupmana atau dari mana itu berasal ... Saya tahu cara me-mount folder guest ke hist seperti: /src/:/var/wwwtetapi dari mana file Anda berasal? Ini menyebabkan saya banyak kesalahan karena saya menempelkan kode, saya pikir saya harus membuatnya di suatu tempat
samayo
4

Ini bukan jawaban langsung untuk pertanyaan Anda, tetapi mungkin sebenarnya lebih penting, dan saya menemukan realisasi ini ketika saya membaca jawaban lain di sini.

Saya memiliki pengalaman memigrasi beberapa sistem yang rumit ke Docker, dan salah satu realisasi penting yang saya miliki adalah bahwa Anda idealnya memiliki satu wadah Docker per aplikasi / layanan atau "per daemon".

Salah satu alasan yang sangat signifikan untuk ini adalah bahwa Docker tidak akan mematikan layanan yang Anda mulai dengan systemctl dan bahkan Anda mungkin berakhir dengan jenis korupsi database yang sama yang berasal dari pemadaman listrik yang tidak terduga.

Untuk menyelami ini sedikit lebih dalam: ketika Docker mengeluarkan perintah "stop" ke sebuah wadah, ia mengirimkan sinyal SIGTERM hanya satu proses tunggal yang dimulai dengan CMD / ENTRYPOINT, tidak untuk semua layanan dan daemon. Sehingga satu layanan memiliki peringatan untuk shutdown dengan bersih dan semua layanan lainnya dihentikan begitu saja.

Jika Anda benar-benar harus mengemas dua layanan dalam wadah yang sama (yaitu aplikasi Anda dan database PostgreSQL atau sesuatu seperti itu) maka Anda harus memiliki CMD / ENTRYPOINT Anda menjadi skrip yang menangkap SIGTERM dan kemudian siaran ulang ke layanan yang dikenal. Ini dapat dilakukan, tetapi jika Anda memiliki kesempatan, pikirkan kembali solusi Anda dan cobalah untuk memecahnya menjadi beberapa wadah.

Adendum

Ada catatan / halaman yang menarik di situs Docker tentang penggunaan supervisord jika Anda benar-benar perlu menjalankan beberapa layanan dalam wadah yang sama.

Murray Todd Williams
sumber
2

Saya telah berhasil memperbaiki masalah ini dalam sebuah wadah Docker CentOS: 7. Saya terutama mengikuti Panduan tentang proyek gambar 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"]

Sekarang, bangun gambar, dan jalankan dengan menggunakan setidaknya argumen berikut untuk docker rundiperintahkan:-v /run -v /sys/fs/cgroup:/sys/fs/cgroup:ro

Maka poin utamanya adalah yang /usr/sbin/initharus menjadi proses pertama di dalam wadah Docker.

Jadi, jika Anda ingin menggunakan skrip khusus yang mengeksekusi beberapa perintah sebelum menjalankan /usr/sbin/init, jalankan di akhir skrip Anda menggunakan exec /usr/sbin/init(dalam skrip bash).

Berikut ini sebuah contoh:

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

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

Dan inilah isi dari 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

Anda dapat memiliki System is booting up. See pam_nologin(8)jika Anda menggunakan sistem PAM, dalam hal ini, hapus /usr/lib/tmpfiles.d/systemd-nologin.confdi Anda Dockerfilekarena itu menciptakan file /var/run/nologinyang menghasilkan kesalahan spesifik ini.

Anthony O.
sumber
systemd-nologin.conf/ nologinuntuk kemenangan karena klaim CentOS / RHEL 7 UsePAM notidak didukung dan akan mengeluh dalam bentuk log. Tidak yakin apakah RH openssh portabel ditambal / rusak entah bagaimana atau mereka mencoba menurunkan permukaan dukungan mereka dari pelanggan pemula.
1

Saya tidak ingin harus meluncurkan systemd sebagai init / PID 1. Setelah melakukan langkah-langkah pembersihan yang disebutkan oleh orang lain, saya meluncurkan systemd dari dalam skrip startup sebagai /usr/lib/systemd/systemd --system &.

Systemd ini diizinkan untuk memulai dan meluncurkan layanan terdaftar, tetapi systemctl gagal dengan kesalahan D-Bus.

Bagi saya, tautan yang hilang adalah tidak adanya direktori / run / systemd / system, yang ditemukan ini oleh stracesystemctl.

Membuat direktori ini secara manual sebelum menjalankan systemctl memungkinkan systemctl bekerja untuk saya.

Chaim Geretz
sumber