溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

LXC容器如何以本地方式運行X Server

發(fā)布時間:2021-09-26 16:49:55 來源:億速云 閱讀:285 作者:柒染 欄目:系統(tǒng)運維

LXC容器如何以本地方式運行X Server,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。

容器要運行X桌面環(huán)境可通過ssh,xdmcp遠(yuǎn)程方式,此時容器是X Client,容器是無需安裝X Server.
容器中以本地方式運行X Server,介紹的內(nèi)容是容器運行X在宿主的桌面窗口之上,容器以本地方式登錄桌面環(huán)境,即界面上類似VirtualBox的方式.

實驗環(huán)境  : debian 11

主機名                shell提示符
-----------------------------------------------
宿主 :  debian       root@debian:/#
容器 :  vm1          root@vm1:/#

一.簡單步驟
1.宿主
1)安裝Xephyr
root@debian:/# apt-get install xserver-xephyr

2)安裝容器工具LXC
root@debian:/# apt-get install lxc

3)創(chuàng)建容器
root@debian:/# lxc-create -t debian -n vm1

創(chuàng)建了以debian為模版的容器,其根目錄是/var/lib/lxc/vm1/rootfs/

這一制作容器的根的過程耗費較長時間,如果已有了容器,此步驟可省略.

4)進(jìn)入容器
啟動容器
root@debian:/# lxc-start -n vm1 -F

或者僅僅為了容器安裝軟件包,用chroot容器的根即可
root@debian:/# chroot /var/lib/lxc/vm1/rootfs/

2.容器
進(jìn)入容器后

1)容器也需安裝Xephyr
root@vm1:/# apt-get install xserver-xephyr

2)安裝窗口管理器
root@vm1:/# apt-get install jwm

3)安裝登錄管理器
root@vm1:/# 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是顯示號.你可選擇其它數(shù)字,但首尾顯示號設(shè)置要一致,并盡量避開宿主常用顯示號,特別避開0和1顯示號.

5)退出容器
如是lxc-start容器的,則
root@vm1:/# poweroff

如是chroot容器的根,則
root@vm1:/# 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

上面配置一行相當(dāng)于在宿主手動運行命令 mount -o ro --bind /tmp/.X11-unix /var/lib/lxc/vm1/rootfs/tmp/.X11-unix

說明:
1)如果步驟1是chroot根,本步驟可在步驟2之前進(jìn)行,因為chroot根僅僅切換根環(huán)境,chroot根的系統(tǒng)不會進(jìn)行系統(tǒng)啟動操作.

2)如果步驟1是lxc-start進(jìn)入容器,因為容器是一個虛擬操作系統(tǒng),容器系統(tǒng)啟動時其操作系統(tǒng)會進(jìn)行一系列開機初始化操作,容器poweroff正常關(guān)閉時也會進(jìn)行清理操作.
經(jīng)測試,有的發(fā)行版會在啟動時刪除/tmp下的臨時文件,有的發(fā)行版會在關(guān)閉時刪除/tmp下的臨時文件,有的發(fā)行版根本不刪除/tmp下的臨時文件.
因此,如果不是只讀而是可讀寫mount宿主的/tmp/.X11-unix目錄給容器,可能會造成刪除了宿主的/tmp/.X11-unix,后續(xù)的實驗就無法進(jìn)行,除非重啟宿主主機.

總之,本步驟最好等到步驟2.容器安裝軟件包配置完畢后才進(jìn)行,并且只讀mount(為什么只讀也沒多大問題?見后面分析).

4.運行
在宿主以普通用戶linlin登錄桌面環(huán)境,打開模擬終端,運行以下命令.

1)宿主
1.1)普通用戶運行下面命令
linlin@debian:~$ ls /tmp/.X11-unix/
X0
X0表示存在顯示號0

