LXC:Linux 容器工具
游覽和設(shè)置新的容器工具 Linux Containers
容器可以提供輕量級(jí)的虛擬化,以便隔離進(jìn)程和資源,而且不需要提供指令解釋機(jī)制以及全虛擬化的其他復(fù)雜性。本文循序漸進(jìn)地介紹容器工具 Linux? Containers(LXC)。作者在文中演示如何設(shè)置和使用它們。
容器有效地將由單個(gè)操作系統(tǒng)管理的資源劃分到孤立的組中,以更好地在孤立的組之間平衡有沖突的資源使用需求。與虛擬化相比,這樣既不需要指令級(jí)模擬,也不需要即時(shí)編譯。容器可以在核心 CPU 本地運(yùn)行指令,而不需要任何專門的解釋機(jī)制。此外,也避免了準(zhǔn)虛擬化(paravirtualization)和系統(tǒng)調(diào)用替換中的復(fù)雜性。
通過(guò)提供一種創(chuàng)建和進(jìn)入容器的方式,操作系統(tǒng)讓應(yīng)用程序就像在獨(dú)立的機(jī)器上運(yùn)行一樣,但又能共享很多底層的資源。例如,可以有效地共享公共文件(比如 glibc)的頁(yè)緩存,因?yàn)樗腥萜鞫际褂孟嗤膬?nèi)核,而且所有容器還常常共享相同的 libc 庫(kù)(取決于容器配置)。這種共享常??梢詳U(kuò)展到目錄中其他不需要寫入內(nèi)容的文件。
容器在提供隔離的同時(shí),還通過(guò)共享這些資源節(jié)省開銷,這意味著容器比真正的虛擬化的開銷要小得多。
容器技術(shù)早就出現(xiàn)。例如,Solaris Zones 和 BSD jails 就是非 Linux 操作系統(tǒng)上的容器。用于 Linux 的容器技術(shù)也有豐富的遺產(chǎn),例如 Linux-Vserver、OpenVZ 和 FreeVPS。雖然這些技術(shù)都已經(jīng)成熟,但是這些解決方案還沒(méi)有將它們的容器支持集成到主流 Linux 內(nèi)核。(要了解更多關(guān)于這些技術(shù)的信息,請(qǐng)查看 參考資料 小節(jié))。
相比之下,Linux Resource Containers 項(xiàng)目(見 參考資料)則通過(guò)為主流 Linux 內(nèi)核作貢獻(xiàn)來(lái)實(shí)現(xiàn)容器。與此同時(shí),這些貢獻(xiàn)可能對(duì)成熟的 Linux 容器解決方案有用處 — 為更成熟的容器項(xiàng)目提供公共后端。本文簡(jiǎn)要介紹如何使用由 LXC 項(xiàng)目創(chuàng)建的工具。
為了充分利用本文,您應(yīng)該熟悉使用命令行運(yùn)行程序,例如 make、gcc 和 patch。此外,還應(yīng)該熟悉 tarball(*.tar.gz 文件)的解壓。
獲取、構(gòu)建和安裝 LXC
LXC 項(xiàng)目由一個(gè) Linux 內(nèi)核補(bǔ)丁和一些 userspace 工具組成。這些 userspace 工具使用由補(bǔ)丁增加的內(nèi)核新特性,提供一套簡(jiǎn)化的工具來(lái)維護(hù)容器。
在使用 LXC 之前,首先需要下載 Linux 內(nèi)核源代碼,應(yīng)用適當(dāng)?shù)?LXC 補(bǔ)丁,然后構(gòu)建、安裝和啟動(dòng)它。最后再下載、構(gòu)建和安裝 LXC 工具。
我使用一個(gè)打了補(bǔ)丁的 Linux 2.6.27 內(nèi)核(見 參考資料)。雖然 2.6.27 Linux 內(nèi)核的 lxc 補(bǔ)丁可能不適用于您喜歡的發(fā)行版的內(nèi)核源代碼,但是 2.6.27 以后的 Linux 版本可能已經(jīng)包含該補(bǔ)丁提供的大部分功能。所以,強(qiáng)烈建議使用最新的補(bǔ)丁和主流內(nèi)核源代碼。而且,除了下載內(nèi)核源代碼并添加補(bǔ)丁外,還可以使用 git 獲取代碼:
git clone git://git.kernel.org/pub/scm/linux/kernel/git/daveh/linux-2.6-lxc.git
在 kernelnewbies.org 可以找到關(guān)于如何為內(nèi)核添加補(bǔ)丁,如何配置、構(gòu)建安裝和啟動(dòng)內(nèi)核的指導(dǎo)說(shuō)明(見 參考資料)。
LXC 需要一些特定的內(nèi)核配置。為 LXC 適當(dāng)配置內(nèi)核的最容易的方式是使用 make menuconfig,然后選擇 Container support。取決于內(nèi)核所支持的特性,這樣做會(huì)進(jìn)一步選擇一組其他配置選項(xiàng)。
#p#
可用的 LXC 環(huán)境
除了一個(gè)支持容器的內(nèi)核外,還需要一些工具才能夠簡(jiǎn)單地啟動(dòng)和管理容器。本文的容器管理工具來(lái)自 liblxc(從 參考資料 獲取鏈接。另外,還可以使用 libvirt)。這個(gè)小節(jié)討論:
iblxc 工具
iproute2 工具
如何配置網(wǎng)絡(luò)
如何填充一個(gè)容器文件系統(tǒng)(構(gòu)建定制的 Debian 容器,還是運(yùn)行 ssh 容器)
如何連接到容器文件系統(tǒng)(SSH、VNC、VT: tty、VT: GUI)
工具:liblxc
下載并解壓縮 liblxc (見 參考資料),然后從 liblxc 目錄中:
./configure --prefix=/ make make install |
如果您習(xí)慣于構(gòu)建源 RPM,可以從網(wǎng)上下載一個(gè)(見 參考資料)。
工具:iproute2
為了在容器中管理網(wǎng)絡(luò)接口,需要 2.6.26 或更高版本的 iproute2 包(見 參考資料)。如果您的 Linux 發(fā)行版沒(méi)有這個(gè)包,請(qǐng)下載并按照說(shuō)明配置和安裝它。
配置網(wǎng)絡(luò)
很多實(shí)用的容器的另一個(gè)關(guān)鍵部分是網(wǎng)絡(luò)訪問(wèn)。目前,橋接(連接多個(gè)以太網(wǎng)區(qū)段,使它們成為一個(gè)單獨(dú)的以太網(wǎng)區(qū)段)是將一個(gè)容器連接到網(wǎng)絡(luò)的最佳方法。為了準(zhǔn)備使用 LXC,我們將創(chuàng)建一個(gè)橋(見 參考資料),并使用它將我們真正的網(wǎng)絡(luò)接口與容器的網(wǎng)絡(luò)接口連接起來(lái)。
創(chuàng)建一個(gè)名為 br0 的橋:
brctl addbr br0 brctl setfd br0 0 |
用一個(gè)已有網(wǎng)絡(luò)接口中的 IP(在本例中是 10.0.2.15)連接橋接口:ifconfig br0 10.0.2.15 promisc up。將已有的網(wǎng)絡(luò)接口(在本例中是 eth0)添加到橋,并取消它與它的 IP 地址的直接關(guān)聯(lián):
brctl addif br0 eth0 ifconfig eth0 0.0.0.0 up |
任何添加到橋 br0 的接口都將對(duì)那個(gè) IP 地址作出響應(yīng)。最后,確保默認(rèn)的路由用 route add -net default gw 10.0.2.2 br0 將數(shù)據(jù)包發(fā)送到網(wǎng)關(guān)。以后,在配置容器時(shí),指定 br0 作為通往外界的鏈接。
填充容器文件系統(tǒng)
除了網(wǎng)絡(luò)外,容器常常需要它們自己的文件系統(tǒng)。取決于您的需要,有幾種填充容器文件系統(tǒng)的方法。我將討論其中兩種:
構(gòu)建一個(gè)定制的 Debian 容器
運(yùn)行一個(gè) ssh 容器
使用 debootstrap 命令構(gòu)建一個(gè)定制的 Debian 容器 非常簡(jiǎn)單:
debootstrap sid rootfs http://debian.osuosl.org/debian/ |
如果要構(gòu)建大量的容器,首先將包下載到一個(gè) tarball 中可以節(jié)省時(shí)間,例如 debootstrap --make-tarball sid.packages.tgz sid http://debian.osuosl.org/debian/。這將產(chǎn)生一個(gè) .tar 文件,這個(gè)文件約 71MB(壓縮了 52MB),而一個(gè)根目錄約 200MB。然后開始在 rootfs 中構(gòu)建根目錄:debootstrap --unpack-tarball sid.packages.tgz sid rootfs。(debootstrap 主頁(yè)上有更多關(guān)于構(gòu)建更小的或更適合的容器的信息)。
這將生成一個(gè)宿主容器高度冗余的環(huán)境(見 參考資料)。
運(yùn)行 ssh 容器 可以大大減少容器文件系統(tǒng)占用的磁盤空間。例如,這種方法僅僅使用數(shù) KB 就能在不同容器的 22 端口上運(yùn)行多個(gè) ssh 守護(hù)進(jìn)程(參考資料 中提供了一個(gè)例子)。容器通過(guò)使用關(guān)鍵根目錄來(lái)實(shí)現(xiàn)這一點(diǎn),例如 /bin、/sbin 和 /lib 等的只讀綁定掛載共享來(lái)自已有 Linux 系統(tǒng)的 sshd 包內(nèi)容。這里使用一個(gè)網(wǎng)絡(luò)名稱空間,并創(chuàng)建基本的讀寫內(nèi)容。
用于生成那些輕量級(jí)容器的方法與用于生成 chroot 環(huán)境的方法基本一樣。不同之處在于只讀綁定掛載和使用名稱空間增強(qiáng) chroot 環(huán)境的隔離性,使之成為有效的容器。
接下來(lái),需要選擇一種連接到容器的方法。
連接到容器
接下來(lái)的步驟是連接到容器。根據(jù)配置容器的不同方式,有幾種方法可供選擇:
SSH
VNC(GUI)
VT: tty(文本)
VT: X(GUI)
如果不需要用于容器的 GUI 接口,那么 通過(guò) SSH 連接 就可以了。在此情況下,一個(gè)簡(jiǎn)單的 ssh 連接就足夠了(參見上面的 “運(yùn)行一個(gè) ssh 容器”)。這種方法的優(yōu)點(diǎn)是依靠 IP 尋址來(lái)支持創(chuàng)建任意數(shù)量的容器。
如果 ssh 連接花很長(zhǎng)的時(shí)間才到達(dá)密碼提示,那么在 DNS 查找期間 Avahi multicast DNS/Service Discovery 守護(hù)進(jìn)程就可能超時(shí)。
通過(guò) Virtual Network Computing(VNC)連接,這種方法可以為容器增加一個(gè) GUI 接口。
使用 vnc4server 啟動(dòng)一個(gè) X 服務(wù)器,該服務(wù)器只為 VNC 客戶機(jī)服務(wù)。需要安裝 vnc4server,以便從容器的 /etc/rc.local 文件運(yùn)行它,如下所示:echo '/usr/bin/vnc4server :0 -geometry 1024x768 -depth 24' >> rootfs/etc/rc.local。當(dāng)容器啟動(dòng)時(shí),將創(chuàng)建一個(gè)分辨率為 1024×768 的 24 位色的 X 屏幕。接下來(lái)的連接很簡(jiǎn)單,如下所示:
vncviewer <ip>:<display> |
如果容器與它的宿主共享 tty,那么 通過(guò) VT: tty(文本)連接 就很有用。在這情況下,可以使用 Linux Virtual Terminals(VT)連接到容器。使用 VT 的簡(jiǎn)單用法是登錄 tty 設(shè)備之一,然后這個(gè) tty 設(shè)備將與 Linux VT 通信。登錄進(jìn)程被稱作 getty。使用 VT 8:
echo '8:2345:respawn:/sbin/getty 38400 tty8' >> rootfs/etc/inittab |
一旦容器被啟動(dòng),它將在 tty8 上運(yùn)行 getty,以允許用戶登錄到容器中。可以通過(guò)類似的技巧,使用 LXC 工具重新啟動(dòng)容器。
這種方法不支持容器的圖形化界面。而且,由于每次只有一個(gè)進(jìn)程可以連接到 tty8,若要啟用多個(gè)容器,則需要進(jìn)一步配置。
通過(guò) VT: X 連接 讓您可以運(yùn)行一個(gè) GUI。在 VT 9 上運(yùn)行 GNOME Display Manager(gdm),然后編輯 rootfs/usr/share/gdm/defaults.conf,將 FirstVT=7 替換為 FirstVT=9,以及將 VTAllocation=true 替換為 VTAllocation=false。
雖然這樣便可以使用一個(gè)圖形化界面,但是仍然只能使用有限的幾種 Linux 虛擬終端之一。
#p#
運(yùn)行 LXC 工具
至此,您正在運(yùn)行一個(gè)適當(dāng)?shù)膬?nèi)核,安裝了 LXC 實(shí)用程序,并且有了一個(gè)可用的環(huán)境,接下來(lái)便可以學(xué)習(xí)管理該環(huán)境的實(shí)例了。(提示:LXC README 中更加詳細(xì)地描述了這方面的大部分內(nèi)容)。
LXC 使用 cgroup 文件系統(tǒng)來(lái)管理容器。在使用 LXC 之前,首先必須掛載這個(gè)文件系統(tǒng):mount -t cgroup cgroup /cgroup??梢詫?cgroup 文件系統(tǒng)掛載到任何地方。LXC 將使用 /etc/mtab 中掛載的第一個(gè) cgroup 文件系統(tǒng)。
本文的后面將展示一些 LXC 基礎(chǔ)知識(shí)和雜項(xiàng)內(nèi)容,并討論低級(jí)訪問(wèn)。
LXC 基礎(chǔ)知識(shí)
對(duì)于使用 LXC 工具的基礎(chǔ)知識(shí),我們將看看:
創(chuàng)建容器
獲得(或列出)關(guān)于已有容器的信息
啟動(dòng)系統(tǒng)和應(yīng)用程序容器
向容器中運(yùn)行的進(jìn)程發(fā)信號(hào)
暫停、恢復(fù)、停止和銷毀容器
創(chuàng)建容器就是將一個(gè)名稱與一個(gè)配置文件關(guān)聯(lián)起來(lái)。該名稱將用于管理容器:
lxc-create -n name -f configfile |
這使得多個(gè)容器可以同時(shí)使用相同的配置文件。在配置文件中,可以指定容器的屬性,例如它的主機(jī)名、網(wǎng)絡(luò)、root 文件系統(tǒng)和 fstab。運(yùn)行 lxc-sshd 腳本(該腳本創(chuàng)建一個(gè)配置)之后,ssh 容器配置如下所示:
lxc.utsname = my_ssh_container lxc.network.type = veth lxc.network.flags = up lxc.network.link = br0 lxc.network.ipv4 = 10.0.2.16/24 lxc.network.name = eth0 lxc.mount = ./fstab lxc.rootfs = ./rootfs |
無(wú)論配置文件如何,用 LXC 工具啟動(dòng)的容器有自己的系統(tǒng)進(jìn)程視圖,以及自己的掛載樹和可用的進(jìn)程間通信(IPC)資源視圖。
除了這些以外,當(dāng)一個(gè)容器啟動(dòng)時(shí),配置中未提到的任何類型的資源都被認(rèn)為是與主機(jī)共享。這使管理員可以簡(jiǎn)潔地指定容器與其主機(jī)之間的關(guān)鍵不同點(diǎn),并且使配置具有可移植性。
列出關(guān)于已有容器的信息對(duì)于管理已有容器非常重要。顯示一個(gè)特定容器的狀態(tài):
lxc-info -n name |
顯示屬于一個(gè)容器的進(jìn)程:
lxc-info -n name |
啟動(dòng)
LXC 根據(jù)容器類型的不同而有所不同:一種是系統(tǒng)容器,一種是應(yīng)用程序容器。系統(tǒng)容器類似于虛擬機(jī)。與真正的虛擬化相比,雖然它們的隔離性要低一些,但是開銷也降低了。直接原因是每個(gè)容器使用相同的 Linux 內(nèi)核。為了類似于虛擬機(jī),系統(tǒng)容器和 Linux 發(fā)行版一樣在同一個(gè)地方啟動(dòng),即通過(guò)運(yùn)行 init 程序:
lxc-start -n name init |
與系統(tǒng)容器相比,應(yīng)用程序容器只是創(chuàng)建用于隔離一個(gè)應(yīng)用程序的單獨(dú)的名稱空間。啟動(dòng)一個(gè)應(yīng)用程序容器:
lxc-execute -n name cmd |
發(fā)信號(hào)
將一個(gè)信號(hào)發(fā)送到在一個(gè)容器中運(yùn)行的所有進(jìn)程:
lxc-kill -n name -s SIGNAL |
暫停
暫停一個(gè)容器在概念上類似于將 SIGSTOP 信號(hào)發(fā)送到一個(gè)容器中的所有進(jìn)程。但是,發(fā)送虛假的 SIGSTOP 信號(hào)可能會(huì)迷惑一些程序。所以,LXC 通過(guò) cgroup 接口使用 Linux 進(jìn)程凍結(jié)器(process freezer):
lxc-freeze -n name |
恢復(fù)
要恢復(fù)一個(gè)被凍結(jié)的容器:
lxc-unfreeze -n name |
停止
停止一個(gè)容器將導(dǎo)致該容器中啟動(dòng)的所有進(jìn)程全體死亡,并且清理容器:
lxc-stop -n name |
銷毀
銷毀容器是指刪除通過(guò) lxc-create 步驟與名稱關(guān)聯(lián)的配置文件和元數(shù)據(jù):
lxc-destroy -n name |
#p#
雜項(xiàng)
下面是您可能想知道的一些其他內(nèi)容(有些與監(jiān)視有關(guān))。
查看和調(diào)整容器的優(yōu)先級(jí):
lxc-priority -n name lxc-priority -n name -p priority |
持續(xù)觀察容器的狀態(tài)和優(yōu)先級(jí)變化:
lxc-monitor -n name |
按 Ctrl-C 停止監(jiān)視容器。
還可以等待容器進(jìn)入以 | 分隔的一組狀態(tài)之一:
lxc-wait -n name -s states |
等待除了 RUNNING 之外的所有狀態(tài):
lxc-wait -n name -s 'STOPPED|STARTING|STOPPING|ABORTING|FREEZING|FROZEN' |
當(dāng)然,這樣將會(huì)立即返回。如果沒(méi)有遇到意外錯(cuò)誤,您應(yīng)該期望只有當(dāng)容器進(jìn)入給定的狀態(tài)時(shí) lxc-wait 才返回。
低級(jí)訪問(wèn)
LXC 使用 cgroup 文件系統(tǒng)管理容器??梢酝ㄟ^(guò) LXC 讀和操縱 cgroup 文件系統(tǒng)的一些部分。要管理每個(gè)容器對(duì) cpu 的使用,則可以通過(guò)讀取和調(diào)整容器的 cpu.shares 來(lái)進(jìn)行,如下所示:
lxc-cgroup -n name cpu.shares lxc-cgroup -n name cpu.shares howmany |
結(jié)束語(yǔ)
至此,這份指南已向您展示了如何掌握 Linux Containers 工具,您可以開始制作自己的有效資源分區(qū)。
參考資料
學(xué)習(xí)
您可以參閱本文在 developerWorks 全球網(wǎng)站上的 英文原文。
kernelnewbies.org 介紹如何為 Linux 內(nèi)核添加補(bǔ)丁,如何配置、構(gòu)建、安裝和啟動(dòng) Linux 內(nèi)核。
其他容器技術(shù)包括
Solaris Zones(Solaris)
BSD jails(FreeBSD)
Linux-Vserver(Linux)
OpenVZ(Linux)
FreeVPS(Linux)
學(xué)習(xí)創(chuàng)建 bridge,為使用 LXC 做好準(zhǔn)備。
這是一個(gè)宿主容器高度冗余的 環(huán)境。
這個(gè) ssh 例子 僅僅使用數(shù) KB 就可以在不同容器的 22 端口上運(yùn)行多個(gè) ssh 守護(hù)進(jìn)程。
【編輯推薦】