d-bus를 통해 호스트와 통신하도록 도커 컨테이너를 설정합니다.

d-bus를 통해 호스트와 통신하도록 도커 컨테이너를 설정합니다.

저는 d-bus를 통해 통신하는 마스터와 슬레이브라는 두 개의 애플리케이션을 만들고 있습니다. 내 애플리케이션이 동일한 호스트에서 실행될 때 예상대로 작동합니다.
이제 슬레이브 애플리케이션을 도커 컨테이너로 이동하고 싶지만 호스트와 컨테이너 간에 d-bus 세션을 공유하는 데 문제가 있습니다. 이것은 내 Dockerfile입니다.

i386/ubuntu:16.04에서

볼륨/실행/사용자/1000/
ENV DBUS_SESSION_BUS_ADDRESS=unix:경로=/run/user/1000/bus

apt-get 업데이트 실행
apt-get 업그레이드-y 실행
apt-get install -y dbus 실행

#RUN apt-get install -y libnotify-bin
#RUN apt-get install -y dbus-x11

adduser -u 1000 myuser 실행

# dbus.conf /etc/dbus-1/session.d/ 복사

사용자 1000:1000
진입점 ["dbus-daemon", "--session", "--print-address"]

/run/user/1000/bus는 내 DBUS_SESSION_BUS_ADDRESS 변수의 값입니다.

나는 컨테이너를 만든다

docker create --mount type=bind,source=/run/user/1000/bus,target=/run/user/1000/bus mycontainer

/run/user/1000/bus는 컨테이너 내부에 표시되지만 컨테이너가 시작되면 주소를 인쇄합니다.

유닉스:추상=/tmp/dbus-iXrYzptYOX,guid=78a790f0f6a4387a39ac3d505da478a3
내 애플리케이션이 통신할 수 없습니다.

컨테이너의 /etc/dbus-1/session.d/에 dbus.conf를 추가하고 덮어쓰면

 <listen>unix:path=/run/user/1000/bus</listen> 
"메시지 버스를 시작할 수 없습니다: '/run/user/1000/bus' 소켓을 바인딩할 수 없습니다: 주소가 이미 사용 중입니다."라는 메시지가 나타납니다.

docker 내에서 dbus-daemon을 시작해야 할지 잘 모르겠습니다.
어떻게 해야 하나요?

답변1

해결책을 찾았습니다. 이것은 내 Dockerfile입니다.

i386/ubuntu:16.04에서

apt-get 업데이트 실행
apt-get 업그레이드-y 실행
apt-get install -y dbus 실행

dbus.conf /etc/dbus-1/session.d/ 복사

ENTRYPOINT ["dbus-run-session", "slaveApp"]

그리고 내 dbus.conf:

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
    "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">

<busconfig>
    <listen>tcp:host=localhost,bind=*,port=6667,family=ipv4</listen>
    <listen>unix:tmpdir=/tmp</listen>
    <auth>ANONYMOUS</auth>
    <allow_anonymous/>
</busconfig>

그리고 호스트 시스템에서 주소 변수를 설정합니다.

DBUS_SESSION_BUS_ADDRESS=tcp:host=${containerIp}, 포트=6667,family=ipv4 내보내기

내 주요 애플리케이션에서 연결을 시작합니다(Qt를 사용합니다).

QDBusConnection::connectToBus("tcp:host=${containerIp},port=6667", "qt_default_session_bus");

이제 마스터 애플리케이션은 슬레이브 애플리케이션에 메시지를 보낼 수 있습니다. 하지만 아직 슬레이브에서 마스터로 메시지를 보내려고 시도한 적은 없습니다.

답변은 다음 기사에서 가져왔습니다. https://stackoverflow.com/a/45487266/6509266

답변2

내가 하나 얻을 수 있어요컨테이너화다음 명령을 사용하여 호스트 DBus를 얻으려면 Spotify를 설치하십시오(Ubuntu에서).

pkexec systemd-nspawn \
  --setenv=DISPLAY=unix$DISPLAY \
  --setenv=PULSE_SERVER=unix:/run/user/1000/pulse/native \
  --setenv=DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus \
  --bind-ro /tmp/.X11-unix \
  --bind /run/user/1000 \
  --bind-ro /run/user/1000/bus \
  --bind /dev/snd \
  -u spotify \
  -M spotify \
  spotify

DBUS_SESSION_BUS_ADDRESS따라서 여기서 핵심은 컨테이너에 호스트 바인딩이 설치되어 있는지 확인하고 동일한 변수를 동일한 값으로 내보내는 것 같습니다 . 컨테이너에 DBus도 설치했는데 부팅 이미지가 없고 Spotify만 실행하고 있다는 점을 고려하면 그럴 필요는 없을 것 같습니다.

답변3

저는 액세스하려는 docker-compose.yml 서비스에 다음을 통합해야 했습니다.

    environment:
      - DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
      - DISPLAY=:0

    security_opt:
      - apparmor:unconfined

    volumes:
      - /run/user/1000/bus:/run/user/1000/bus
      - /tmp/.X11-unix:/tmp/.X11-unix

(X11 비트가 필요한지 모르겠습니다. dbus 세션 버스 주소와 security_opt가 중요한 비트입니다.)

notify-send저는 libnotify를 위해 이 작업을 하고 있습니다. 따라서 libnotify-bin 패키지(또는 시스템에 명령을 제공하는 패키지) 가 설치되어 있는지 확인해야 합니다.

그런 다음 하나를 만들고 작동 docker-compose up하는지 확인하십시오 notify-send hello!

관련 정보