LXC容器运行X Server(续1)

容器要运行X桌面环境可通过ssh,xdmcp远程方式,此时容器是X Client,容器是无需安装X Server.
上篇( https://blog.51cto.com/13752418/2440496 )容器中以本地方式运行X是在宿主的虚拟终端(如vt09)上运行容器X.
本文是续篇,同样容器中以本地方式运行X Server,介绍的内容是容器运行X在宿主的桌面窗口之上,容器以本地方式登录桌面环境,即界面上类似VirtualBox的方式.

实验环境 : debian 11

主机名                shell提示符
-----------------------------------------------
宿主 :  debian       [email protected]:/#
容器 :  vm1          [email protected]:/#

一.简单步骤
1.宿主
1)安装Xephyr
[email protected]:/# apt-get install xserver-xephyr

2)安装容器工具LXC
[email protected]:/# apt-get install lxc

3)创建容器
[email protected]:/# lxc-create -t debian -n vm1

创建了以debian为模版的容器,其根目录是/var/lib/lxc/vm1/rootfs/

这一制作容器的根的过程耗费较长时间,如果已有了容器,此步骤可省略.

4)进入容器
启动容器
[email protected]:/# lxc-start -n vm1 -F

或者仅仅为了容器安装软件包,用chroot容器的根即可
[email protected]:/# chroot /var/lib/lxc/vm1/rootfs/

2.容器
进入容器后

1)容器也需安装Xephyr
[email protected]:/# apt-get install xserver-xephyr

2)安装窗口管理器
[email protected]:/# apt-get install jwm

3)安装登录管理器
[email protected]:/# apt-get install xdm

4)配置xdm
将容器/etc/X11/xdm/Xservers中即在宿主/var/lib/lxc/vm1/rootfs/etc/X11/xdm/Xservers中
:0 local /usr/bin/X :0 vt7 -nolisten tcp
一行修改为
:30 local /usr/bin/Xephyr :30

修改后的行首尾:30是显示号.你可选择其它数字,但首尾显示号设置要一致,并尽量避开宿主常用显示号,特别避开0和1显示号.

5)退出容器
如是lxc-start容器的,则
[email protected]:/# poweroff

如是chroot容器的根,则
[email protected]:/# exit

3.再配置容器
回到宿主,编辑/var/lib/lxc/vm1/config文件,加上容器启动自动只读mount宿主的X Server套接字所在目录,添加下面一行
lxc.mount.entry = /tmp/.X11-unix tmp/.X11-unix none bind,ro,optional,create=dir

上面配置一行相当于在宿主手动运行命令 mount -o ro --bind /tmp/.X11-unix /var/lib/lxc/vm1/rootfs/tmp/.X11-unix

说明:
1)如果步骤1是chroot根,本步骤可在步骤2之前进行,因为chroot根仅仅切换根环境,chroot根的系统不会进行系统启动操作.

2)如果步骤1是lxc-start进入容器,因为容器是一个虚拟操作系统,容器系统启动时其操作系统会进行一系列开机初始化操作,容器poweroff正常关闭时也会进行清理操作.
经测试,有的发行版会在启动时删除/tmp下的临时文件,有的发行版会在关闭时删除/tmp下的临时文件,有的发行版根本不删除/tmp下的临时文件.
因此,如果不是只读而是可读写mount宿主的/tmp/.X11-unix目录给容器,可能会造成删除了宿主的/tmp/.X11-unix,后续的实验就无法进行,除非重启宿主主机.

总之,本步骤最好等到步骤2.容器安装软件包配置完毕后才进行,并且只读mount(为什么只读也没多大问题?见后面分析).

4.运行
在宿主以普通用户linlin登录桌面环境,打开模拟终端,运行以下命令.

1)宿主
1.1)普通用户运行下面命令
[email protected]:~$ ls /tmp/.X11-unix/
X0
X0表示存在显示号0

运行Xephyr并新建显示号1
[email protected]:~$ Xephyr :1
可见弹出一个图形界面,相当于一个屏幕,所以Xephyr也是一个X Client.为方便说明记作[Xephyr :1]

[email protected]:~$ ls /tmp/.X11-unix/
X0 X1
已可见到两个显示号0和1

切换到root用户
[email protected]:~$ su

1.2)root用户启动容器
[email protected]:/# lxc-start -n vm1 -F

2)容器
进入容器后,在模拟终端即为容器的控制台下,以root用户登录
GNU/Linux vm1 console
vm1 login: root
密码:

2.1)
[email protected]:/# ls /tmp/.X11-unix/
X0 X1
同样在容器也可见到两个显示号0和1,但这两个是宿主创建的

查看显示号环境变量

[email protected]:/# export | grep DISPLAY
[email protected]:/#

为空

启动登录管理器
[email protected]:/# DISPLAY=:1 xdm

2.2)
已成功在宿主的[Xephyr :1]生成容器的[Xephyr :30.0]并弹出xdm登录对话框图形界面,可以登录进入桌面系统.在容器里是可见到有X0、X1、X30等显示号.
在xdm登录对话框以root用户登录容器桌面,打开容器桌面的模拟终端,查看环境变量
[email protected]:/# export | grep DISPLAY
declare -x DISPLAY=":30.0"
[email protected]:/#
已是显示号30

至此,容器已经成功以本地方式运行X Server、以本地方式登录桌面环境.
但本文仍需手工输入Xephyr、xdm命令,还没能解决能一启动容器就自动弹出xdm登录对话框.

二.安全问题

因宿主共享/tmp/.X11-unix给容器,所以存在安全隐患,因此上面的容器运行X不要应用在生产环境中.

三.详尽解析
1.X Window
X Window 是一Client/Server模式,客户和服务器既可本地也可远程,X 客户和服务器的本地进程间通信是通过unix域进行.X Server启动时会在/tmp/.X11-unix目录下创建X0、X1、X2 ...之类的unix域套接字文件.

2.Xephyr
Xephyr也是一个X Server,但是它运行在一个存在的X Server里面.Xephyr既是一个普通的GUI程序又是一个X Server,常用于xdmcp远程桌面连接.

例如:远程主机192.168.1.2安装有支持xdmcp的会话登录管理器(如xdm,需配置启用xdmcp)
当前本地机器在控制台tty7运行着X Window桌面环境,要远程桌面连接远程主机,有两种方式:

方式1:传统的方式
按<ctrl><alt><f1>键,登录进入控制台tty1命令行,执行X -query 192.168.1.2 :1
上面命令没指定控制台,会自动选择控制台tty8来运行着第二个X,显示号为1
按<ctrl><alt><f8>键,便切换到控制台tty8,并弹出有远程支持xdmcp的登录窗口,就可远程登录了
早期的X Server需在root根用户下执行,现代X Server已可在非根用户下运行

方式2:Xephyr
在控制台tty7的X Window桌面环境里,打开模拟终端,执行Xephyr -query 192.168.1.2 :1
便在当前桌面环境里打开了图形界面窗口Xephyr,嵌套运行着远程主机桌面环境

本文的实验目的是在容器中以本地方式运行X,而常规的容器配置对设备的访问是受限的,在容器里运行标准的X Server会失败.而Xephyr作为X Client,只要容器里普通的X Client能运行成功,那容器里Xephyr便能运行成功.下面实验试图探出一条容器本地运行X之路.

3.命名空间
LXC容器是操作系统级的虚拟化,用于隔离了系统中的各种资源是命名空间,主要有:pid、uts、mount、net、IPC.

unix域是当作为进程间通信IPC,但却是网络编程接口socket下协议族的其中一种.而IPC命名空间好像只有System V IPC和POSIX message queues命名空间化.所以本人无法断定unix域是IPC命名空间化了还是网络命名空间化了.

下面分别单独对mount命名空间、网络命名空间、IPC命名空间进行实验,每个实验只涉及单个命名空间,不涉及叠加其它命名空间.
1)mount命名空间
有两种方式可达到mount命名空间化,也即切换根.
方式1:pivot_root
这是LXC容器是使用的方式

方式2:chroot
这是很传统的方式,下面实验用此方式

实验目的:chroot根下(即容器根/var/lib/lxc/vm1/rootfs/)运行图形界面,用X Client程序xlogo测试.

用普通用户linlin登录桌面环境,打开模拟终端su切换到根用户.

首先在宿主chroot根
[email protected]:/# chroot /var/lib/lxc/vm1/rootfs/

在chroot根下,查看环境变量DISPLAY,当前Xorg的显示号0
[email protected]:/# export | grep DISPLAY
declare -x DISPLAY=":0.0"

然后有两种方式可实现运行图形界面
1.1)方式1:获得Xorg授权
通常X Client要访问X Server(通常指桌面窗口意义上的Xorg),需获得XAUTHORITY认证授权,即使在本地.