運行Xephyr并新建顯示號1
linlin@debian:~$ Xephyr :1
可見彈出一個圖形界面,相當(dāng)于一個屏幕,所以Xephyr也是一個X Client.為方便說明記作[Xephyr :1]

linlin@debian:~$ ls /tmp/.X11-unix/
X0  X1
已可見到兩個顯示號0和1

切換到root用戶
linlin@debian:~$ su

1.2)root用戶啟動容器
root@debian:/# lxc-start -n vm1 -F

2)容器
進(jìn)入容器后,在模擬終端即為容器的控制臺下,以root用戶登錄
GNU/Linux vm1 console
vm1 login: root
密碼:

2.1)
root@vm1:/# ls /tmp/.X11-unix/
X0  X1
同樣在容器也可見到兩個顯示號0和1,但這兩個是宿主創(chuàng)建的

查看顯示號環(huán)境變量

root@vm1:/# export | grep DISPLAY
root@vm1:/#

為空

啟動登錄管理器
root@vm1:/# DISPLAY=:1 xdm

2.2)
已成功在宿主的[Xephyr :1]生成容器的[Xephyr :30.0]并彈出xdm登錄對話框圖形界面,可以登錄進(jìn)入桌面系統(tǒng).在容器里是可見到有X0、X1、X30等顯示號.
在xdm登錄對話框以root用戶登錄容器桌面,打開容器桌面的模擬終端,查看環(huán)境變量
root@vm1:/# export | grep DISPLAY
declare -x DISPLAY=":30.0"
root@vm1:/#
已是顯示號30

至此,容器已經(jīng)成功以本地方式運行X Server、以本地方式登錄桌面環(huán)境.
但本文仍需手工輸入Xephyr、xdm命令,還沒能解決能一啟動容器就自動彈出xdm登錄對話框.

二.安全問題

因宿主共享/tmp/.X11-unix給容器,所以存在安全隱患,因此上面的容器運行X不要應(yīng)用在生產(chǎn)環(huán)境中.

三.詳盡解析
1.X Window
X Window 是一Client/Server模式,客戶和服務(wù)器既可本地也可遠(yuǎn)程,X 客戶和服務(wù)器的本地進(jìn)程間通信是通過unix域進(jìn)行.X Server啟動時會在/tmp/.X11-unix目錄下創(chuàng)建X0、X1、X2 ...之類的unix域套接字文件.

2.Xephyr
Xephyr也是一個X Server,但是它運行在一個存在的X Server里面.Xephyr既是一個普通的GUI程序又是一個X Server,常用于xdmcp遠(yuǎn)程桌面連接.

例如:遠(yuǎn)程主機192.168.1.2安裝有支持xdmcp的會話登錄管理器(如xdm,需配置啟用xdmcp)
當(dāng)前本地機器在控制臺tty7運行著X Window桌面環(huán)境,要遠(yuǎn)程桌面連接遠(yuǎn)程主機,有兩種方式:

方式1:傳統(tǒng)的方式
按<ctrl><alt><f1>鍵,登錄進(jìn)入控制臺tty1命令行,執(zhí)行X -query 192.168.1.2 :1
上面命令沒指定控制臺,會自動選擇控制臺tty8來運行著第二個X,顯示號為1  
按<ctrl><alt><f8>鍵,便切換到控制臺tty8,并彈出有遠(yuǎn)程支持xdmcp的登錄窗口,就可遠(yuǎn)程登錄了
早期的X Server需在root根用戶下執(zhí)行,現(xiàn)代X Server已可在非根用戶下運行

方式2:Xephyr
在控制臺tty7的X Window桌面環(huán)境里,打開模擬終端,執(zhí)行Xephyr -query 192.168.1.2 :1
便在當(dāng)前桌面環(huán)境里打開了圖形界面窗口Xephyr,嵌套運行著遠(yuǎn)程主機桌面環(huán)境

