Переслать X11 через SSH-соединение с хостом контейнера?

4339
M-Pixel

Я хотел бы запустить приложение GUI в контейнере с удаленного компьютера.

Я не хочу решать эту проблему, добавив хост SSH в контейнер, потому что

  • У меня уже есть доступ к хост-машине через SSH
  • Это добавляет ненужные накладные расходы
  • Это делает контейнер непереносимым между удаленным и локальным использованием

Я уже могу успешно запускать приложения с графическим интерфейсом на хосте, но не из контейнера. Вот шаги, которые я сделал до сих пор:

хозяин

  • xauth + (не на длительный срок, но полезно для устранения возможных проблем)
  • docker-userс uid 501000 на хосте == docker-userс uid 1000 в контейнере через функцию пространства имен
  • .Xauthorityфайл скопирован в docker-userдомашнюю папку

Dockerfile

  • На основе альпийских
  • Устанавливает xauthи, для целей тестирования,xterm
  • Создает docker-userс надлежащим UID / GID

докер-Compose

  • Переменная среды DISPLAYпересылается в
  • Объем /home/docker-user/:/home/docker-user/:roдля предоставления .Xauthoritycookie
  • Объем /tmp/.X11-unix:/tmp/.X11-unix:roдля предоставления доступа к сокету X11
  • Запускает команду su - docker-user -c "export DISPLAY=$DISPLAY && xterm"
    • su раньше бегал как docker-user
    • DISPLAYперенаправлен в suконтекст

К сожалению, этого еще недостаточно. В то время как xterm в операционной системе хоста подключается к моему локальному X-серверу без проблем, xterm в контейнере говорит Xt error: Can't open display: localhost:10.0.

Я подтвердил, что «localhost: 10.0» является правильным, localhost существует в контейнере /etc/hosts, и cookie и сокет делают это с правильными разрешениями.

Что еще может пойти не так?

4

3 ответа на вопрос

3
pale bone

Похоже, вы делаете все то же самое, что и я, за исключением того, что вы делитесь .Xauthority во время создания контейнера. Это означает, что если вы когда-либо создадите ssh -X на своей машине после создания контейнера, .Xauthority больше не будет действительным. Вы не можете ssh -X из другого терминала в тот же компьютер и вернуться назад и использовать .Xauthority, ssh -X каждый раз меняет .Xauthority для самого последнего терминала. Я только заставил его работать, копируя .Xauthority каждый раз, когда я запускаю ssh -X на свою машину и пытаюсь поделиться экраном с моим контейнером.

примечание: я поделился устройством и идентификатором машины, потому что я переадресовал выходные данные веб-камеры

1. Создайте контейнер и сообщите xhost, чтобы разрешить пересылку с идентификатора контейнера:

sudo docker run -it -d \ --net=host \ --env="DISPLAY" \ --env="QT_X11_NO_MITSHM=1" \ --volume="/tmp/.X11-unix:/tmp/.X11-unix:rw" \ --device="/dev/video0:/dev/video0" \ --volume="/path/to/your/sharedDockerFiles:/root/sharedDockerFiles" \ --volume="/etc/machine-id:/etc/machine-id" \ yourdockerrepo/image:tag \ bash export containerId=$(docker ps -l -q) sudo xhost +local:`sudo docker inspect --format='{{ .Config.Hostname }}' $containerId` sudo docker start $containerId 

2. Скопируйте .Xauthority из домашнего хоста в каталог sharedDockerFiles:

sudo cp ~/.Xauthority /path/to/your/sharedDockerFiles 

3. Запустите и прикрепите свой контейнер

4. Скопируйте .Xauthority в вашей общей папке в ваш домашний контейнер

sudo cp /root/sharedDockerFiles/.Xauthority ~/ 

5. (необходимо один раз): отредактируйте файл / etc / ssh / ssh_config контейнера в Host *, включив в него:

 ForwardX11 yes X11Forwarding yes 

6. Перезапустите свой контейнер, подключите и запустите приложение с графическим интерфейсом.

7. Если у вас все еще есть проблемы, убедитесь, что переменная $ DISPLAY в контейнере совпадает с переменной хоста

echo $DISPLAY #do this in the container exit echo $DISPLAY #do this in the host, should be the same as container's #if they aren't equal, start container and: export DISPLAY= #put the output of your host's $DISPLAY variable here 
1
Jure S

Скопируйте .Xauthority в контейнер в начале сеанса SSH перед использованием GUI:

sudo docker exec -i container_name bash -c 'cat > ~/.Xauthority' < ~/.Xauthority 

Затем вы можете передать DISPLAY, если используете 'docker exec'. Например, чтобы открыть новый Bash:

sudo docker exec -it --env="DISPLAY" container_name bash 

Еще 2 возможных причины ошибки: (в дополнение к принятому ответу)

  • basic: у вас нет ssh-сервера или xauth в контейнере (для ubuntu запустите 'apt install openssh-server xauth')

  • подлый: Если ваше имя хоста контейнера отличается от имени хоста (например, установите через -h значок в 'docker run'), вы получите ошибку, и вам придется с этим справиться (например, установить то же имя хоста или добавить cookie в Xauth)

Это решение сработало для меня. Очевидно, было достаточно просто скопировать файл .Xauthority в докер-контейнер без необходимости его перезапуска. Nikolay Frick 6 лет назад 0
0
psh

Давайте запустим docker с параметром --net = host. Это заставляет контейнер видеть тот же сетевой стек хоста.

Например,

запуск докера --net = host --rm -ti -u myid -e DISPLAY = "$ DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix image: tag BINARY