1.1.1)在chroot根下
运行X Client程序,出现无法打开显示号的错误
[email protected]:/# xlogo
Error: Can‘t open display: :0.0

查看环境变量XAUTHORITY,可见chroot时继承linlin用户的环境变量
[email protected]:/# export | grep XAUTHORITY
declare -x XAUTHORITY="/home/linlin/.Xauthority"

重设环境变量XAUTHORITY
[email protected]:/# export XAUTHORITY="/root/.Xauthority"
[email protected]:/# export | grep XAUTHORITY
declare -x XAUTHORITY="/root/.Xauthority"

1.1.2)回到宿主,复制当前登录用户的认证授权文件到chroot根的root用户目录下
[email protected]:/# cp /home/linlin/.Xauthority /var/lib/lxc/vm1/rootfs/root/

1.1.3)回到chroot根,运行X Client程序,已成功在当前登录用户桌面窗口打开图形界面
[email protected]:/# xlogo

1.2)方式2:Xephyr免认证
1.2.1)在chroot根下
为实验目的先删除chroot根认证授权文件
[email protected]:/# rm /root/.Xauthority

运行X Client程序,出现‘无法打开显示‘错误,说明没有获得Xorg授权
[email protected]:/# xlogo
No protocol specified
xlogo: 无法打开显示:

1.2.2)回到宿主
安装X认证工具xauth
[email protected]:/# apt-get install xauth

运行Xephyr,指定显示号1,不能与Xorg的显示号冲突.这时的[Xephyr :1]既是一个普通的X Client程序又充当一个X Server,默认免认证
[email protected]:~$ Xephyr :1

查看有哪些X Server在运行
[email protected]:~$ ps -ef |grep X
root 674 634 1 13:19 tty7 00:01:37 /usr/lib/xorg/Xorg :0 -seat seat0 -auth /var/run/lightdm/root/:0 -nolisten tcp vt7 -novtswitch
linlin 3216 3211 0 15:33 pts/2 00:00:00 Xephyr :1

查看认证详情,可见只有显示号0需认证,没有显示号1
[email protected]:~$ xauth list
Using authority file /home/linlin/.Xauthority
debian/unix:0 MIT-MAGIC-COOKIE-1 e27be218c83f36a1cbab935912c70ce2

查看网络服务监听
[email protected]:/# netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 18014 719/Xorg @/tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 85267 3537/Xephyr @/tmp/.X11-unix/X1
unix 2 [ ACC ] STREAM LISTENING 18015 719/Xorg /tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 85268 3537/Xephyr /tmp/.X11-unix/X1
[email protected]:/home/linlin#

1.2.3)回到chroot根
运行xlogo,已成功在[Xephyr :1]上打开图形界面,不需认证
[email protected]:/# DISPLAY=:1 xlogo
上面xlogo命令前先指定了显示号1,当然也可先单独export显示号1再直接运行xlogo

查看chroot根是否有显示号套接字
[email protected]:/# ls /tmp/.X11-unix -a
[email protected]:/#
发现为空目录,并没有显示号套接字X0、X1、...
DISPLAY=:1的 1是指显示号1,等号和冒号之间空的应该是指使用本地unix域
如果环境变量是DISPLAY=127.0.0.1:1应该是指网络方式的显示号1

至于为什么chroot根环境不用读取显示号套接字文件就能与宿主Xephyr通信?在下面的网络命名空间化实验将体现出来.

1.2.4)回到宿主,关闭Xephyr程序

2)IPC命名空间
lxc-unshare命令可设置进入某个命名空间,参数"IPC"是进入IPC命名空间.lxc-unshare需在根用户下运行,在普通用户下运行会提示‘Operation not permitted‘错误.

2.1)
下面命令在宿主另开辟一个shell环境,并已IPC命名空间化了
[email protected]:/# lxc-unshare -s "IPC" /bin/bash

在IPC命名空间化了的shell下运行程序
2.1.1)
[email protected]:/# xlogo
也正常打开图形界面

2.1.2)查看网络服务监听
[email protected]:/# netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 18014 719/Xorg @/tmp/.X11-unix/X0
unix 2 [ ACC ] STREAM LISTENING 18015 719/Xorg /tmp/.X11-unix/X0
[email protected]:/home/linlin#

‘/tmp/.X11-unix/X0‘应是指Xorg在/tmp/.X11-unix/X0套接字文件上监听,这是unix域传统方式.
‘@/tmp/.X11-unix/X0‘前面多了个@字符,这是linux特有的unix域抽象套接字(注意:API编程时不是用@符号来表示抽象套接字,具体可man 7 unix帮助).