本文的實驗?zāi)康氖窃谌萜髦幸员镜胤绞竭\行X,而常規(guī)的容器配置對設(shè)備的訪問是受限的,在容器里運行標(biāo)準(zhǔn)的X Server會失敗.而Xephyr作為X Client,只要容器里普通的X Client能運行成功,那容器里Xephyr便能運行成功.下面實驗試圖探出一條容器本地運行X之路.

3.命名空間
LXC容器是操作系統(tǒng)級的虛擬化,用于隔離了系統(tǒng)中的各種資源是命名空間,主要有:pid、uts、mount、net、IPC.

unix域是當(dāng)作為進(jìn)程間通信IPC,但卻是網(wǎng)絡(luò)編程接口socket下協(xié)議族的其中一種.而IPC命名空間好像只有System V IPC和POSIX message queues命名空間化.所以本人無法斷定unix域是IPC命名空間化了還是網(wǎng)絡(luò)命名空間化了.

下面分別單獨對mount命名空間、網(wǎng)絡(luò)命名空間、IPC命名空間進(jìn)行實驗,每個實驗只涉及單個命名空間,不涉及疊加其它命名空間.
1)mount命名空間
有兩種方式可達(dá)到mount命名空間化,也即切換根.
方式1:pivot_root
這是LXC容器是使用的方式

方式2:chroot
這是很傳統(tǒng)的方式,下面實驗用此方式

實驗?zāi)康?chroot根下(即容器根/var/lib/lxc/vm1/rootfs/)運行圖形界面,用X Client程序xlogo測試.

用普通用戶linlin登錄桌面環(huán)境,打開模擬終端su切換到根用戶.

首先在宿主chroot根
root@debian:/# chroot /var/lib/lxc/vm1/rootfs/

在chroot根下,查看環(huán)境變量DISPLAY,當(dāng)前Xorg的顯示號0
root@vm1:/# export | grep DISPLAY
declare -x DISPLAY=":0.0"

然后有兩種方式可實現(xiàn)運行圖形界面
1.1)方式1:獲得Xorg授權(quán)  
通常X Client要訪問X Server(通常指桌面窗口意義上的Xorg),需獲得XAUTHORITY認(rèn)證授權(quán),即使在本地.

1.1.1)在chroot根下
運行X Client程序,出現(xiàn)無法打開顯示號的錯誤
root@vm1:/# xlogo
Error: Can't open display: :0.0

查看環(huán)境變量XAUTHORITY,可見chroot時繼承l(wèi)inlin用戶的環(huán)境變量
root@vm1:/# export | grep XAUTHORITY
declare -x XAUTHORITY="/home/linlin/.Xauthority"

重設(shè)環(huán)境變量XAUTHORITY
root@vm1:/# export XAUTHORITY="/root/.Xauthority"
root@vm1:/# export | grep XAUTHORITY
declare -x XAUTHORITY="/root/.Xauthority"

1.1.2)回到宿主,復(fù)制當(dāng)前登錄用戶的認(rèn)證授權(quán)文件到chroot根的root用戶目錄下
root@debian:/# cp /home/linlin/.Xauthority /var/lib/lxc/vm1/rootfs/root/

1.1.3)回到chroot根,運行X Client程序,已成功在當(dāng)前登錄用戶桌面窗口打開圖形界面
root@vm1:/# xlogo

1.2)方式2:Xephyr免認(rèn)證
1.2.1)在chroot根下
為實驗?zāi)康南葎h除chroot根認(rèn)證授權(quán)文件
root@vm1:/# rm /root/.Xauthority

運行X Client程序,出現(xiàn)'無法打開顯示'錯誤,說明沒有獲得Xorg授權(quán)
root@vm1:/# xlogo
No protocol specified
xlogo: 無法打開顯示:

1.2.2)回到宿主
安裝X認(rèn)證工具xauth
root@debian:/# apt-get install xauth

