LXC容器運行X Server(續1)

容器要運行X桌面環境可經過ssh,xdmcp遠程方式,此時容器是X Client,容器是無需安裝X Server.
上篇( http://www.javashuo.com/article/p-pzrnqawu-ks.html )容器中以本地方式運行X是在宿主的虛擬終端(如vt09)上運行容器X.
本文是續篇,一樣容器中以本地方式運行X Server,介紹的內容是容器運行X在宿主的桌面窗口之上,容器以本地方式登陸桌面環境,即界面上相似VirtualBox的方式.前端

實驗環境 : debian 11node

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

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

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

3)建立容器
root@debian:/# lxc-create -t debian -n vm1編程

建立了以debian爲模版的容器,其根目錄是/var/lib/lxc/vm1/rootfs/安全

這一製做容器的根的過程耗費較長時間,若是已有了容器,此步驟可省略.bash

4)進入容器
啓動容器
root@debian:/# lxc-start -n vm1 -F服務器

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

2.容器
進入容器後app

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是顯示號.你可選擇其它數字,但首尾顯示號設置要一致,並儘可能避開宿主經常使用顯示號,特別避開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

上面配置一行至關於在宿主手動運行命令 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)普通用戶運行下面命令
linlin@debian:~$ ls /tmp/.X11-unix/
X0
X0表示存在顯示號0

運行Xephyr並新建顯示號1
linlin@debian:~$ Xephyr :1
可見彈出一個圖形界面,至關於一個屏幕,因此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)容器
進入容器後,在模擬終端即爲容器的控制檯下,以root用戶登陸
GNU/Linux vm1 console
vm1 login: root
密碼:

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

查看顯示號環境變量

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

爲空

啓動登陸管理器
root@vm1:/# DISPLAY=:1 xdm

2.2)
已成功在宿主的[Xephyr :1]生成容器的[Xephyr :30.0]並彈出xdm登陸對話框圖形界面,能夠登陸進入桌面系統.在容器裏是可見到有X0、X一、X30等顯示號.
在xdm登陸對話框以root用戶登陸容器桌面,打開容器桌面的模擬終端,查看環境變量
root@vm1:/# export | grep DISPLAY
declare -x DISPLAY=":30.0"
root@vm1:/#
已經是顯示號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、X一、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根
root@debian:/# chroot /var/lib/lxc/vm1/rootfs/

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

而後有兩種方式可實現運行圖形界面
1.1)方式1:得到Xorg受權
一般X Client要訪問X Server(一般指桌面窗口意義上的Xorg),需得到XAUTHORITY認證受權,即便在本地.

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

查看環境變量XAUTHORITY,可見chroot時繼承linlin用戶的環境變量
root@vm1:/# export | grep XAUTHORITY
declare -x XAUTHORITY="/home/linlin/.Xauthority"

重設環境變量XAUTHORITY
root@vm1:/# export XAUTHORITY="/root/.Xauthority"
root@vm1:/# export | grep XAUTHORITY
declare -x XAUTHORITY="/root/.Xauthority"

1.1.2)回到宿主,複製當前登陸用戶的認證受權文件到chroot根的root用戶目錄下
root@debian:/# cp /home/linlin/.Xauthority /var/lib/lxc/vm1/rootfs/root/

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

1.2)方式2:Xephyr免認證
1.2.1)在chroot根下
爲實驗目的先刪除chroot根認證受權文件
root@vm1:/# rm /root/.Xauthority

運行X Client程序,出現'沒法打開顯示'錯誤,說明沒有得到Xorg受權
root@vm1:/# xlogo
No protocol specified
xlogo: 沒法打開顯示:

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

運行Xephyr,指定顯示號1,不能與Xorg的顯示號衝突.這時的[Xephyr :1]既是一個普通的X Client程序又充當一個X Server,默認免認證
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

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

查看網絡服務監聽
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]上打開圖形界面,不需認證
root@vm1:/# DISPLAY=:1 xlogo
上面xlogo命令前先指定了顯示號1,固然也可先單獨export顯示號1再直接運行xlogo

查看chroot根是否有顯示號套接字
root@vm1:/# ls /tmp/.X11-unix -a
root@vm1:/#
發現爲空目錄,並無顯示號套接字X0、X一、...
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命名空間化了
root@debian:/# lxc-unshare -s "IPC" /bin/bash

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

2.1.2)查看網絡服務監聽
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'應是指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
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環境
root@debian:/# lxc-unshare -s "IPC" /bin/bash

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

說明在IPC命名空間下而且即便沒套接字文件,X 客戶和服務器還能通訊,但我不能肯定unix域是否IPC命名空間化了.

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

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