man 7 unix 里说
Abstract sockets automatically disappear when all open references to the socket are closed.(当所有打开套接字的引用都关闭完毕,抽象套接字会自动消失)
The abstract socket namespace is a nonportable Linux extension.(不知这里的namespace是本文所关心的操作系统级虚拟化隔离各资源的命名空间概念还是另有其意?)

传统的unix域套接字关闭时,不会自动删除套接字文件,需手动删除.

2.1.3)退出IPC命名空间化了的shell
[email protected]:/# exit

2.2)
将X0套接字文件改名为X0-bak
[email protected]:/# mv /tmp/.X11-unix/X0 /tmp/.X11-unix/X0-bak
[email protected]:/# ls /tmp/.X11-unix
X0-bak

开辟IPC命名空间化shell环境
[email protected]:/# lxc-unshare -s "IPC" /bin/bash

在IPC命名空间化了的shell下运行程序
[email protected]:/# xlogo
也正常打开图形界面

说明在IPC命名空间下并且即使没套接字文件,X 客户和服务器还能通信,但我不能确定unix域是否IPC命名空间化了.

退出IPC命名空间化了的shell
[email protected]:/# exit

将X0-bak改回为X0
[email protected]:/# mv /tmp/.X11-unix/X0-bak /tmp/.X11-unix/X0

3)网络命名空间
安装系统调用跟踪器strace
r[email protected]:/# apt-get install strace

[email protected]:/# ls /tmp/.X11-unix
X0

3.1)
下面命令在宿主另开辟一个shell环境,并已网络命名空间化了
[email protected]:/# lxc-unshare -s "NETWORK" /bin/bash

在网络命名空间化了的shell下运行程序
[email protected]:/# ifconfig
为空
[email protected]:/# ping 192.168.1.2
ping: connect: 网络不可达

[email protected]:/# xlogo
也正常打开图形界面

[email protected]:/# netstat -lp |grep X
Active UNIX domain sockets (only servers)
为空
[email protected]:/# netstat
Active Internet connections (w/o servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
Active UNIX domain sockets (w/o servers)
Proto RefCnt Flags Type State I-Node Path
为空
[email protected]:/#

退出网络命名空间化了的shell
[email protected]:/# exit

3.2)
将X0套接字文件改名为X0-bak
[email protected]:/# mv /tmp/.X11-unix/X0 /tmp/.X11-unix/X0-bak
[email protected]:/# ls /tmp/.X11-unix
X0-bak

[email protected]:/# export
...
declare -x DISPLAY=":0.0"
...
declare -x XAUTHORITY="/home/linlin/.Xauthority"
...

3.2.1)不进行命名空间化
[email protected]:/# xlogo
在这没网络命名空间化,即使没有套接字文件,也正常打开图形界面

3.2.2)xlogo进程网络命名空间化
[email protected]:/# lxc-unshare -s "NETWORK" xlogo
xlogo: 无法打开显示:

3.2.3)
开辟网络命名空间化shell环境
[email protected]:/# lxc-unshare -s "NETWORK" /bin/bash

在网络命名空间化了的shell下运行程序
[email protected]:/# xlogo
xlogo: 无法打开显示:
在找不到显示号套接字文件及网络命名空间化后,已无法打开显示