運行Xephyr,指定顯示號1,不能與Xorg的顯示號沖突.這時的[Xephyr :1]既是一個普通的X Client程序又充當(dāng)一個X Server,默認(rèn)免認(rèn)證
linlin@debian:~$ Xephyr :1

查看有哪些X Server在運行
linlin@debian:~$ 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

查看認(rèn)證詳情,可見只有顯示號0需認(rèn)證,沒有顯示號1
linlin@debian:~$ xauth list
Using authority file /home/linlin/.Xauthority
debian/unix:0  MIT-MAGIC-COOKIE-1  e27be218c83f36a1cbab935912c70ce2

查看網(wǎng)絡(luò)服務(wù)監(jiān)聽
root@debian:/# 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
root@debian:/home/linlin#

1.2.3)回到chroot根
運行xlogo,已成功在[Xephyr :1]上打開圖形界面,不需認(rèn)證
root@vm1:/# DISPLAY=:1 xlogo
上面xlogo命令前先指定了顯示號1,當(dāng)然也可先單獨export顯示號1再直接運行xlogo

查看chroot根是否有顯示號套接字
root@vm1:/# ls /tmp/.X11-unix -a
root@vm1:/#
發(fā)現(xiàn)為空目錄,并沒有顯示號套接字X0、X1、...
DISPLAY=:1的 1是指顯示號1,等號和冒號之間空的應(yīng)該是指使用本地unix域
如果環(huán)境變量是DISPLAY=127.0.0.1:1應(yīng)該是指網(wǎng)絡(luò)方式的顯示號1

至于為什么chroot根環(huán)境不用讀取顯示號套接字文件就能與宿主Xephyr通信?在下面的網(wǎng)絡(luò)命名空間化實驗將體現(xiàn)出來.

1.2.4)回到宿主,關(guān)閉Xephyr程序

2)IPC命名空間
lxc-unshare命令可設(shè)置進(jìn)入某個命名空間,參數(shù)"IPC"是進(jìn)入IPC命名空間.lxc-unshare需在根用戶下運行,在普通用戶下運行會提示'Operation not permitted'錯誤.

2.1)
下面命令在宿主另開辟一個shell環(huán)境,并已IPC命名空間化了
root@debian:/# lxc-unshare -s "IPC" /bin/bash

在IPC命名空間化了的shell下運行程序
2.1.1)
root@debian:/# xlogo
也正常打開圖形界面

2.1.2)查看網(wǎng)絡(luò)服務(wù)監(jiān)聽
root@debian:/# 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
root@debian:/home/linlin#

'/tmp/.X11-unix/X0'應(yīng)是指Xorg在/tmp/.X11-unix/X0套接字文件上監(jiān)聽,這是unix域傳統(tǒng)方式.
'@/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.(當(dāng)所有打開套接字的引用都關(guān)閉完畢,抽象套接字會自動消失)
The abstract socket namespace is a nonportable Linux extension.(不知這里的namespace是本文所關(guān)心的操作系統(tǒng)級虛擬化隔離各資源的命名空間概念還是另有其意?)

傳統(tǒng)的unix域套接字關(guān)閉時,不會自動刪除套接字文件,需手動刪除.

2.1.3)退出IPC命名空間化了的shell
root@debian:/# exit

2.2)
將X0套接字文件改名為X0-bak
root@debian:/# mv /tmp/.X11-unix/X0 /tmp/.X11-unix/X0-bak
root@debian:/# ls /tmp/.X11-unix
X0-bak

開辟IPC命名空間化shell環(huán)境
root@debian:/# lxc-unshare -s "IPC" /bin/bash

在IPC命名空間化了的shell下運行程序
root@debian:/# xlogo
也正常打開圖形界面

說明在IPC命名空間下并且即使沒套接字文件,X 客戶和服務(wù)器還能通信,但我不能確定unix域是否IPC命名空間化了.

退出IPC命名空間化了的shell
root@debian:/# exit

