Linux Vserver

author:Yung-Yu Chen (yungyuc) <yyc@seety.org>
date:2005/12/15
copyright:© 2005, all rights reserved.

目錄

Linux 是一種相當穩定的作業系統,一台同時用作桌面環境和伺服器的電腦,常常可以幾個月都不必重新開機。各 Linux distribution 使用的多半是開放原始碼/自由軟體,所以都有完整的套件管理系統,例如 RedHat/Fedora/Mandriva 的 rpm、SuSE 的 yast 以及 Debian 的 apt。Linux 的使用者透過它們,可以對系統作比較精細的控制,也容易進行各種軟體昇級工作。不過,Linux 再怎麼穩定、套件管理系統再怎麼完整方便,也總是會出錯,這個時候就會讓使用者或伺服器管理員開始傷腦筋了。

對於用作伺服器的 Linux 電腦來說,資訊安全則是另一個要擔心的問題。專門的伺服器一定會套用多重的防護措施,然而對於公開服務的伺服器來說,來自於網路四面八方的攻擊實在是防不勝防;敏感資料如果可以的話,最好不要曝露在外部網路上,而伺服器資料一定會備份再備份。單獨伺服器的安全性特別難維護,因為性質不同的伺服工作得集中在一台電腦上,很難實作比較理想的伺服網路架構,幾乎無法解決。

基於這些穩定性和安全性方面的考慮,許多 Linux 使用者都期待有一種能在同一台電腦上執行多個獨立作業系統,又不會像 VMware 等虛擬機器一樣損耗效能的技術;如此一來,以上的問題都可以獲得很大程度的解決,同時還能提供更佳的使用性。vserver (linux-vserver) 就是這樣的一項技術。

1   What is vserver?

vserver 是一項為 Linux 加入虛擬作業系統能力的技術,實作這項技術的計畫叫作 linux-vserver (簡稱 vserver);這個計畫對 Linux 核心進行修改,以核心修補配合管理工具的方式進行散佈。vserver 能在同一個 Linux 核心之下同時執行多個彼此無關的作業系統,並且完全不會消耗額外的運算能力 (與 VMware, VPC, XEN 等虛擬機器技術不同)。

我們可以把 vserver 視為一種強化的 chroot (changed root) 技術,在 host OS 上透過內容切換 (content switching) 的方式實作出獨立的 Linux 執行環境 (guest OS)。由於 Un*x 是一種檔案導向的作業系統,單純的 chroot 環境就已經具有相當程度的獨立性,而 linux-vserver 則進一步在 Linux 核心上動手腳,讓各個 vserver 能完全地獨立出來,就好像真的是不同的系統一樣。在 vserver 內可以安裝與 host OS 完全不同的 Linux distribution,使用不同的網路設定、不同的虛擬終端機、不同的 X;host OS 和 guest OS 唯一必須具備的關聯是核心。因為 guest OS 是 host OS 核心裡的一個特別執行環境,所以 vserver 會限制 guest OS 對核心的操作;guest OS 不能新增移除核心模組、不能修改與核心有關的任何參數。

vserver 可以說是「自核心以下,完全獨立」的超級 chroot。

不會損耗運算能力的 vserver 技術很適合各種基於 Linux 的應用。虛擬機器技術的缺點就是會在轉譯機器碼的時候損耗過多的運算能力,所以多半只會安裝在比較高效能的電腦上執行特別的功能或進行測試;vserver 則可應用在各種 Linux 原生的環境下,提供與原先幾乎完全相同的運算能力與操作性。這兩者是不同取向的技術;我們不能在 vserver 上安裝 Windows 或 OSX,但卻能在同一套硬體上,同時運作不同「身份」的 Linux、提供不同的服務、執行不同的程式,彼此間都不會互相干涉。

2   Why vserver?

想要保持系統的穩定又想玩玩新奇的玩意兒?那麼 vserver 似乎是最佳的選擇了。

