Запустите приложение X в контейнере Docker надежно на сервере, подключенном через SSH без " --net host"
без контейнера Docker легко запустить программу X11 на удаленном сервере, используя пересылку SSH X11 (ssh-X). Я попытался сделать то же самое работает, когда приложение работает внутри контейнера Docker на сервере. Когда SSH-ing в сервер с опцией-X, туннель X11 настроен и переменная среды "$DISPLAY "автоматически устанавливается в типично "localhost: 10.0" или аналогичный. Если я просто попытаюсь запустить приложение X в докере, я получу эта ошибка:
Error: GDK_BACKEND does not match available displays
моей первой идеей было фактически передать $DISPLAY в контейнер с опцией"- e " следующим образом:
docker run -ti -e DISPLAY=$DISPLAY name_of_docker_image
Это помогает, Но это не решит проблему. Сообщение об ошибке изменяется на:
Unable to init server: Broadway display type not supported: localhost:10.0
Error: cannot open display: localhost:10.0
после поиска в Интернете я понял, что могу сделать некоторые можно magic для исправления аутентификации. Я добавил следующее:--8-->
SOCK=/tmp/.X11-unix
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | xauth -f $XAUTH nmerge -
chmod 777 $XAUTH
docker run -ti -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH
-e XAUTHORITY=$XAUTH name_of_docker_image
однако, это работает только если добавить "--net host" в команду docker:
docker run -ti -e DISPLAY=$DISPLAY -v $XSOCK:$XSOCK -v $XAUTH:$XAUTH
-e XAUTHORITY=$XAUTH --net host name_of_docker_image
это нежелательно, так как это делает всю хост-сеть видимой для контейнера.
чего теперь не хватает, чтобы полностью запустить его на удаленном сервере в докере без "--net host"?
1 ответов
я понял. Когда вы подключаетесь к компьютеру с SSH и используете переадресацию X11, / tmp/.Для X11-Unix и не используется для связи X, и часть, связанная с $XSOCK, не нужна.
любое приложение X скорее использует имя хоста в $DISPLAY, обычно "localhost" и подключается с помощью TCP. Затем это туннелируется обратно к клиенту SSH. При использовании" --net host "для Docker" localhost " будет таким же для контейнера Docker, как и для хоста Docker, и поэтому он будет работать нормально.
если не указано "--net host", Docker использует режим сети моста по умолчанию. это означает, что "localhost" означает что-то еще внутри контейнера, чем для хоста, и X-приложения внутри контейнера не смогут видеть X-сервер, ссылаясь на "localhost". Поэтому, чтобы решить эту проблему, нужно было бы заменить "localhost" фактическим IP-адресом хоста. Обычно это "172.17.0.1" или аналогичный. Проверьте" ip addr "для интерфейса" docker0".
это можно сделать с заменой sed:
DISPLAY=`echo $DISPLAY | sed 's/^[^:]*\(.*\)/172.17.0.1/'`
кроме того, сервер SSH обычно не настроен на прием удаленных подключений к этому туннелю X11. Это должно быть изменено путем редактирования /и т. д./по ssh/sshd_config в (по крайней мере в Debian) и установка:
X11UseLocalhost no
а затем перезапустите сервер SSH и повторно войдите на сервер с помощью "ssh-X".
это почти все, но есть один осложнение слева. Если на хосте Docker запущен брандмауэр, необходимо открыть TCP-порт, связанный с туннелем X11. Номер порта-это номер между : и . в $дисплей добавлен к 6000.
чтобы получить номер порта TCP, вы можете запустить:
X11PORT=`echo $DISPLAY | sed 's/^[^:]*:\([^\.]\+\).*//'`
TCPPORT=`expr 6000 + $X11PORT`
затем (при использовании ufw как брандмауэр), откройте этот порт для контейнеров Docker в подсети 172.17.0.0:
ufw allow from 172.17.0.0/16 to any port $TCPPORT proto tcp
все команды вместе можно поставить в скрипт:
XAUTH=/tmp/.docker.xauth
xauth nlist $DISPLAY | sed -e 's/^..../ffff/' | sudo xauth -f $XAUTH nmerge -
sudo chmod 777 $XAUTH
X11PORT=`echo $DISPLAY | sed 's/^[^:]*:\([^\.]\+\).*//'`
TCPPORT=`expr 6000 + $X11PORT`
sudo ufw allow from 172.17.0.0/16 to any port $TCPPORT proto tcp
DISPLAY=`echo $DISPLAY | sed 's/^[^:]*\(.*\)/172.17.0.1/'`
sudo docker run -ti --rm -e DISPLAY=$DISPLAY -v $XAUTH:$XAUTH \
-e XAUTHORITY=$XAUTH name_of_docker_image
предполагая, что вы не корень и поэтому должны использовать sudo.
вместо sudo chmod 777 $XAUTH
вы можете:
sudo chown my_docker_container_user $XAUTH
sudo chmod 600 $XAUTH
чтобы запретить другим пользователям на сервере также иметь доступ к X-серверу, если они знают, что вы создали /tmp/.докер.auth файл для.
Я надеюсь, что это должно заставить его работать правильно для большинства сценариев.