將X0-bak改回為X0
root@debian:/# mv /tmp/.X11-unix/X0-bak /tmp/.X11-unix/X0

3)網(wǎng)絡(luò)命名空間
安裝系統(tǒng)調(diào)用跟蹤器strace
root@debian:/# apt-get install strace

root@debian:/# ls /tmp/.X11-unix
X0

3.1)
下面命令在宿主另開辟一個shell環(huán)境,并已網(wǎng)絡(luò)命名空間化了
root@debian:/# lxc-unshare -s "NETWORK" /bin/bash

在網(wǎng)絡(luò)命名空間化了的shell下運行程序
root@debian:/# ifconfig
為空
root@debian:/# ping 192.168.1.2
ping: connect: 網(wǎng)絡(luò)不可達(dá)

root@debian:/# xlogo
也正常打開圖形界面

root@debian:/# netstat -lp |grep X
Active UNIX domain sockets (only servers)
為空
root@debian:/# 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
為空
root@debian:/#

退出網(wǎng)絡(luò)命名空間化了的shell
root@debian:/# exit

3.2)
將X0套接字文件改名為X0-bak
root@debian:/# mv /tmp/.X11-unix/X0 /tmp/.X11-unix/X0-bak
root@debian:/# ls /tmp/.X11-unix
X0-bak

root@debian:/# export
...
declare -x DISPLAY=":0.0"
...
declare -x XAUTHORITY="/home/linlin/.Xauthority"
...

3.2.1)不進(jìn)行命名空間化
root@debian:/# xlogo
在這沒網(wǎng)絡(luò)命名空間化,即使沒有套接字文件,也正常打開圖形界面

3.2.2)xlogo進(jìn)程網(wǎng)絡(luò)命名空間化
root@debian:/# lxc-unshare -s "NETWORK" xlogo
xlogo: 無法打開顯示:

3.2.3)
開辟網(wǎng)絡(luò)命名空間化shell環(huán)境
root@debian:/# lxc-unshare -s "NETWORK" /bin/bash

在網(wǎng)絡(luò)命名空間化了的shell下運行程序
root@debian:/# xlogo
xlogo: 無法打開顯示:
在找不到顯示號套接字文件及網(wǎng)絡(luò)命名空間化后,已無法打開顯示