linux-vserver 計畫:「你可能會想,虛擬伺服器 (vserver) 看起來很酷,但大概不是對所有人都有用吧。!」vserver 真的很有用,對一般使用者來說,它至少可以讓系統更加強固穩定:安裝 host OS 作 container,再使用 vserver 進行日常工作。以 Debian GNU/Linux 來說,有了 vserver 之後,我們就能夠採取以下的系統管理模式:

  1. 安裝基本的 stable 作 host OS:用穩定版的 Debain 安裝 host OS 來處理基本的磁碟與網路管理作業;避免系統因為上游套件的一點問題而無法使用 (或不方便使用)。
  2. 在 stable Debian host OS 上安裝 linux-vserver:可以視需要安裝多個 vserver;在其中沒有執行程式的情況下,只會佔用相當少量的記憶體,對運算能力的影響幾乎是 0。在 vserver 裡執行的程式效能與在 host OS 裡完全相同。
  3. 在 vserver 裡工作:
    • vserver 裡面安裝的軟體,不會影響 host OS。
    • 測試新程式或系統時可建立獨立的 vserver;在 vserver 裡面隨便怎麼玩,host OS 都不會壞,也不會干擾到日常作業用的 vserver。
    • 用 vserver 提供網路服務;將危險限制在獨立的 vserver 內部。

所以,不管是日常作業、系統開發或網路伺服,vserver 都可以幫助我們。得此工具,夫復何求?

3   安裝 Debian 提供的 vserver 套件

Debian GNU/Linux (以下簡稱 Debian) 是一套結構完整、套件豐富的 distribution,為求方便,我們用它來討論 vserver 的使用;其它的 Linux distribution 一樣可以使用 vserver。

在 Debian 裡面有三個相關的套件:kernel-patch-vserver, util-vserver, vserver-debiantoolslinux-vserver 是 linux-vserver 計畫所發行的核心修補 (patch),可以套用在 Debian 的 2.6.8, 2.6.11 和 2.6.12 (經過筆者的測試) 核心上面 (也支援 2.4 的核心,但我未測試),這是一定要安裝的套件。

註記

在筆者測試過的這幾個版本的核心裡面,2.6.11是最穩定,最沒有問題的版本。

util-vserver 是一組用來管理 vserver 的工具程式集,也是 linux-vserver 計畫的一部分;vserver-debiantools 則是 Debian 特別為 vserver 開發的工具程式集。這兩者雖非絕對必要,但少了它們也幾乎就沒辦法管理 vserver,所以一般來說三個套件我們都會安裝:

$ apt-get -t sid kernel-patch-vserver util-vserver vserver-debiantools

因為 sarge 裡的 vserver-debiantools 還有問題,所以改用 unstable (即 sid) 裡新的 vserver 相關套件。

當然還需要取得核心原始碼:

$ apt-get -t sid kernel-source-2.6.11
$ mkdir /usr/src/work; cd /usr/src/work
$ tar xfj /usr/src/kernel-source-2.6.11.tar.bz2
$ mv kernel-source-2.6.11 kernel-source-2.6.11vserver

註記

別忘了先裝 libncurses5-dev。也別忘了 kernel-package (提供 make-kpkg) 和 dpkg-dev

2.6.12 核心可以用 gcc-4.0 編譯,舊 (<=2.6.11) 核心則要用 gcc-3.3。如果系統 gcc 的版本不一樣,那在 make-kpkg 之前加入相對的 MAKEFLAGS="CC=gcc-4.0"MAKEFLAGS="CC=gcc-3.3" 即可。因為我們的 make-kpkg 動作會直接套用修補檔,所以在之前先組態一下會比較好:

$ make menuconfig

然後用 (參考4):

$ make-kpkg --rootcmd fakeroot \
--revision custom01 --append-to-version +vserver \
--added-patches vserver \
--initrd --config menuconfig binary-arch

