Docker本身的工作模式是命令行模式,因为主要的使用场景可能是做服务器后端方面的比较多。 但有时候我们会有在docker容器里运行一些图形界面的软件,输出图像等等一些需求,这个时候需要解决这个Docker 可视化的问题。

安装docker,并设置镜像加速器

curl -sSL https://get.daocloud.io/docker | sh
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://g5uyhrgn.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker

GUI的准备工作

  1. 在宿主机中下载x11软件并开放权限

    sudo apt-get install x11-xserver-utils
    
    xhost +  
    #是开放权限,允许所有用户,当然包括docker,访问X11 的显示接口,正常返回access control disabled, clients can connect from any host
    

xhost 是用来控制X server访问权限的。通常当我们从宿主机登陆到docker上,运行docker上的应用程序时,做为应用程序来说,宿主机是client,但是作为图形来说,是要在宿主机上显示的,需要使用宿主机的Xserver,所以宿主机是server。因此在登陆到docker前,需要在宿主机上运行xhost +来使其它用户能够访问宿主机的Xserver。xhost + 是使所有用户都能访问宿主机的Xserver.xhost + ip使ip上的用户能够访问宿主机的Xserver。

有时在执行xhost会报出以下错误

xhost:  unable to open display "XXXX"

解决方法:设置DISPLAY变量,DISPLAY用来设置将图形显示到何处,DISPLAY 环境变量格式如下hostname: displaynumber.screennumber,在某些机器上,可能有多个显示设备共享使用同一套输入设备,例如在一台PC上连接两台CRT显示器,但是它们只共享使用一个键盘和一个鼠标。这一组显示设备就拥有一个共同的displaynumber,而这组显示设备中的每个单独的设备则拥有自己单独的 screennumber。displaynumber和screennumber都是从零开始的数字。这样,对于我们普通用户来说, displaynumber、screennumber就都是0。 hostname指Xserver所在的主机主机名或者ip地址, 图形将显示在这一机器上。

export DISPLAY=:0.0
xhost +    
  1. 根据dockerfile创建image镜像

    docker build -f dockerfile -t 镜像名  .  
    
  2. 创建容器

    docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
    
    docker   run  -dit  -P  -e DISPLAY=$DISPLAY --privileged --network=host -v /tmp/.X11-unix:/tmp/.X11-unix:rw -v /dev/bus/usb:/dev/bus/usb   -v /home/lfxs/StudioData:/StudioData     --name gui01   mydb:0.1  /bin/bash
    #-d: 后台运行容器,并返回容器ID
    #-i: 以交互模式运行容器,通常与 -t 同时使用;
    #-P: 随机端口映射,容器内部端口随机映射到主机的端口
    #-p: 指定端口映射,格式为:主机(宿主)端口:容器端口
    #-e:设置环境变量
    #--privileged 是否允许Docker运行的容器拥有root权限
    #--network指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;常用bridge和host
    #-v:绑定一个卷
    #--name :容器名
    

通过ssh 连接docker,并运行GUI程序

命令:

ssh -Y 用户名@容器名 -p port 

说明:在/etc/hosts 中指定ip和容器的对应关系,添加192.168.2.68 gui01,由于network设置为hosts模式,容器和宿主机共用一个network namespaces,使用宿主机的IP和port。

然后通过命令/etc/init.d/ssh status查看宿主机和容器中ssh是否是开启的,如果没有开启使用命令

systemctl restart sshd.service

打开/etc/ssh/sshd_config,添加端口号

port=10002

重启ssh服务

/etc/init.d/ssh restart

还有以下几种方式登录docker

ssh -Y -l 用户名 ip -p port
ssh -Y 用户名@ip -p port

测试docker中GUI在宿主机上显示,在docker中下载xarclock

 sudo apt-get install xarclock
 xarclock

遇到的问题

  1. 创建容器时如果设置network为host模式时,要指定在容器中执行/bin/bash。如果不指定,可能会出现容器启动不了的问题。
  2. 修改lightmd.conf导致图形界面崩溃。
    https://blog.csdn.net/u012570215/article/details/102946670