第一次跟蹤調(diào)試
root@debian:/# strace xlogo
...
connect(3, {sa_family=AF_UNIX, sun_path=@"/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 (網(wǎng)絡(luò)不可達(dá))
...
write(2, "Can't open display: :0.0", 24Can't open display: :0.0) = 24
...
root@debian:/#
跟蹤結(jié)果依次嘗試連接失敗  sun_path=@"/tmp/.X11-unix/X0" --> sun_path="/tmp/.X11-unix/X0" --> sin_addr=inet_addr("127.0.0.1")
即  抽象套接字 --> 套接字文件 --> 網(wǎng)絡(luò)

將X0-bak改回為X0,并再進(jìn)行第二次跟蹤調(diào)試
root@debian:/# mv /tmp/.X11-unix/X0-bak /tmp/.X11-unix/X0
root@debian:/# strace xlogo
...
connect(3, {sa_family=AF_UNIX, sun_path=@"/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"成功了,就不進(jìn)行嘗試"127.0.0.1"

根據(jù)兩次跟蹤調(diào)試結(jié)果:在網(wǎng)絡(luò)命名空間下,sun_path=@"/tmp/.X11-unix/X0" 拒絕連接,應(yīng)該說明unix域Abstract sockets有網(wǎng)絡(luò)命名空間化.
但傳統(tǒng)sun_path="/tmp/.X11-unix/X0"在網(wǎng)絡(luò)命名空間下只要套接字文件存在就能正常連接,不知是否說明unix域套接字文件沒網(wǎng)絡(luò)命名空間化?

這個實驗同時也說明了小節(jié)1)mount命名空間實驗結(jié)果:雖然chroot根環(huán)境讀不了宿主/tmp/.X11-unix/下套接字文件,但因沒網(wǎng)絡(luò)命名空間化,所以仍能通過抽象套接字和宿主X Server通信.

至此,基本能找出一條容器本地運行X之路.但對于unix域是否命名空間化、屬于哪個命名空間問題,本人不才,還是沒能完全明白unix域命名空間化的程度.

4.小結(jié)
下表列出各命名空間對unix域的(有無)影響

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

5.LXC系統(tǒng)容器
容器可分為:
應(yīng)用容器:對某個或一組進(jìn)程按需單獨或組合進(jìn)行命名空間化(namespace)、控制組化(cgroup).
系統(tǒng)容器:虛擬為操作系統(tǒng),需進(jìn)行徹底的資源隔離,本文的LXC容器特指系統(tǒng)容器.

LXC容器疊加了mount、網(wǎng)絡(luò)等多個命名空間.容器無法讀取宿主顯示號套接字,無法通過抽象unix域與宿主X Server通信,唯一方法只能將宿主的/tmp/.X11-unix目錄通過mount --bind共享給容器根以便讀取到顯示號套接字.

1)宿主
運行Xephyr并新建顯示號1
linlin@debian:~$ Xephyr :1

查看linlin用戶uid
linlin@debian:~$ id
uid=1000(linlin) gid=1000(linlin) 組=1000(linlin)
linlin@debian:~$

只讀共享宿主目錄
root@debian:/# mount -o ro --bind /tmp/.X11-unix  /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
或者容器系統(tǒng)不會刪除/tmp下文件,可讀寫mount
root@debian:/# mount --bind /tmp/.X11-unix  /var/lib/lxc/vm1/rootfs/tmp/.X11-unix

啟動容器
root@debian:/# lxc-start -n vm1 -F

2)容器
進(jìn)入容器后

2.1)在模擬終端即為容器的控制臺下,以root用戶登錄
GNU/Linux vm1 console
vm1 login: root
密碼:

root@vm1:/# DISPLAY=:1 xlogo
也正常打開圖形界面

試圖在顯示號0上運行
root@vm1:/# xlogo
No protocol specified
xlogo: 無法打開顯示:
運行失敗,原因顯示號0是宿主的Xorg顯示號,Xorg需認(rèn)證授權(quán),即使從宿主簡單地復(fù)制.Xauthority到容器的../root/.Xauthority也不行.
而在小節(jié)1)mount命名空間實驗里從宿主簡單地復(fù)制.Xauthority到chroot根的../root/.Xauthority能成功,而容器卻不行,這與.Xauthority文件里含主機名信息有關(guān)(可xauth list查看),
簡單的chroot根不會改變根環(huán)境的主機名,而容器是可以另外一個主機名.
然而,是可以往宿主.Xauthority添加授權(quán)某主機認(rèn)證信息,至于如何往宿主和容器兩端注入授權(quán)信息,本人沒實驗過,不表.

另:在容器里是可以創(chuàng)建顯示號0的套接字文件,在宿主和容器共享的/tmp/.X11-unix之下,這會覆蓋掉宿主顯示號0套接字文件,至于會出現(xiàn)什么后果,不再實驗,不表.
也因此,第一章節(jié)第4)小節(jié)設(shè)置容器的xdm配置文件就不要指定顯示號0.

2.2)以普通用戶登錄
GNU/Linux vm1 console
vm1 login: linlin
密碼:

linlin@vm1:~$ id
uid=1000(linlin) gid=1000(linlin) 組=1000(linlin)
linlin@vm1:~$
這里的容器用戶uid同宿主linlin用戶的uid,都為1000

linlin@vm1:~$ DISPLAY=:1 xlogo
正常同root