這一行指令,以 make-kpkg (它是 kernel-package 套件的一部分) 這個工具來建立 Debian 的核心包裝檔 (.deb)。其中的 --added-patches vserver 會在編譯之前把 vserver 修補上去 (修補檔放在 /usr/src/patches 裡面),然後用 menuconfig 以確認 vserver 相關的組態 (--config menuconfig)。最後編譯,完成之後會在上一層目錄裡 (此處即 /usr/src/work) 產生:

kernel-headers-2.6.11+vserver_custom01_i386.deb
kernel-image-2.6.11+vserver_custom01_i386.deb

兩個檔案。

註記

--append-to-version +vserver 作出來的核心,在 uname -r 執行的結果裡會變成 2.6.11+vserver。有些利用 uname 檢查核心版號的程式會因此而無法判斷核心的版本。我們可以把這些程式用來判斷核心版本的 shell script 從

`uname -r`

改為

`uname -r | cut -d+ -f1`

亦即利用 cut 工具把 +vserver 從版號裡移掉即可。

我們要用 dpkg -i kernel-image-2.6.12+vserver_custom01_i386.deb 來把建好的核心安裝到系統裡面;kernel-headers-2.6.12+vserver_custom01_i386.deb 套件則是此核心的標頭檔,通常也要一併安裝,以供某些會用到核心參數的程式,或是 3rd party 的驅動程式編譯使用。

裝好了核心檔案、適當地修改 boot loader (lilo/grub),再用 patched kernel 重新開機以後,系統就具備了 vserver 的能力。此後即可使用 util-vservervserver-debiantools 套件裡的工具來管理 vserver。

4   調整 host OS

因為 vserver 是一種配合 content-switching 技術的 chroot 環境,所以許多伺服程式需要調整組態來配合,ssh 就是其中之一。幾乎所有的系統上都需要這個服務,所以我們先說明如何處理。

ssh 預設會對系統上所有的 IP 位址進行監聽 (0.0.0.0),這個行為與 vserver 的運作相衝突。如果不改變此行為,那麼所有連往 vserver IP 的 ssh 連線都會被 host OS 上的 sshd 攔下來,讓 vserver 的 sshd 失效。我們要把 host OS 的 /etc/ssh/sshd_config 的這一行:

#ListenAddress 0.0.0.0

改為

ListenAddress 69.90.134.201 # host OS 的 IP,可多行
ListenAddress 127.0.0.1 # host OS 的 loopback

然後重新啟動 ssh server。如果 host OS 上有其它伺服器的話,也需要作類似的修改。

5   建立 vserver

我們用 utils-vserver 提供的總管工具 vserver 來建立 vserver (請參考5):

$ REMOVE_PACKAGES="sparc-utils,dhcp-client,lilo,makedev,pcmcia-cs,ppp,\
pppconfig,pppoe,pppoeconf,setserial,syslinux,fdutils,libpcap0,\
iptables,pciutils"
$ vserver cosmos build -m debootstrap --hostname cosmos \
--interface eth0:192.168.200.1/24 --interface lo:127.0.0.1/8 \
-- -d sarge -- --exclude=$REMOVE_PACKAGES

註記

這個動作會去抓取所需的套件,用 debootstrap 安裝 base system。在 -d sarge 後面可以接 -m URL 來指定 debootstrap 的鏡像來源,未指定的話 vserver 會使用預設值;使用本機的鏡像可以節省大量的時間。

這裡之所以不使用 vserver-debiantools 提供的 newvserver 工具,是希望對 vserver 進行比較通用的講解;Debian host OS 才會有 vserver-debiantools 套件,但 utils-vserver 則是可以在所有 distribution 上使用的。

cosmos 是 vserver 的名字,請隨便取你喜歡的。如此建立出來的 vserver 會採用 vserver2 的設定模式,與 legacy 設定模式不同;vserver2 設定模式的詳細說明請參考大花頁3,不過我先警告一下,它很

所有 vserver 的組態都放在 /etc/vservers 之下;各 vserver 預設的根目錄結構則位於 /var/lib/vserver

6   進行 vserver 的基本組態

6.1   啟動與進入 vserver

作到這裡,已經可以用:

$ vserver cosmos start

啟動 cosmos vserver,而用

$ vserver cosmos enter

則會把我們帶進 cosmos。

剛建好的 vserver 什麼套件都沒有裝,所以沒有 locale,所以若 host OS 有設定 locale 的話,進入 vserver 裡面時的畫面就會亂亂的;把目前執行環境的 locale 改成 C 即可解決 (LC_ALL=C LANG=C LANGUAGE=C)。

6.2   移掉不必要的 init 指令稿

參考 Step-by-Step Guide2,我也把以下的 init 指令稿 symbolic link 刪除了:

cd /home/vservers/DebianSid/etc/rc0.d
rm K20makedev K25hwclock.sh S30urandom S31umountnfs.sh \
S35networking S36ifupdown S40umountfs S90halt K89klogd

cd /home/vservers/DebianSid/etc/rc6.d
rm K20makedev K25hwclock.sh S30urandom S31umountnfs.sh\
S35networking S36ifupdown S40umountfs S90reboot K89klogd

cd /home/vservers/DebianSid/etc/rcS.d
rm S05keymap.sh S48console-screen.sh S50hwclock.sh S40networking \
S45mountnfs.sh S10checkroot.sh S02mountvirtfs
rm S30procps.sh S35mountall.sh S36mountvirtfs S39ifupdown \
S30checkfs.sh S18ifupdown-clean S18hwclockfirst.sh

cd /home/vservers/DebianSid/etc/rc2.d
rm S20makedev S11klogd

作完以後,就可以在 host OS 裡用 vserver cosmos stopvserver cosmos restart 安全地關閉 vserver 了。

6.3   base-config

用以上程序安裝的 vserver 並不會自動進行 base-config,所以我們必須進入 vserver,執行一次 base-config,再繼續安裝/設定你的 vserver。

base-config 裡的 Set up users and passwords 是一定要作的;這要作過之後,vserver 裡面才會有 /etc/shadow。timezone 也可以在這個時候設定,但其餘的東西則是到 vserver 裡面的組態檔裡面去改可能會比較方便。

另一個重要的檔案是 vserver 裡的 /etc/hosts。一開始這個檔案是不存在的,我們要自行建立,在其中寫入本機的 IP 與 FQDN 及主機名稱的對照。許多服務程式需要取得本機的名稱及 IP 位址,如果缺少這個檔案的資訊,執行就會失敗或者不正常。

以 cosmos 舉例來說,hosts 檔的內容會像是:

127.0.0.1 localhost.localdomain localhost
192.168.200.1 cosmos.your.domain cosmos

6.4   安裝基本套件

剛作完 base-config 之後的 Debian 還非常生素,我們至少要安裝兩個套件:

  • locales: 用來產生系統所需的地域資料定義。
  • ssh: 為 vserver 開啟一個遠端連線的端口,方便我們從 host OS 或其它位置來管理它。請記得修改 ListenAddress

還有一些不是一定要安裝,但很常用到的套件:

  • vim: debootstrap 會安裝一個 nvi,提供基本的 vi 編輯環境,不過非常陽春。通常我們會安裝 vim 取代這個簡單的 nvi 程式。
  • less: 比原始的 more 方便很多的分頁器。
  • sudo: 系統管理工具;用來取代 su 大部分的功能。
  • screen: 在同一次登入裡提供多個虛擬終端機的工具。

安裝之前請先寫好系統的 sources.list。最簡單的方法就是回到 host OS 裡複製一份:

$ cp /etc/apt/sources.list /var/lib/vservers/cosmos/etc/apt/source.list

註記

symbolic link 是沒有用的;不要忘記 vserver 裡面可是一個 chroot 環境。

apt-get update,然後我們就可以 apt-get install 它們了。

7   X window in vserver

vserver 是可以執行 X 的!這也是 vserver 的賣點之一。