3)網絡命名空間
安裝系統調用跟蹤器strace
root@debian:/# apt-get install strace

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

3.1)
下面命令在宿主另開闢一個shell環境,並已網絡命名空間化了
root@debian:/# lxc-unshare -s "NETWORK" /bin/bash

在網絡命名空間化了的shell下運行程序
root@debian:/# ifconfig
爲空
root@debian:/# ping 192.168.1.2
ping: connect: 網絡不可達

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:/#

退出網絡命名空間化了的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)不進行命名空間化
root@debian:/# xlogo
在這沒網絡命名空間化,即便沒有套接字文件,也正常打開圖形界面

3.2.2)xlogo進程網絡命名空間化
root@debian:/# lxc-unshare -s "NETWORK" xlogo
xlogo: 沒法打開顯示:

3.2.3)
開闢網絡命名空間化shell環境
root@debian:/# lxc-unshare -s "NETWORK" /bin/bash

在網絡命名空間化了的shell下運行程序
root@debian:/# xlogo
xlogo: 沒法打開顯示:
在找不到顯示號套接字文件及網絡命名空間化後,已沒法打開顯示

第一次跟蹤調試
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 (網絡不可達)
...
write(2, "Can't open display: :0.0", 24Can't open display: :0.0) = 24
...
root@debian:/#
跟蹤結果依次嘗試鏈接失敗 sun_path=@"/tmp/.X11-unix/X0" --> sun_path="/tmp/.X11-unix/X0" --> sin_addr=inet_addr("127.0.0.1")
即 抽象套接字 --> 套接字文件 --> 網絡

將X0-bak改回爲X0,並再進行第二次跟蹤調試
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"成功了,就不進行嘗試"127.0.0.1"

根據兩次跟蹤調試結果:在網絡命名空間下,sun_path=@"/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
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
或者容器系統不會刪除/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)容器
進入容器後

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需認證受權,即便從宿主簡單地複製.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
密碼:

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登陸桌面,容器也一樣建立了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,此步驟也可省略
linlin@debian:~$ 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地址配置以下:

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

路由器做爲DNS域名服務器,路由器裏配置有上級外網電信互聯網服務商的DNS IP地址或某搜索引擎公司的公共DNS 8.8.8.8,家裏的主機就經過此逐級DNS而得到域名解析.

固然家裏主機也可直接設置外網DNS IP地址,如:

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

4)調整桌面環境顯示尺寸
容器桌面環境顯示尺寸較小(默認640x480).
若是是安裝好完整的桌面環境,可經過桌面環境的工具重設分辨率,會保存,下次啓動系統會按新的分辨率.
若是臨時調整,可用xrandr命令

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

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

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

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

5)在容器外即在宿主直接運行容器裏的命令,需在root用戶下執行lxc-attach來運行容器命令
root@debian:/# lxc-attach -n vm1 -- env DISPLAY=:1 xdm -nodaemon &
說明:用env 設置容器裏環境變量
xdm的參數-nodaemon表示非守護進程運行
加上&後臺運行
這樣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 &

說明:命令前面多加了判斷容器是否處在運行狀態RUNNING,由於不判斷的話,假如容器處於凍結狀態,lxc-attach執行就會處在假死狀態.

7)容器只讀mount宿主/tmp/.X11-unix,容器裏啓動的Xephyr只會建立抽象unix域,沒能建立套接字文件,不過對本實驗也足夠了.
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建立X30套接字文件,只見X30抽象unix域.

相似的Xnest、x2goserver、xpra等是否會建立抽象unix域?沒測試過.

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

容器ssh遠程鏈接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)假如容器的系統不會刪除/tmp下文件,能夠讀寫mount
root@debian:/# 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參數選項哪裏控制到?
root@debian:/# ls -l /var/lib/lxc/vm1/rootfs/tmp/.X11-unix
總用量 0 ,爲空目錄
root@debian:/#

若是是在宿主手動運行命令mount,在宿主是可見到掛載點/var/lib/lxc/vm1/rootfs/tmp/.X11-unix裏有所共享目錄的內容
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

( 附:單點登陸 Kerberos+LDAP 一鍵安裝腳本 onekeysso-ver0.0.9.zip 源代碼 下載地址 http://u.163.com/vvGp4X7e 提取碼: TAsaIfky )
( 附:單點登陸管理圖形界面前端 fgsso-ver0.0.9.zip 源代碼 下載地址 http://u.163.com/1Rr9zaaP 提取碼: qk8gMrfr )

相關文章
相關標籤/搜索