第一次跟踪调试
[email protected]:/# strace xlogo
...
connect(3, {sa_family=AF_UNIX, [email protected]"/tmp/.X11-unix/X0"}, 20) = -1 ECONNREFUSED (拒绝连接)
...
connect(3, {sa_family=AF_UNIX, sun_path="/tmp/.X11-unix/X0"}, 110) = -1 ENOENT (没有那个文件或目录)
...
connect(3, {sa_family=AF_INET, sin_port=htons(6000), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 ENETUNREACH (网络不可达)
...
write(2, "Can‘t open display: :0.0", 24Can‘t open display: :0.0) = 24
...
[email protected]:/#
跟踪结果依次尝试连接失败 [email protected]"/tmp/.X11-unix/X0" --> sun_path="/tmp/.X11-unix/X0" --> sin_addr=inet_addr("127.0.0.1")
即 抽象套接字 --> 套接字文件 --> 网络

将X0-bak改回为X0,并再进行第二次跟踪调试
[email protected]:/# mv /tmp/.X11-unix/X0-bak /tmp/.X11-unix/X0
[email protected]:/# strace xlogo
...
connect(3, {sa_family=AF_UNIX, [email protected]"/tmp/.X11-unix/X0"}, 20) = -1 ECONNREFUSED (拒绝连接)
...
connect(3, {sa_family=AF_UNIX, sun_path="/tmp/.X11-unix/X0"}, 110) = 0
getpeername(3, {sa_family=AF_UNIX, sun_path="/tmp/.X11-unix/X0"}, [124->20]) = 0
uname({sysname="Linux", nodename="debian", ...}) = 0
access("/home/linlin/.Xauthority", R_OK) = 0
openat(AT_FDCWD, "/home/linlin/.Xauthority", O_RDONLY) = 4
...
也正常打开图形界面,并且"/tmp/.X11-unix/X0"成功了,就不进行尝试"127.0.0.1"

根据两次跟踪调试结果:在网络命名空间下,[email protected]"/tmp/.X11-unix/X0" 拒绝连接,应该说明unix域Abstract sockets有网络命名空间化.
但传统sun_path="/tmp/.X11-unix/X0"在网络命名空间下只要套接字文件存在就能正常连接,不知是否说明unix域套接字文件没网络命名空间化?

这个实验同时也说明了小节1)mount命名空间实验结果:虽然chroot根环境读不了宿主/tmp/.X11-unix/下套接字文件,但因没网络命名空间化,所以仍能通过抽象套接字和宿主X Server通信.

至此,基本能找出一条容器本地运行X之路.但对于unix域是否命名空间化、属于哪个命名空间问题,本人不才,还是没能完全明白unix域命名空间化的程度.

4.小结
下表列出各命名空间对unix域的(有无)影响

             套接字文件     抽象套接字
--------------------------------------------------------------
mount       有                 无
--------------------------------------------------------------
ipc            无                 无
--------------------------------------------------------------
net            无                有
--------------------------------------------------------------

5.LXC系统容器
容器可分为:
应用容器:对某个或一组进程按需单独或组合进行命名空间化(namespace)、控制组化(cgroup).
系统容器:虚拟为操作系统,需进行彻底的资源隔离,本文的LXC容器特指系统容器.

LXC容器叠加了mount、网络等多个命名空间.容器无法读取宿主显示号套接字,无法通过抽象unix域与宿主X Server通信,唯一方法只能将宿主的/tmp/.X11-unix目录通过mount --bind共享给容器根以便读取到显示号套接字.

1)宿主
运行Xephyr并新建显示号1
[email protected]:~$ Xephyr :1

查看linlin用户uid
[email protected]:~$ id
uid=1000(linlin) gid=1000(linlin) 组=1000(linlin)
[email protected]:~$

只读共享宿主目录
[email protected]:/# mount -o ro --bind /tmp/.X11-unix /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
或者容器系统不会删除/tmp下文件,可读写mount
[email protected]:/# mount --bind /tmp/.X11-unix /var/lib/lxc/vm1/rootfs/tmp/.X11-unix

启动容器
[email protected]:/# lxc-start -n vm1 -F

2)容器
进入容器后

2.1)在模拟终端即为容器的控制台下,以root用户登录
GNU/Linux vm1 console
vm1 login: root
密码:

[email protected]:/# DISPLAY=:1 xlogo
也正常打开图形界面

试图在显示号0上运行
[email protected]:/# xlogo
No protocol specified
xlogo: 无法打开显示:
运行失败,原因显示号0是宿主的Xorg显示号,Xorg需认证授权,即使从宿主简单地复制.Xauthority到容器的../root/.Xauthority也不行.
而在小节1)mount命名空间实验里从宿主简单地复制.Xauthority到chroot根的../root/.Xauthority能成功,而容器却不行,这与.Xauthority文件里含主机名信息有关(可xauth list查看),
简单的chroot根不会改变根环境的主机名,而容器是可以另外一个主机名.
然而,是可以往宿主.Xauthority添加授权某主机认证信息,至于如何往宿主和容器两端注入授权信息,本人没实验过,不表.

另:在容器里是可以创建显示号0的套接字文件,在宿主和容器共享的/tmp/.X11-unix之下,这会覆盖掉宿主显示号0套接字文件,至于会出现什么后果,不再实验,不表.
也因此,第一章节第4)小节设置容器的xdm配置文件就不要指定显示号0.

2.2)以普通用户登录
GNU/Linux vm1 console
vm1 login: linlin
密码:

[email protected]:~$ id
uid=1000(linlin) gid=1000(linlin) 组=1000(linlin)
[email protected]:~$
这里的容器用户uid同宿主linlin用户的uid,都为1000

[email protected]:~$ DISPLAY=:1 xlogo
正常同root

[email protected]:~$ DISPLAY=:0 xlogo
也正常在显示号0上运行.
说明:宿主上是以用户linlin登录桌面,容器也同样创建了linlin用户,两者的用户uid号相同.本人猜想容器进程对宿主来说等同宿主其它普通进程,容器运行的xlogo进程用户uid就是当前宿主登录桌面用户uid相同,所以无需X认证.

2.3)要完整的运行容器本地X,容器会以不同的用户登录,所以不能仅仅凭相同uid在显示号0上运行

6.解决方案
终合上面实验,要使容器能运行X,可采取如下方案
宿主运行X Server(Xorg),宿主的Xephyr运行在X Server上;容器运行Xephyr,容器的Xephyr运行在宿主的Xephyr上,容器的X Client运行在容器的Xephyr上

即:

容器的X Client->容器的Xephyr->宿主的Xephyr->宿主X Server

7.其它
1)
xdm的很多配置文件开头好多空白行,让人误以为没东西,实际拉到后面是有内容的.
其它的登录管理器好像很死板,无法象xdm灵活.

注意:如果容器的xdm配置是指定显示号0
:0 local /usr/bin/Xephyr :0
则容器会新建的显示号0并覆盖掉共享目录下宿主显示号0,虽然宿主一般应用是没问题,但尽量避免.

2)
在显示号1上即宿主的[Xephyr :1]运行窗口管理器openbox,此步骤也可省略
[email protected]:~$ DISPLAY=:1 openbox
加运行这个窗口管理器为了容器Xephyr界面可在[Xephyr :1]里移动,方便可多个容器Xephyr界面移动来移动去.
如一个宿主Xephyr只管理一个容器则不需此命令,有两个容器就运行两个宿主Xephyr([Xephyr :1]和[Xephyr :2]).
如有容器vm1和vm2,两个容器的桌面系统都在宿主的[Xephyr :1]上,如果宿主的[Xephyr :1]没窗口管理器,则后一个的vm2桌面系统固定位置覆盖了vm1.

3)容器上外网所需的DNS地址配置
容器安装软件需连上互联网,除非通过http代理服务器上外网可不需设置DNS地址,否则必须在/etc/resolv.conf配置好DNS地址.
通常在lxc-create创建容器过程中,就已复制宿主/etc/resolv.conf的内容到容器/etc/resolv.conf,无需手工配置.也正是因如此,往往容易忽略此细节.
例如lxc-create创建的容器的/etc/resolv.conf通常是普通文件并可能没采取dhcp动态获得DNS地址,宿主的/etc/resolv.conf往往是一指向network-manager的符号链接并动态获得DNS地址.
当家里的路由器IP地址改变时,容器就因DNS地址不正确而无法获得域名解析导致上外网失败.

例如在家里通过路由器(IP 192.168.1.1)上外网,通常的DNS地址配置如下:

[email protected]:/# cat /etc/resolv.conf
nameserver 192.168.1.1
[email protected]:/#

路由器作为DNS域名服务器,路由器里配置有上级外网电信互联网服务商的DNS IP地址或某搜索引擎公司的公共DNS 8.8.8.8,家里的主机就通过此逐级DNS而获得域名解析.

当然家里主机也可直接设置外网DNS IP地址,如:

[email protected]:/# cat /etc/resolv.conf
nameserver 8.8.8.8
[email protected]:/#

4)调整桌面环境显示尺寸
容器桌面环境显示尺寸较小(默认640x480).
如果是安装好完整的桌面环境,可通过桌面环境的工具重设分辨率,会保存,下次启动系统会按新的分辨率.
如果临时调整,可用xrandr命令

容器和宿主都安装X server工具
# apt-get install x11-xserver-utils

在容器里
[email protected]:/# xrandr -s 1024x768
容器的Xephyr虚桌面变大了,但宿主的Xephyr尺寸不变,导致窗口效果尺寸不变,导致容器里一些菜单看不到了.需调整宿主Xephyr的分辨率

回到宿主,调整宿主Xephyr的尺寸与容器一致
[email protected]:~$ xrandr --display :1 -s 1024x768

或者一开始宿主就指定分辨率
[email protected]:~$ Xephyr -screen 1024x768 :1