vserver 既然能跑 X,那麼就可以把原本在 host OS 裡執行的 X 桌面改放到 vserver 裡跑,這樣子好處多多。例如筆者不喜歡伺服器的家目錄裡有一堆 "." 開頭的檔案和目錄,但 X 桌面環境無可避免地會製造出很多這種組態檔;使用 vserver 來跑 X,就可以把這些組態檔侷限到其它目錄裡面去。另外,比較不穩定的 X 程式也不致於影響主機的運作。而且,利用 vserver,我們很容易就可以在同一台主機上執行多個 X server。

註記

使用的 X 程式一多,組態檔和目錄常常上百個,管理起來很麻煩。

vserver 要執行 X 需要作一些調整:先打開 vserver 的 CAP_SYS_RAWIO,請在 /etc/vservers/cosmos/bcapabilities 檔案 (預設並沒有這個檔案,請自己建一個新的) 裡寫入 CAP_SYS_RAWIO,其次要為 vserver 建立 mem 與一些 tty 裝置:

$ mknod /var/lib/vservers/cosmos/dev/mem c 1 1
$ chmod 640 /var/lib/vservers/cosmos/dev/mem
$ chown root.kmem /var/lib/vservers/cosmos/dev/mem
$ mknod /var/lib/vservers/cosmos/dev/tty1 c 4 1
$ chmod 600 /var/lib/vservers/cosmos/dev/tty1
$ chown root.tty /var/lib/vservers/cosmos/dev/tty1
$ mknod /var/lib/vservers/cosmos/dev/tty7 c 4 7
$ chmod 600 /var/lib/vservers/cosmos/dev/tty7
$ chown root.tty /var/lib/vservers/cosmos/dev/tty7
$ mknod /var/lib/vservers/cosmos/dev/tty8 c 4 8
$ chmod 600 /var/lib/vservers/cosmos/dev/tty8
$ chown root.tty /var/lib/vservers/cosmos/dev/tty8
$ mknod /var/lib/vservers/cosmos/dev/tty9 c 4 9
$ chmod 600 /var/lib/vservers/cosmos/dev/tty9
$ chown root.tty /var/lib/vservers/cosmos/dev/tty9

然後就可以在 vserver 裡用一般的方式來安裝 X:

$ apt-get install x-window-system

我們可以手動安裝 gnome, KDE 桌面環境與其它各種軟體。如果嫌麻煩的話,也可以用 tasksel 來安裝 Desktop environment。

在 vserver 裡面安裝組態 X 的工作與在 host OS 裡沒什麼不同,反倒是啟動比較有學問。如果想使用 startx,得先給 vserver 指定一個文字模式 tty,登入以後才能用 startx 啟動 X。如果不想那麼麻煩,那麼可以改用 gdm (或 xdm/kdm) 來啟動 X;這個好處是只要啟動 vserver,馬上就可以登入 X 桌面,省掉登入 vserver 文字終端機的動作。

8   其它

有人提供了一些 vserver 常用的裝置6,可以參考一下;其中 randomurandom (及其權限設定) 對使用 TLS/SSL 的程式蠻重要的。

在 vserver 內安裝大部分的伺服程式時,多半只需要注意一下不要讓程式監聽到所有 IP (0.0.0.0) 即可,其它的設定方式則和 vserver 外一樣。其中,安裝 NIS 客戶端的時候,請注意 vserver 裡一定要有 lo 裝置,如果 NIS 客戶端不能存取 loopback 的話,將無法繫結 NIS 伺服器。

本文以 Debian 來簡介 linux-vserver 的基本使用,熟悉了這項技術之後,相信還能變化出更多的應用。希望大家 vserver 愉快!

9   References

[1]Linux Vservers: http://deb.riseup.net/vserver/
[2]Step-by-Step Guide 2.6: http://linux-vserver.org/Step-by-Step+Guide+2.6
[3]大花頁:http://www.nongnu.org/util-vserver/doc/conf/configuration.html
[4]http://deb.riseup.net/vserver/preparing/
[5]http://deb.riseup.net/vserver/create-instance/
[6]http://www.paul.sladen.org/vserver/archives/200202/0190.html