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