linlin@vm1:~$ DISPLAY=:0 xlogo
也正常在顯示號0上運行.
說明:宿主上是以用戶linlin登錄桌面,容器也同樣創(chuàng)建了linlin用戶,兩者的用戶uid號相同.本人猜想容器進(jìn)程對宿主來說等同宿主其它普通進(jìn)程,容器運行的xlogo進(jìn)程用戶uid就是當(dāng)前宿主登錄桌面用戶uid相同,所以無需X認(rèn)證.

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的很多配置文件開頭好多空白行,讓人誤以為沒東西,實際拉到后面是有內(nèi)容的.
其它的登錄管理器好像很死板,無法象xdm靈活.

注意:如果容器的xdm配置是指定顯示號0
:0 local /usr/bin/Xephyr :0
則容器會新建的顯示號0并覆蓋掉共享目錄下宿主顯示號0,雖然宿主一般應(yīng)用是沒問題,但盡量避免.

2)
在顯示號1上即宿主的[Xephyr :1]運行窗口管理器openbox,此步驟也可省略
linlin@debian:~$ DISPLAY=:1 openbox
加運行這個窗口管理器為了容器Xephyr界面可在[Xephyr :1]里移動,方便可多個容器Xephyr界面移動來移動去.
如一個宿主Xephyr只管理一個容器則不需此命令,有兩個容器就運行兩個宿主Xephyr([Xephyr :1]和[Xephyr :2]).
如有容器vm1和vm2,兩個容器的桌面系統(tǒng)都在宿主的[Xephyr :1]上,如果宿主的[Xephyr :1]沒窗口管理器,則后一個的vm2桌面系統(tǒng)固定位置覆蓋了vm1.

3)容器上外網(wǎng)所需的DNS地址配置
容器安裝軟件需連上互聯(lián)網(wǎng),除非通過http代理服務(wù)器上外網(wǎng)可不需設(shè)置DNS地址,否則必須在/etc/resolv.conf配置好DNS地址.
通常在lxc-create創(chuàng)建容器過程中,就已復(fù)制宿主/etc/resolv.conf的內(nèi)容到容器/etc/resolv.conf,無需手工配置.也正是因如此,往往容易忽略此細(xì)節(jié).
例如lxc-create創(chuàng)建的容器的/etc/resolv.conf通常是普通文件并可能沒采取dhcp動態(tài)獲得DNS地址,宿主的/etc/resolv.conf往往是一指向network-manager的符號鏈接并動態(tài)獲得DNS地址.
當(dāng)家里的路由器IP地址改變時,容器就因DNS地址不正確而無法獲得域名解析導(dǎo)致上外網(wǎng)失敗.

例如在家里通過路由器(IP 192.168.1.1)上外網(wǎng),通常的DNS地址配置如下:

root@vm1:/# cat /etc/resolv.conf
nameserver 192.168.1.1
root@vm1:/#

路由器作為DNS域名服務(wù)器,路由器里配置有上級外網(wǎng)電信互聯(lián)網(wǎng)服務(wù)商的DNS IP地址或某搜索引擎公司的公共DNS 8.8.8.8,家里的主機就通過此逐級DNS而獲得域名解析.

當(dāng)然家里主機也可直接設(shè)置外網(wǎng)DNS IP地址,如:

root@vm1:/# cat /etc/resolv.conf
nameserver 8.8.8.8
root@vm1:/#

4)調(diào)整桌面環(huán)境顯示尺寸
容器桌面環(huán)境顯示尺寸較小(默認(rèn)640x480).
如果是安裝好完整的桌面環(huán)境,可通過桌面環(huán)境的工具重設(shè)分辨率,會保存,下次啟動系統(tǒng)會按新的分辨率.
如果臨時調(diào)整,可用xrandr命令

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

在容器里
root@vm1:/# xrandr -s 1024x768
容器的Xephyr虛桌面變大了,但宿主的Xephyr尺寸不變,導(dǎo)致窗口效果尺寸不變,導(dǎo)致容器里一些菜單看不到了.需調(diào)整宿主Xephyr的分辨率