5)在容器外即在宿主直接运行容器里的命令,需在root用户下执行lxc-attach来运行容器命令
[email protected]:/# lxc-attach -n vm1 -- env DISPLAY=:1 xdm -nodaemon &
说明:用env 设置容器里环境变量
xdm的参数-nodaemon表示非守护进程运行
加上&后台运行
这样xdm便在容器里运行,并打开xdm登录对话框

6)可写成脚本,自动寻找未用的显示号,一次启动容器桌面
[email protected]:/# lxc-info -s -n vm1 | grep RUNNING && for i in seq 99 ; do [ ! -e /tmp/.X11-unix/X$i ] && (Xephyr :$i &) && break ; done && lxc-attach -n vm1 -- env DISPLAY=:$i xdm -nodaemon &

说明:命令前面多加了判断容器是否处在运行状态RUNNING,因为不判断的话,假如容器处于冻结状态,lxc-attach执行就会处在假死状态.

7)容器只读mount宿主/tmp/.X11-unix,容器里启动的Xephyr只会创建抽象unix域,没能创建套接字文件,不过对本实验也足够了.
[email protected]:/# ls -l /tmp/.X11-unix
srwxrwxrwx 1 root root 0 9月 17 07:48 X0
srwxrwxrwx 1 linlin linlin 0 9月 17 08:01 X1
[email protected]:/# netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix 2 [ ACC ] STREAM LISTENING 28773 403/Xephyr @/tmp/.X11-unix/X30
[email protected]:/#
X0和X1是宿主的显示号套接字文件.没见容器Xephyr创建X30套接字文件,只见X30抽象unix域.

类似的Xnest、x2goserver、xpra等是否会创建抽象unix域?没测试过.

8)容器只读mount宿主/tmp/.X11-unix,容器里使用SSH客户端
以本地方式登录容器桌面系统,打开模拟终端,运行命令
[email protected]:/# export | grep DISPLAY
declare -x DISPLAY=":30.0"
[email protected]:/#
可见环境变量显示号30

容器ssh远程连接debian机器
[email protected]:/# ssh -X [email protected]
[email protected]‘s password:

[email protected]:~$ export | grep DISPLAY
declare -x DISPLAY="localhost:10.0"
[email protected]:~$ xlogo
connect /tmp/.X11-unix/X30: No such file or directory
xlogo: 无法打开显示:
[email protected]:~$
因容器没有X30套接字文件,运行图形界面失败,说明SSH客户端只连接套接字文件,而不连接抽象unix域

9)假如容器的系统不会删除/tmp下文件,可以读写mount
[email protected]:/# mount --bind /tmp/.X11-unix /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
容器里启动的Xephyr创建抽象unix域,也创建了套接字文件.系统不删除/tmp下文件,但Xephyr进程正常退出会关闭其对应的显示号并删除套接字文件.因此容器显示号尽量避开宿主显示号.

10)
如果是容器/var/lib/lxc/vm1/config文件加自动mount,在宿主是见不到容器根/var/lib/lxc/vm1/rootfs/tmp/.X11-unix里的内容,不知mount命名空间mount参数选项哪里控制到?
[email protected]:/# ls -l /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
总用量 0 ,为空目录
[email protected]:/#

如果是在宿主手动运行命令mount,在宿主是可见到挂载点/var/lib/lxc/vm1/rootfs/tmp/.X11-unix里有所共享目录的内容
[email protected]:/# ls -l /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
srwxrwxrwx 1 root root 0 9月 17 07:48 X0
srwxrwxrwx 1 linlin linlin 0 9月 17 08:01 X1

