Encaminhar X11 por uma conexão SSH para o host do contêiner?

4

Gostaria de executar um aplicativo GUI em contêiner de uma máquina remota.

Eu não quero resolver este problema adicionando um host ssh ao container porque

  • Já tenho acesso à máquina host por SSH
  • Adiciona sobrecarga desnecessária
  • Torna o contêiner não portátil entre uso remoto e local

Já posso executar com êxito aplicativos GUI no host, mas não de dentro do contêiner. Estes são os passos que tomei até agora:

Anfitrião

  • xauth + (não a longo prazo, mas útil para eliminar possíveis problemas)
  • docker-user com o uid 501000 no host == docker-user com o uid 1000 no contêiner via recurso de namespace
  • .Xauthority arquivo copiado para docker-user home folder

Dockerfile

  • Baseado em alpino
  • Instala xauth e, para fins de teste, xterm
  • Cria docker-user com o uid / gid adequado

docker-compose

  • Variável de ambiente DISPLAY enviada em
  • Volume /home/docker-user/:/home/docker-user/:ro para fornecer .Xauthority cookie
  • Volume /tmp/.X11-unix:/tmp/.X11-unix:ro para fornecer acesso ao soquete X11
  • Executa o comando su - docker-user -c "export DISPLAY=$DISPLAY && xterm"
    • su costumava ser executado como docker-user
    • DISPLAY encaminhado para su context

Infelizmente, isso ainda não é suficiente. Enquanto o xterm no sistema operacional host se conecta ao meu servidor X local sem problemas, o xterm no container diz Xt error: Can't open display: localhost:10.0 .

Confirmei que "localhost: 10.0" está correto, localhost existe no /etc/hosts do contêiner e o cookie e o soquete estão fazendo isso com as permissões corretas.

O que mais poderia estar dando errado?

    
por M-Pixel 24.04.2017 / 06:08

3 respostas

3

Parece que você está fazendo as mesmas coisas que estou fazendo, EXCETO você está compartilhando a autoridade .Xa no momento da criação do contêiner. Isso significa que se você alguma vez ssh -X em sua máquina depois de criar o contêiner, o .Xauthority não será mais válido. Você não pode ssh -X de outro terminal na mesma máquina e voltar e usar o .Xauthority, ssh -X muda a autoridade .X toda vez para o terminal mais recente. Eu só tenho que trabalhar copiando o .Xauthority toda vez que eu ssh -X na minha máquina e tento compartilhar a tela com o meu container.

nota: estou compartilhando um dispositivo e um ID de máquina porque estava encaminhando uma saída de webcam

1.Crie o contêiner e informe ao xhost para permitir o encaminhamento do ID do contêiner:

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.Copie .Xauthority da home host para o diretório sharedDockerFiles:

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

3. Inicie e anexe seu contêiner

4. Copie o .Xauthority na sua pasta compartilhada para o container home

sudo cp /root/sharedDockerFiles/.Xauthority ~/

5. (necessário uma vez): Edite o arquivo / etc / ssh / ssh_config do contêiner em Host * para incluir:

   ForwardX11 yes
   X11Forwarding yes

6. Reinicie seu contêiner e reconecte e execute o aplicativo da GUI

7. Se você ainda tiver problemas, verifique se a variável $ DISPLAY no contêiner é a mesma que a do host .

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
    
por 10.08.2017 / 20:22
1

Copie .Xauthority no contêiner no início da sessão ssh antes de usar a GUI:

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

Depois, você pode passar o DISPLAY se estiver usando 'docker exec'. Por exemplo. para abrir o novo bash:

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

2 mais possíveis causas de erro: (além da resposta aceita)

  • basic: Você não tem servidor ssh ou xauth no container (para o ubuntu rode 'apt install opensh-server xauth')

  • sneaky one: Se o seu container hostname for diferente do host (por exemplo, set via -h badge em 'docker run') você irá obter o erro e você tem que lidar com isso (por exemplo, definir o mesmo nome de host ou adicionar cookie para xauth)

por 08.11.2017 / 17:39
0

Vamos iniciar o Docker com a opção --net = host. Isso faz com que o contêiner veja a mesma pilha de rede do host.

Por exemplo,

docker run --net = host --rm -ti -u myid -e DISPLAY="$ DISPLAY" -v /tmp/.X11-unix:/tmp/.X11-unix image: tag BINARY

    
por 02.05.2017 / 10:44