回到宿主,調(diào)整宿主Xephyr的尺寸與容器一致
linlin@debian:~$ xrandr --display :1 -s 1024x768

或者一開始宿主就指定分辨率
linlin@debian:~$ Xephyr -screen 1024x768 :1

5)在容器外即在宿主直接運行容器里的命令,需在root用戶下執(zhí)行l(wèi)xc-attach來運行容器命令
root@debian:/# lxc-attach -n vm1 -- env DISPLAY=:1   xdm -nodaemon &
說明:用env 設(shè)置容器里環(huán)境變量
xdm的參數(shù)-nodaemon表示非守護(hù)進(jìn)程運行
加上&后臺運行
這樣xdm便在容器里運行,并打開xdm登錄對話框

6)可寫成腳本,自動尋找未用的顯示號,一次啟動容器桌面
root@debian:/# 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 &

說明:命令前面多加了判斷容器是否處在運行狀態(tài)RUNNING,因為不判斷的話,假如容器處于凍結(jié)狀態(tài),lxc-attach執(zhí)行就會處在假死狀態(tài).

7)容器只讀mount宿主/tmp/.X11-unix,容器里啟動的Xephyr只會創(chuàng)建抽象unix域,沒能創(chuàng)建套接字文件,不過對本實驗也足夠了.
root@vm1:/# 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
root@vm1:/# netstat -lp |grep X
Active UNIX domain sockets (only servers)
unix  2      [ ACC ]     STREAM     LISTENING     28773    403/Xephyr           @/tmp/.X11-unix/X30
root@vm1:/#
X0和X1是宿主的顯示號套接字文件.沒見容器Xephyr創(chuàng)建X30套接字文件,只見X30抽象unix域.

類似的Xnest、x2goserver、xpra等是否會創(chuàng)建抽象unix域?沒測試過.

8)容器只讀mount宿主/tmp/.X11-unix,容器里使用SSH客戶端
以本地方式登錄容器桌面系統(tǒng),打開模擬終端,運行命令
root@vm1:/# export | grep DISPLAY
declare -x DISPLAY=":30.0"
root@vm1:/#
可見環(huán)境變量顯示號30

容器ssh遠(yuǎn)程連接debian機器
root@vm1:/# ssh -X linlin@debian
linlin@debian's password:

linlin@debian:~$ export | grep DISPLAY
declare -x DISPLAY="localhost:10.0"
linlin@debian:~$ xlogo
connect /tmp/.X11-unix/X30: No such file or directory
xlogo: 無法打開顯示:
linlin@debian:~$
因容器沒有X30套接字文件,運行圖形界面失敗,說明SSH客戶端只連接套接字文件,而不連接抽象unix域

9)假如容器的系統(tǒng)不會刪除/tmp下文件,可以讀寫mount
root@debian:/# mount --bind /tmp/.X11-unix  /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
容器里啟動的Xephyr創(chuàng)建抽象unix域,也創(chuàng)建了套接字文件.系統(tǒng)不刪除/tmp下文件,但Xephyr進(jìn)程正常退出會關(guān)閉其對應(yīng)的顯示號并刪除套接字文件.因此容器顯示號盡量避開宿主顯示號.

10)
如果是容器/var/lib/lxc/vm1/config文件加自動mount,在宿主是見不到容器根/var/lib/lxc/vm1/rootfs/tmp/.X11-unix里的內(nèi)容,不知mount命名空間mount參數(shù)選項哪里控制到?
root@debian:/# ls -l /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
總用量 0 ,為空目錄
root@debian:/#

如果是在宿主手動運行命令mount,在宿主是可見到掛載點/var/lib/lxc/vm1/rootfs/tmp/.X11-unix里有所共享目錄的內(nèi)容
root@debian:/# 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

看完上述內(nèi)容,你們掌握LXC容器如何以本地方式運行X Server的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

lxc
AI