( 附:单点登录 Kerberos+LDAP 一键安装脚本 onekeysso-ver0.0.9.zip 源代码 下载地址 http://u.163.com/vvGp4X7e 提取码: TAsaIfky )
( 附:单点登录管理图形界面前端 fgsso-ver0.0.9.zip 源代码 下载地址 http://u.163.com/1Rr9zaaP 提取码: qk8gMrfr )

原文地址:https://blog.51cto.com/13752418/2461908

时间: 2024-10-11 07:30:51

LXC容器运行X Server(续1)的相关文章

Linux Container(LXC)容器隔离实现机制

一.LXC概述 LXC(LinuxContainer)是来自于Sourceforge网站上的开源项目,LXC给Linux用户提供了用户空间的工具集,用户可以通过LXC创建和管理容器,在容器中创建运行操作系统就可以有效的隔离多个操作系统,实现操作系统级的虚拟化.最初的Docker容器技术基于LXC进行构建,后来Docker在自己的内核中刨除了LXC. 二.LXC命令介绍 从Linux内核2.6.27版本开始已经支持LXC,只需要在Linux用户态安装相应的用户态工具liblxc即可.下表3-1是L

LXC容器

1.    LXC简述 Linux container是一种资源隔离机制而非虚拟化技术.VMM(VMM Virtual Machine Monitor)或者叫Hypervisor是标准的虚拟化技术,这种技术通过虚拟层(也就是VMM或叫Hypervisor),主要作用一是让多个操作系统和应用共享硬件资源, 其二是把上层虚拟机的指令转换成底层Host操作系统所认识的指令,这就意味着在Linux上可以跑windows系统,container技术介于chroot和VM之间,其“虚拟机”和主机操作系统相同

运行sql server profiler所需的权限

/********运行Sql Server Profiler所需的权限(performance)*********/ --EG.-- 使用TRACE帐户(Performancetest)跟踪Sql Server事件.-- 创建TRACE登陆帐户(Performancetest),并授予其 ALTER TRACE和VIEW SERVER STATE的权限. USE Master CREATE LOGIN Performancetest WITH PASSWORD='[email protected

在 Linux 实例上自动安装并运行 VNC Server

原文网址:https://help.aliyun.com/knowledge_detail/41181.html?spm=5176.8208715.110.11.4c184ae8mlC7Yy 您可以使用本文提供的脚本在Linux实例上自动安装并运行VNC Server,实现远程图形化管理Linux服务器.目前,该脚本仅适用于CentOS实例,会在CentOS实例中安装GNOME桌面环境. VNC Server脚本 适用镜像:目前仅适用于CentOS镜像. 使用方法:以root身份执行命令 bas

docker容器运行后退出,怎么才能一直运行?【转】

现象 启动docker容器 docker run –name [CONTAINER_NAME] [CONTAINER_ID] 查看容器运行状态 docker ps -a 发现刚刚启动的mydocker容器已经退出 原因 docker容器的主线程(dockfile中CMD执行的命令)结束,容器会退出 办法 可以使用交互式启动 docker run -i [CONTAINER_NAME or CONTAINER_ID] 上面的不太友好,建议使用后台模式和tty选项 docker run -dit [

Docker容器运行ASP.NET Core

原文:Docker容器运行ASP.NET Core 最近要学习的知识太多,都不知道先学哪些了,原本计划这篇博客是写xamarin.forms中的listview用法,关于listview的用法简书上有一篇介绍的也比较详细,所以暂时先缓一缓,属于次要任务,等以后再写.本周在万能的淘宝找了写关于区块链的教程,同时了解了下.net core.最近一两年对C#技术跟进不多,侧重点是Java,之前出.net core1.0的时候觉得.net core还不完善,所以就没学,没想到.net core这么快已经

Docker下载镜像并创建容器运行

在linux系统中安装完成docker后,我们开始进行docker的镜像.容器的使用. 在使用docker时,首先要明确的两个概念:image(镜像) 与  container (容器) image:根据官网的解释,镜像是一个为容器提供服务的独立的文件系统,它包含独立运行所需要的文件与代码. 简单地说:镜像就是一个不包含linux内核而又精简的linux系统 docker 镜像默认存储在/var/lib/docker/<storage-driver>中,现在最新版本的linux系统的存储驱动一

在Ubuntu16.04上部署LXC容器管理系统的相关步骤

打算安装一个LXC linux容器管理的软件来分配使用资源并配置不同的编程环境,这样就方便大家的使用,步骤如下(宿主机的环境都搭建好了,对应显卡的驱动等): 参考网站: 简单入门和相关指令总结:https://www.ibm.com/developerworks/cn/linux/1312_caojh_linuxlxc/index.html Linux 容器的资源管理方法:https://www.ibm.com/developerworks/cn/linux/1404_caojh_lxc/ 其他

Docker容器运行GUI程序的配置方法

0.环境说明 Ubuntu 16.04 docker 1.35 1.Docker的"可视化" Docker本身的工作模式是命令行的,因为主要的使用场景可能是做服务器后端方面的比较多. 但有时候我们会有在docker容器里运行一些图形界面的软件,或者要调用摄像头,输出图像等等一些需求,这个时候需要解决这个Docker "可视化"的问题. (这里的"可视化"不是很容易搜到的可视化管理的方法) 2.解决方案1-启动容器时添加配置选项 林帆:Docker