chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

能當(dāng)主力,能入虛擬機(jī),Linux有多神奇?

馬哥Linux運(yùn)維 ? 來(lái)源:未知 ? 作者:胡薇 ? 2018-06-26 17:02 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

這里介紹一下自己管理自己的Linux桌面的一點(diǎn)經(jīng)驗(yàn)吧,我覺(jué)得還是有不少可取之處的。先來(lái)說(shuō)一下大多數(shù)人管理Linux桌面的方法有哪些不方便的地方吧:買(mǎi)新電腦了,又得在新電腦上安裝Linux,安裝各種軟件,各種庫(kù),各種開(kāi)發(fā)環(huán)境,配置各種服務(wù),真麻煩。

最近一直在用電腦A,干了好多事情安裝了好多軟件,也配置了不少開(kāi)發(fā)環(huán)境跟各種服務(wù),然而處于某種原因,我又要開(kāi)始使用好久沒(méi)用過(guò)的電腦B了,難道我要把在A上的做的各種配置在B上再重新做一遍?

在Windows下做著PPT呢,發(fā)現(xiàn)需要調(diào)出自己之前的程序,然后根據(jù)若干組輸入跑幾個(gè)結(jié)果畫(huà)張圖好插到PPT里,然而這個(gè)程序是在Linux下寫(xiě)的,編譯等的過(guò)程也嚴(yán)重依賴(lài)自己用的Linux環(huán)境,重啟進(jìn)Linux拿到結(jié)果再回Windows太不方便,想在Windows下配置好環(huán)境把自己的程序跑通更不容易。

要對(duì)系統(tǒng)安裝某個(gè)軟件,或者進(jìn)行一些比較危險(xiǎn)的更新操作(要知道Archlinux滾動(dòng)更新滾掛了太正常了),擔(dān)心把系統(tǒng)搞掛了,系統(tǒng)備份又實(shí)在太麻煩,要真掛了,系統(tǒng)恢復(fù)起來(lái)更麻煩。

我一直用Archlinux做主力,然而最近做的某件事情要用某個(gè)軟件,這個(gè)軟件官方只給了Ubuntu上的安裝方式,Archlinux里面沒(méi)有相應(yīng)的包,在Archlinux上手動(dòng)安裝也太不方便。裝個(gè)Ubuntu,然后暫時(shí)用幾天Ubuntu吧,也是夠折騰的。更何況有時(shí)候只是想用一小下而已,怎樣才能最小化自己在折騰上浪費(fèi)的時(shí)間呢?

有的軟件官方軟件倉(cāng)庫(kù)里面沒(méi)有,而make install的話(huà)則會(huì)在系統(tǒng)中安裝上不被包管理器所管理的文件,將來(lái)卸載也不方便,我還是更希望所有的文件都在一個(gè)包管理器中管理的。

聽(tīng)說(shuō)新版本內(nèi)核引入了某個(gè)牛逼的東西?我就想快速測(cè)試一下玩玩,我電腦還有計(jì)算在跑著呢,我可不想重啟,那就只能用虛擬機(jī)嘗試了。而且,一定要快速,我可不想為此特地裝一個(gè)虛擬機(jī)。

上述的這些不方便之處是可以通過(guò)自己管理系統(tǒng)時(shí)的一些技巧來(lái)克服的,本文目的就是來(lái)介紹一下這些技巧。通過(guò)這些技巧,我們實(shí)現(xiàn)的功能是:一臺(tái)機(jī)器上,可以同時(shí)安裝Windows跟若干Linux系統(tǒng),Windows下可以通過(guò)虛擬機(jī)來(lái)運(yùn)行位于本地磁盤(pán)的這些Linux系統(tǒng),而這些Linux系統(tǒng)下也可以通過(guò)容器或者虛擬機(jī)的方式互相運(yùn)行。并且這些系統(tǒng)可以非常方便地備份跟刪除,也可以隨時(shí)創(chuàng)建以及運(yùn)行快照。并且這些Linux系統(tǒng)可以隨時(shí)打包帶走,只需要經(jīng)過(guò)很少的修改,就能直接在U盤(pán)或者其他機(jī)器上運(yùn)行。如果要換電腦,或者新裝一臺(tái)電腦,也不需要重新安裝系統(tǒng),只需要把已有的系統(tǒng)同步到新電腦就行。這也正是這篇文章標(biāo)題的意思。

為了行文的方便,我們假定讀者有一臺(tái)全新的機(jī)器,硬盤(pán)還沒(méi)分區(qū),也還沒(méi)裝任何系統(tǒng)。如果已經(jīng)什么都裝好了,而只是想遷移到我這種管理方式的話(huà),我相信讀者能夠判斷這個(gè)安裝教程中哪些步驟是需要做的哪些步驟是不需要做的。 另外需要注意的是這不是一個(gè)手把手的一步一步的教程,中間有一些顯然的步驟我就略去不寫(xiě)了,所以希望讀者不要照著文章里的的命令不加思考地一條一條粘貼運(yùn)行,而是要搞明白這些命令的目的是什么,然后根據(jù)你自己的情況來(lái)做相應(yīng)的修改。

分區(qū)與子卷

具體怎么分區(qū)我就不說(shuō)了,隨便找個(gè)livecd啟動(dòng)進(jìn)去,然后找到你自己最喜歡的分區(qū)程序,按照你的喜好把區(qū)分了就好。注意別忘了EFI分區(qū)。我這里需要說(shuō)的是,分區(qū)的時(shí)候,不論有多少個(gè)發(fā)行版要安裝,總共只給Linux劃分兩個(gè)分區(qū):一個(gè)是swap,另一個(gè)則是一個(gè)大的btrfs分區(qū)。那個(gè)btrfs分區(qū)里面裝著所有的文件,包括用戶(hù)的個(gè)人數(shù)據(jù),以及所有發(fā)行版的rootfs。這兩個(gè)分區(qū)在格式化的時(shí)候,一定要給他們?nèi)abel,這么做的好處接下來(lái)我們很快就會(huì)看到。我的習(xí)慣是,swap分區(qū)的Label我就叫他“swap”,而那個(gè)btrfs分區(qū)我則叫他“l(fā)inux”。創(chuàng)建好分區(qū)以后,如果格式化工作是在圖形的分區(qū)管理程序下完成的,那么指定Label是個(gè)非常簡(jiǎn)單的工作,右鍵屬性里面就有。如果是使用命令行工具格式化分區(qū)的,則可以使用-L label選項(xiàng)來(lái)指定label,比如:

mkswap -L swap /dev/sdb4mkfs.btrfs -L linux /dev/nvme0n1p4

那個(gè)大的btrfs分區(qū)上的不同內(nèi)容是通過(guò)btrfs的子卷來(lái)管理的,具體來(lái)講就是為自己想安裝的每個(gè)不同的Linux系統(tǒng)來(lái)創(chuàng)建一個(gè)單獨(dú)的子卷。 比如說(shuō)我電腦上同時(shí)安裝了Archlinux、Ubuntu、Kali、Debian四個(gè)系統(tǒng),那么的btrfs分區(qū)里面就有四個(gè)子卷:archlinux、ubuntu、kali、debian。 子卷的創(chuàng)建可以通過(guò)btrfs subvolume create 命令完成,比如說(shuō)要?jiǎng)?chuàng)建我這五個(gè)子卷,需要做的事情就是:

如果你只想裝一個(gè)發(fā)行版,比如archlinux,那么只需要archlinux子卷就夠了。另外,如果你想把用戶(hù)數(shù)據(jù)單獨(dú)放在一個(gè)子卷里,也是完全可以的,不過(guò)這里不推薦多個(gè)Linux系統(tǒng)共享同一個(gè)家目錄,因?yàn)椴煌到y(tǒng)上安裝的軟件不同,同樣的軟件版本也不相同,即使版本相同,不同發(fā)行版也可能應(yīng)用了不同的patch,這就導(dǎo)致在一個(gè)系統(tǒng)上用戶(hù)家目錄里面產(chǎn)生的配置文件,在另一個(gè)系統(tǒng)里無(wú)法兼容,產(chǎn)生奇怪的行為。

系統(tǒng)安裝

創(chuàng)建好分區(qū)與子卷,下一步就是安裝操作系統(tǒng)了。這里分兩種情況來(lái)講:第一種情況是你想要全新安裝一個(gè)Linux操作系統(tǒng);第二種情況則是你已經(jīng)有了某個(gè)可用的操作系統(tǒng)了,而只是想把這個(gè)操作系統(tǒng)遷移到文章所說(shuō)的管理方式上。

全新安裝

如果想要全新安裝一個(gè)操作系統(tǒng),安裝方式上,作者只推薦純手工安裝,而不是用官方給的安裝光盤(pán)不斷點(diǎn)著“下一步”來(lái)進(jìn)行安裝。這么做是為了防止官方安裝程序做一些我們不想讓他做的事情,比如說(shuō)自動(dòng)安裝grub。對(duì)于Archlinux跟Gentoo來(lái)講,唯一的安裝方法就是純手工安裝,所以只要按照官方的教程來(lái)就好了。對(duì)于deb系的系統(tǒng),可以使用debootstrap程序。對(duì)于其他的發(fā)行版,可能會(huì)找不到手工安裝的教程,這時(shí)候可以新建一個(gè)虛擬機(jī),在虛擬機(jī)中使用官方的安裝程序不斷點(diǎn)擊“下一步”來(lái)完成安裝,然后按照下一節(jié)即將介紹的現(xiàn)有系統(tǒng)遷移教程把系統(tǒng)從虛擬機(jī)中遷移到現(xiàn)實(shí)機(jī)器上;除此之外,讀者還可以找到發(fā)行版官方提供的安裝程序的源代碼閱讀一下,看明白這些安裝程序都在干啥,就知道怎么手工安裝了,安裝程序的代碼還是相對(duì)簡(jiǎn)單的,有時(shí)間的讀者不妨嘗試一下。下面來(lái)具體說(shuō)一下安裝過(guò)程,這里只介紹Archlinux跟deb系。如果有多個(gè)Linux系統(tǒng)需要安裝,建議先安裝并完全配置好其中一個(gè),讓這個(gè)系統(tǒng)處于可用并且方便使用的狀態(tài),然后再在這個(gè)可用的系統(tǒng)中安裝其他系統(tǒng)。這里我們假設(shè)讀者已經(jīng)完成了分區(qū),創(chuàng)建了對(duì)應(yīng)的子卷,并且把那個(gè)btrfs分區(qū)掛載在了/mnt上。

Archlinux的手動(dòng)安裝

Archlinux的手動(dòng)安裝主要還是看官方教程。分區(qū)的時(shí)候注意按照上文介紹的方法。非常關(guān)鍵的pacstrap那一步注意使用如下命令安裝到子卷里,而不是整個(gè)btrfs分區(qū)中:

pacstrap -d /mnt/archlinux base

至于fstab,就不要使用教程中的方法來(lái)生成了,我們的管理方式比較非常規(guī),還是自己寫(xiě)fstab比較好。bootloader也要按照本文下文說(shuō)的方式來(lái)安裝跟配置。至于其他的設(shè)置鍵盤(pán)、設(shè)置網(wǎng)絡(luò)、設(shè)置時(shí)區(qū)等操作,照著教程來(lái)就行。

deb系的手動(dòng)安裝

deb系的系統(tǒng)網(wǎng)上找到的教程都是使用發(fā)行版自帶的安裝程序的教程,并沒(méi)有像Archlinux那么詳細(xì)的手動(dòng)安裝教程。因?yàn)槲覀兿胍謩?dòng)安裝,所以我們就不參照網(wǎng)上的deb系的安裝教程了。但是我們還是有教程可以參照的,那就是Archlinux的wiki里面關(guān)于systemd-nspawn的教程,這個(gè)教程里面有一節(jié)介紹如何使用debootstrap安裝Debian或者Ubuntu。具體安裝過(guò)程請(qǐng)參照上述教程,其中關(guān)鍵命令如下:

debootstrap --arch amd64 zesty /mnt/ubuntu http://archive.ubuntu.com/ubuntu/

值得一提的是,我們安裝deb系的發(fā)行版并不一定要使用deb系的livecd,任何能夠安裝debootstrap程序的livecd都是可以的。比如說(shuō)我們完全可以使用Archlinux的livecd來(lái)啟動(dòng),然后安裝debootstrap并通過(guò)debootstrap來(lái)安裝Ubuntu。

注意的是,debootstrap并不會(huì)像官方安裝程序那樣安裝一個(gè)完整齊全開(kāi)袋即食的操作系統(tǒng),而只是安裝最基本的軟件包,讀者需要根據(jù)自己的情況單獨(dú)安裝桌面環(huán)境等的軟件包。同時(shí)fstab跟bootloader也要根據(jù)本文的方法自己配置。

現(xiàn)有系統(tǒng)遷移

Linux系統(tǒng)的遷移其實(shí)非常簡(jiǎn)單,無(wú)非就是把rootfs的文件全都拷貝到目的地即可。不過(guò)這個(gè)過(guò)程雖然看似簡(jiǎn)單,但是還是有一些需要注意的東西的。比如說(shuō)對(duì)于符號(hào)鏈接,如果處理不當(dāng),則會(huì)不小心把符號(hào)鏈接搞成實(shí)體文件,這就不好了。再比如說(shuō),文件的權(quán)限等元數(shù)據(jù)的問(wèn)題,如果處理不當(dāng),可能會(huì)導(dǎo)致拷貝過(guò)程中元數(shù)據(jù)的丟失。這兩種問(wèn)題,都有可能會(huì)導(dǎo)致系統(tǒng)不能正常運(yùn)行。還有一個(gè)需要注意的地方就是,正常運(yùn)行的操作系統(tǒng)里,會(huì)有/proc、/dev等目錄,這些目錄都是單獨(dú)的虛擬文件系統(tǒng),是不需要拷貝的,也是無(wú)法拷貝的。

我們現(xiàn)在假設(shè)用戶(hù)想要把位于A的Ubuntu系統(tǒng)遷移到目標(biāo)子卷/mnt/ubuntu去。其中,A可能位于虛擬機(jī)中,可能位于另一臺(tái)電腦上,也可能位于本地磁盤(pán)。對(duì)系統(tǒng)進(jìn)行遷移,大方向上來(lái)講,需要做的有兩步:

掛載相應(yīng)分區(qū),設(shè)置ssh,保證我們能夠訪(fǎng)問(wèn)到A。

使用rsync或者btrfs send命令來(lái)把數(shù)據(jù)從A發(fā)送到目標(biāo)子卷中去。

第一步具體怎么做就不說(shuō)了,分三種情況簡(jiǎn)單幾句話(huà)概括一下怎么做:

如果只是一個(gè)分區(qū)的話(huà),mount就可以了

如果是另一臺(tái)機(jī)器,把那臺(tái)機(jī)器配置好ssh,保證root用戶(hù)可以用ssh訪(fǎng)問(wèn)

如果是虛擬機(jī),有兩種選擇,一種是想辦法掛載虛擬機(jī)的磁盤(pán)鏡像,然后像情況1那樣處理;另一種則是配置好網(wǎng)絡(luò)跟ssh,像情況2那樣處理。具體采取哪種措施請(qǐng)讀者根據(jù)自己的情況來(lái)自行決定。

第二步我們來(lái)分別介紹rsync跟btrfs send兩種方法。

我們現(xiàn)在假設(shè)A的ip地址為192.168.88.3。則只需執(zhí)行如下命令即可:

rsync -aAXv --exclude={"/dev/*","/proc/*","/sys/*","/tmp/*","/run/*","/mnt/*","/media/*","/lost+found"} root@192.168.88.3:/ /mnt/ubuntu

這里提醒讀者注意自己系統(tǒng)上是否還有其他不想要同步的文件,記得一并排除掉。

btrfs send只在A的rootfs也是btrfs的情況下才能使用。這個(gè)方法的教程參見(jiàn)這里。首先需要做的是在A機(jī)器上給rootfs創(chuàng)建一個(gè)只讀快照(注意下面命令是在A機(jī)器上執(zhí)行的):

btrfs subvolume snapshot -r / /ubuntu

注意上面命令中快照的名字要和目標(biāo)子卷的名字相同,這樣可以省去將來(lái)改名的麻煩。然后就可以使用btrfs send命令來(lái)把快照/ubuntu中的內(nèi)容發(fā)送到目的地了,在這之前我們需要暫時(shí)刪除我們分區(qū)的時(shí)候創(chuàng)建的ubuntu子卷,這個(gè)子卷會(huì)在接收過(guò)程中自動(dòng)重新創(chuàng)建:

btrfs subvolume delete /mnt/ubuntussh root@192.168.88.3 btrfs send /ubuntu | btrfs receive /mnt

最后在A機(jī)器上把剛剛創(chuàng)建的快照刪除就可以了

btrfs subvolume delete /ubuntu

bootloader與fstab

系統(tǒng)裝好了,我們的fstab還沒(méi)設(shè)置,啟動(dòng)管理器也還沒(méi)安裝配置。下面來(lái)講講怎么配置這兩樣?xùn)|西。我們之前說(shuō)過(guò)一定要給分區(qū)取一個(gè)Label,玄機(jī)在這里。如何在虛擬機(jī)中直接運(yùn)行本地磁盤(pán)上安裝的Linux,以及如何能把一個(gè)系統(tǒng)直接進(jìn)行打包帶走而不需要更改太多配置,關(guān)鍵也在這里。

fstab

先來(lái)說(shuō)說(shuō)fstab,fstab總共有五列,分別為fs、mountpoint、type、opts跟dump/pass。這五列分別為什么意思、以及fstab該怎么填,網(wǎng)上一查便知,在此不再贅述。這里只說(shuō)我們需要做的跟常規(guī)不一樣的地方。

第一個(gè)要注意的事情是,大家在填寫(xiě)fstab的時(shí)候,通常喜歡在fs那一列填寫(xiě)類(lèi)似/dev/sda4或者UUID=d5acc217-d524-4a2d-a937-bad945a047b2,而在這里這樣是不行的,這里我們填寫(xiě)的是形如/dev/disk/by-label/linux這樣的東西。也就是說(shuō),我們的fstab里面是通過(guò)分區(qū)的Label來(lái)找分區(qū)的。這么做的原因是,我們希望我們的rootfs不光能在這臺(tái)機(jī)器上啟動(dòng),還希望它能在虛擬機(jī)的環(huán)境中,或者當(dāng)我們把rootfs打包帶走同步到別的機(jī)器上的時(shí)候,也能正常啟動(dòng)。在這臺(tái)機(jī)器上rootfs所在的分區(qū)叫做/dev/sda4,在別的機(jī)器上或者虛擬機(jī)里就不一定還叫/dev/sda4了。但是我們只要遵守自己的命名規(guī)則,所有機(jī)器上的這些分區(qū)我們都取相同的Label,那么我們的fstab就是放之四海而皆準(zhǔn)的,不需要為不同的環(huán)境而更改。

第二個(gè)需要注意的問(wèn)題是,不要填寫(xiě)rootfs的條目。這種做法跟通常發(fā)行版或者其他用戶(hù)的默認(rèn)做法是非常不相同的。為了理解這一點(diǎn),先來(lái)說(shuō)說(shuō)Linux系統(tǒng)的啟動(dòng)過(guò)程。通常情況下,Linux啟動(dòng)的時(shí)候,首先由bootloader把內(nèi)核裝載到內(nèi)存,并向內(nèi)核傳遞參數(shù)告訴內(nèi)核rootfs的位置。接下來(lái)內(nèi)核就會(huì)根據(jù)傳遞的參數(shù),以只讀方式掛載rootfs,并執(zhí)行rootfs中的init程序。init程序會(huì)調(diào)用相應(yīng)的初始化程序執(zhí)行各種初始化操作。其中一項(xiàng)初始化操作就是根據(jù)fstab的配置,來(lái)重新以讀寫(xiě)方式掛載rootfs,并且掛載fstab里面配置的其他各個(gè)分區(qū)到指定位置。明白了Linux啟動(dòng)的過(guò)程,我們就知道,fstab里面的rootfs那一行其實(shí)不是必須的。刪掉了rootfs那一行,我們只需要通過(guò)修改bootloader傳遞給內(nèi)核的參數(shù),就可以告訴內(nèi)核直接以讀寫(xiě)而不是只讀的方式掛載rootfs。

那么,我們?cè)趯?xiě)fstab的時(shí)候不寫(xiě)rootfs那一項(xiàng)有啥好處呢?好處就是,我們不僅希望我們的系統(tǒng)能在裸機(jī)上用,還希望我們的系統(tǒng)能在虛擬機(jī)上用。在下文設(shè)置qemu虛擬機(jī)的時(shí)候,我們會(huì)以virtfs的方式把我們的子卷傳遞給虛擬機(jī),這個(gè)時(shí)候rootfs就已經(jīng)不再是/dev/disk/by-label/linux了,如果我們把rootfs的掛載方式硬編碼到fstab里面,那么會(huì)導(dǎo)致init程序的失敗,進(jìn)而無(wú)法啟動(dòng)。

另外有一點(diǎn)值得一提的小技巧是,很多時(shí)候我們還有別的一些個(gè)分區(qū)想要自動(dòng)掛載。問(wèn)題在于,這些分區(qū)在虛擬機(jī)環(huán)境中,并不一定是存在的,這就會(huì)導(dǎo)致啟動(dòng)的時(shí)候由于無(wú)法掛載而啟動(dòng)失敗。其實(shí)系統(tǒng)的設(shè)計(jì)者早就考慮到這個(gè)問(wèn)題了。如果你不希望fstab中的某些條目自動(dòng)掛載,在選項(xiàng)里面增加noauto即可。如果你希望一些條目自動(dòng)掛載,但是這些條目不是那么重要,即使掛載失敗也不希望這些條目導(dǎo)致啟動(dòng)失敗,可以在選項(xiàng)中增加nofail。這兩個(gè)選項(xiàng)真的是給我們的系統(tǒng)管理工作提供了非常大的方便。比如說(shuō)我們可能會(huì)在fstab中增加/dev/disk/by-label/swap的條目,以便開(kāi)機(jī)自動(dòng)將這個(gè)分區(qū)設(shè)置為交換分區(qū)供系統(tǒng)使用。然而后面我們會(huì)看到,我們?cè)O(shè)置虛擬機(jī)的時(shí)候,這個(gè)分區(qū)在虛擬機(jī)環(huán)境下,并不一定是可用的。這種情況下,我們希望系統(tǒng)在找不到這個(gè)分區(qū)的時(shí)候直接忽略錯(cuò)誤不用swap便是,而不是報(bào)錯(cuò)拒絕啟動(dòng)。

說(shuō)了這么多,直接貼一個(gè)fstab的例子好了:

tmpfs /tmptmpfsdefaults0 0/dev/disk/by-label/swapnoneswapdefaults,nofail0 0

bootloader

再來(lái)說(shuō)說(shuō)啟動(dòng)管理器,這里作者推薦的啟動(dòng)管理器是refind,安裝教程官網(wǎng)有,在此不贅述。這里只講一下啟動(dòng)項(xiàng)怎么寫(xiě)。先貼示例代碼:

其中第三行的volume用來(lái)指定內(nèi)核存放的分區(qū),此分區(qū)可以通過(guò)多種方式來(lái)指定,比如通過(guò)分區(qū)的GUID,但是對(duì)我們來(lái)說(shuō)最重要的是可以通過(guò)文件系統(tǒng)的Label來(lái)指定。我們的rootfs分區(qū)Label是”linux”,所以這一行寫(xiě)作volume linux。

接下來(lái)就是指定內(nèi)核位置、內(nèi)核參數(shù)跟initramfs的位置了。其中l(wèi)oader用來(lái)指定內(nèi)核位置,options用來(lái)指定內(nèi)核參數(shù),initrd則用來(lái)指定initramfs的位置。示例中的是Archlinux系統(tǒng),內(nèi)核是archlinux子卷中的boot/vmlinuz-linux文件,所以寫(xiě)作loader archlinux/boot/vmlinuz-linux。類(lèi)似,initrd那一行則寫(xiě)作initrd archlinux/boot/initramfs-linux.img。至于內(nèi)核參數(shù),root=/dev/disk/by-label/linux告訴內(nèi)核我們的rootfs所在的分區(qū),rootflags=subvol=archlinux告訴內(nèi)核掛載名為archlinux的子卷,rw則告訴內(nèi)核以讀寫(xiě)方式掛載。對(duì)于Ubuntu系統(tǒng),這三行應(yīng)該寫(xiě)作:

loader ubuntu/vmlinuzoptions "root=/dev/disk/by-label/linux rootflags=subvol=ubuntu rw"initrd ubuntu/initrd.img

細(xì)心的讀者可能已經(jīng)發(fā)現(xiàn),我們的refind的配置文件中在指定分區(qū)的時(shí)候用的全是他們的Label,這就保證了這個(gè)配置文件的普適性,換臺(tái)電腦,只要你用同樣的管理方式,同樣的命名習(xí)慣,配置文件里面的東西動(dòng)都不用動(dòng),直接拷貝過(guò)去就行。

系統(tǒng)的備份與恢復(fù)以及快照的應(yīng)用

由于使用了btrfs的動(dòng)態(tài)卷,所以備份恢復(fù)工作做起來(lái)非常簡(jiǎn)單。備份系統(tǒng)只需要?jiǎng)?chuàng)建快照即可:

cd /mntbtrfs subvolume snapshot archlinux backup

至于恢復(fù),其實(shí)我們根本不需要恢復(fù),直接把快照作為rootfs用就行。我們只需要去refind的配置文件里面,把相應(yīng)的啟動(dòng)項(xiàng)改改即可。比如說(shuō)對(duì)于Archlinux而言,只需要改成:

如果有強(qiáng)迫癥,覺(jué)得rootfs名字不叫archlinux很不爽,那其實(shí)改名也很簡(jiǎn)單:

其實(shí),btrfs的快照功能不僅可以用來(lái)備份與恢復(fù)系統(tǒng),還有很多非常靈活的運(yùn)用的。比如說(shuō)我想在系統(tǒng)里面安裝一個(gè)巨大而又混亂的軟件,這個(gè)軟件我只想用幾天干一件事情,干完這件事情我就不想用了。問(wèn)題是,這個(gè)軟件在官方的軟件倉(cāng)庫(kù)并沒(méi)有,要安裝,我只能使用軟件提供的安裝程序來(lái)安裝,然而軟件并沒(méi)有提供卸載程序,或者卸載程序卸載的很不徹底,會(huì)在系統(tǒng)殘留垃圾。我想用這軟件,然而又不想臟了我的系統(tǒng),這該怎么辦?很簡(jiǎn)單:創(chuàng)建一個(gè)快照,新增加一條以快照為rootfs的啟動(dòng)項(xiàng),要用軟件了就啟動(dòng)到快照中去,用完這個(gè)軟件以后把快照刪除即可。再比如說(shuō),我想要搞個(gè)虛擬機(jī)跟實(shí)體機(jī)一起來(lái)測(cè)試某個(gè)東西(比如說(shuō)測(cè)試某些網(wǎng)絡(luò)協(xié)議、測(cè)試某些集群管理軟件等),這個(gè)時(shí)候我根本沒(méi)必要重新用安裝光盤(pán)去裝一個(gè)虛擬機(jī),只需要?jiǎng)?chuàng)建一個(gè)快照,然后把快照作為虛擬機(jī)的rootfs啟動(dòng)即可,具體方法下文會(huì)介紹,在此不多說(shuō)。當(dāng)然,快照的應(yīng)用還遠(yuǎn)遠(yuǎn)不止我說(shuō)的這些,更多好玩的應(yīng)用還待讀者自己探索。

Windows下訪(fǎng)問(wèn)Linux

從文章的剛開(kāi)頭我們就說(shuō),有時(shí)候我們是有在Windows下運(yùn)行本地安裝的Linux的需求的。這個(gè)需求可以通過(guò)VirtualBox來(lái)滿(mǎn)足,只需要在VirtualBox中使用本地磁盤(pán)來(lái)作虛擬磁盤(pán)即可。說(shuō)起來(lái)簡(jiǎn)單,但是實(shí)現(xiàn)起來(lái)還是需要折騰一下子的。

首先我們需要新建一個(gè)虛擬機(jī),具體過(guò)程不多說(shuō),一路“下一步”就行了,唯一需要注意的是,在創(chuàng)建虛擬磁盤(pán)的那一步,選擇“不添加虛擬硬盤(pán)”:

這里我的虛擬機(jī)取名為“Linux”。創(chuàng)建完虛擬機(jī)了以后,就需要把本地磁盤(pán)設(shè)置為虛擬磁盤(pán)了。首先要做的是尋找我們安裝Linux的磁盤(pán)的編號(hào),這個(gè)可以在系統(tǒng)自帶的磁盤(pán)管理程序中找到,在我的機(jī)器上這個(gè)磁盤(pán)編號(hào)為2:

知道了磁盤(pán)的編號(hào),就可以創(chuàng)建虛擬盤(pán)了。這里我們使用的命令如下,注意使用管理員身份運(yùn)行:

VBoxManage internalcommands createrawvmdk -filename "C:UsersgaoxiangVirtualBox VMsLinuxlocaldisk.vmdk" -rawdisk .PhysicalDrive2

有了虛擬磁盤(pán)了,就可以將虛擬磁盤(pán)添加到虛擬機(jī)中去了:

虛擬磁盤(pán)設(shè)置好了,最后一步就是設(shè)置EFI了。由于我們之前在分區(qū)的時(shí)候給文件系統(tǒng)都賦予了Label,并且在refind設(shè)置的時(shí)候也是用的Label來(lái)指定分區(qū),所以同一套refind的配置在虛擬機(jī)上也能用。因此我們不需要單獨(dú)給虛擬機(jī)安裝bootloader,而是直接用我們之前安裝在物理磁盤(pán)上的EFI分區(qū)中的refind就行。VitualBox默認(rèn)是不開(kāi)啟EFI的,我們需要在虛擬機(jī)的系統(tǒng)設(shè)置里面手動(dòng)勾選EFI:

為了要讓VirtualBox自動(dòng)啟動(dòng)refind,還要對(duì)EFI的分區(qū)做一些簡(jiǎn)單的設(shè)置,設(shè)置的時(shí)候一定要注意,這些設(shè)置一定要是通用的,即同一份文件既能在物理機(jī)上正常工作也能在虛擬機(jī)上正常工作,不要改完了設(shè)置以后虛擬機(jī)上能跑了物理機(jī)卻掛了,這就不好玩了。VirtualBox的EFI在啟動(dòng)的時(shí)候會(huì)優(yōu)先選擇/EFI/BOOT/BOOTX64.EFI,如果找不到的話(huà),才會(huì)啟動(dòng)EFI分區(qū)根目錄下的startup.nsh中指定的bootloader。知道了這一點(diǎn),為了實(shí)現(xiàn)自動(dòng)啟動(dòng)refind,首先需要檢查一下/EFI/BOOT/BOOTX64.EFI這個(gè)文件是否存在,若存在,備份并刪除之:

cd EFI/BOOTmv bootx64.efi bootx64-backup.efi

然后就是在EFI分區(qū)根目錄下新建一個(gè)startup.nsh了,這個(gè)文件只需要一行,內(nèi)容如下:

EFI efind efind_x64.efi

一切設(shè)置完畢,運(yùn)行虛擬機(jī),就能看到我們熟悉的refind界面了:

打開(kāi)其中的Ubuntu系統(tǒng),測(cè)試一切正常就大功告成了:

當(dāng)然,要在虛擬機(jī)中使用,還有一些細(xì)節(jié)性的工作要處理,比如安裝VirtualBox的guest需要的相應(yīng)的內(nèi)核模塊等等,這些在此不談,讀者使用過(guò)程中如果發(fā)現(xiàn)少啥了,自己裝上便是。

Linux下不同發(fā)行版的互相訪(fǎng)問(wèn)

我們已經(jīng)成功地在Windows下運(yùn)行Linux了,下一步就是想辦法在一個(gè)Linux系統(tǒng)下訪(fǎng)問(wèn)其他Linux了。由于這些系統(tǒng)都是Linux,而且都在同一個(gè)文件系統(tǒng)里面,所以如果只是想要訪(fǎng)問(wèn)一下里面的文件的話(huà),掛載了用就行了。但是很多時(shí)候我們還是有需要來(lái)運(yùn)行其他系統(tǒng)里面安裝的程序,或者對(duì)那個(gè)系統(tǒng)進(jìn)行管理的。應(yīng)對(duì)這種需求有兩種解決方案:容器跟虛擬機(jī)。

可能很多讀者并不了解這兩者的區(qū)別,這里簡(jiǎn)單介紹一下。粗略來(lái)講,虛擬機(jī)是通過(guò)軟件的方式虛擬出一套硬件環(huán)境來(lái),并在這套硬件環(huán)境中啟動(dòng)內(nèi)核,然后內(nèi)核會(huì)進(jìn)行一個(gè)完整的開(kāi)機(jī)過(guò)程,包括進(jìn)行相應(yīng)的初始化,加載init程序等。相比之下,容器則要輕量很多。容器并不會(huì)虛擬出自己的硬件環(huán)境,也不會(huì)額外加載一個(gè)內(nèi)核。容器所做的,就是在現(xiàn)有內(nèi)核上,運(yùn)用namespace來(lái)創(chuàng)建出一套獨(dú)立的進(jìn)程PID、掛載點(diǎn)、網(wǎng)絡(luò)接口、用戶(hù)ID等等,由于不同namespace中的這些個(gè)ID之類(lèi)的標(biāo)識(shí)符都是獨(dú)立的,所以不同namespace中的進(jìn)程是互相之間看不到對(duì)方的,虛擬出來(lái)的環(huán)境乍看上去就跟在單獨(dú)運(yùn)行的一個(gè)系統(tǒng)一樣,同樣有PID為1的init進(jìn)程,有自己一套獨(dú)立的rootfs,等等。虛擬機(jī)的優(yōu)點(diǎn)是更不容易被突破,安全性更好,可以使用自己的內(nèi)核,但是效率也更低。容器的優(yōu)點(diǎn)是輕便效率高,但是安全性就要稍差一些,也沒(méi)法使用定制內(nèi)核。

容器

Linux下大家最熟悉的容器就是chroot了,但是作者并不喜歡chroot,主要原因有兩點(diǎn):

/proc、 /dev等東西不會(huì)自動(dòng)掛載,每次手動(dòng)掛載掛的心好累

沒(méi)有一個(gè)相對(duì)完整的開(kāi)機(jī)過(guò)程,好多我希望自動(dòng)啟動(dòng)的服務(wù)并不會(huì)運(yùn)行起來(lái)

基于上面的原因,作者在這里推薦的容器是systemd-nspawn。systemd-nspawn的使用非常簡(jiǎn)單,假設(shè)你的linux分區(qū)已經(jīng)mount到了/mnt上去了,那么你只需要下面步驟就能啟動(dòng)一個(gè)systemd-nspawn容器(以Debian為例):

cd /mnt/debiansystemd-nspawn -b

然后就能看到刷刷刷的開(kāi)機(jī)界面了,真的是非常的方便快捷。這里還有一點(diǎn)小技巧是,如果嫌每次開(kāi)容器都要把linux分區(qū)掛載到/mnt上太麻煩,可以在/var/lib/machines里面為每個(gè)系統(tǒng)新建一個(gè)目錄,然后在fstab里面設(shè)置一下自動(dòng)把相應(yīng)的子卷掛載進(jìn)去:

這么做的好處是,根目錄位于/var/lib/machines的系統(tǒng),在啟動(dòng)systemd-nspawn的時(shí)候可以直接使用-M選項(xiàng)來(lái)指定系統(tǒng),而不需要進(jìn)入相應(yīng)目錄。比如如果想啟動(dòng)Ubuntu系統(tǒng):

systemd-nspawn -b -M ubuntu

虛擬機(jī)

如果只是想運(yùn)行一下其他系統(tǒng)里面的程序,那么容器完全就夠用了,但是有的時(shí)候我們還是需要玩玩不同的內(nèi)核的,這就必須得用虛擬機(jī)了。通常情況下,大家用虛擬機(jī),都是新建一個(gè)磁盤(pán)鏡像,然后插入安裝光盤(pán),然后把光盤(pán)安裝到鏡像上。這么做的壞處,一個(gè)是訪(fǎng)問(wèn)鏡像中的文件不方便,另一個(gè)是,我們?cè)诒镜匾呀?jīng)有安裝過(guò)若干系統(tǒng)了,不去充分利用一下這些而去再重新往鏡像里面安裝那實(shí)在是舍近求遠(yuǎn)。那我們就來(lái)找一個(gè)把子卷當(dāng)成虛擬機(jī)rootfs的方法。困難在于,虛擬機(jī)是個(gè)很獨(dú)立的東西,是無(wú)法直接訪(fǎng)問(wèn)宿主機(jī)的文件系統(tǒng)的。然而幸運(yùn)的是,Linux的內(nèi)核虛擬化方案KVM提供了一個(gè)把本地文件系統(tǒng)傳遞給虛擬機(jī)的解決方案,用到的東西叫做VirtFS。

好消息是,VirtFS是可以作為rootfs的。但是要能正常掛載VirtFS,內(nèi)核必須要有相應(yīng)的驅(qū)動(dòng)才行。這里有兩種方法可以做到這一點(diǎn)。如果你是自己編譯內(nèi)核的話(huà),那么建議直接將相應(yīng)的驅(qū)動(dòng)編譯進(jìn)內(nèi)核而不是模塊。根據(jù)官網(wǎng)的指示,涉及到的內(nèi)核配置如下:

CONFIG_NET_9P=yCONFIG_NET_9P_VIRTIO=yCONFIG_9P_FS=yCONFIG_9P_FS_POSIX_ACL=y

如果使用的是發(fā)行版提供的內(nèi)核的話(huà),那么可以修改initramfs的相關(guān)設(shè)置保證9p、9pnet、9pnet_virtio三個(gè)modules能被安裝到initramfs里面去。這里以Ubuntu做guest為例,具體做法是修改Ubuntu系統(tǒng)中的/etc/initramfs-tools/modules文件,增加下面三行:

9p9pnet9pnet_virtio

然后重新生成initramfs即可:

update-initramfs -u

內(nèi)核驅(qū)動(dòng)設(shè)置好了,就可以啟動(dòng)qemu虛擬機(jī)了,這里假定Ubuntu的rootfs已經(jīng)被mount到了/var/lib/machines/ubuntu:

qemu-system-x86_64 -enable-kvm -m 16G -kernel /var/lib/machines/ubuntu/vmlinuz -initrd /var/lib/machines/ubuntu/initrd.img -virtfs local,id=root9p,path=/var/lib/machines/ubuntu,security_model=passthrough,mount_tag=root9p -nographic -append 'root=root9p rw rootfstype=9p rootflags=trans=virtio console=ttyS0 init=/lib/systemd/systemd'

最后放一張成功的截圖:

無(wú)盤(pán)系統(tǒng)

在某些特定的應(yīng)用場(chǎng)景中,無(wú)盤(pán)系統(tǒng)用起來(lái)還是有不少方便之處的。尤其對(duì)于計(jì)算機(jī)集群而言,使用無(wú)盤(pán)系統(tǒng)不光能節(jié)省購(gòu)買(mǎi)硬盤(pán)的成本,還能大大簡(jiǎn)化集群的管理。雖然我們并沒(méi)有集群要管理,但是做一個(gè)無(wú)盤(pán)系統(tǒng)放在硬盤(pán)上用來(lái)代替livecd,在需要的時(shí)候進(jìn)行一些系統(tǒng)恢復(fù)類(lèi)的操作還是不錯(cuò)的。對(duì)同時(shí)安裝有多個(gè)Linux的同學(xué)來(lái)說(shuō),其實(shí)用到livecd的時(shí)候并不多,偶爾一個(gè)系統(tǒng)出故障了,進(jìn)其他系統(tǒng)把故障系統(tǒng)修復(fù)了就好。但是有些操作還是不得不用livecd的,比如要調(diào)整Linux分區(qū)的大小跟位置,這個(gè)分區(qū)就不能處于掛載狀態(tài),這就不得不用到livecd了。相比于livecd,自己做的無(wú)盤(pán)系統(tǒng)的好處主要是可定制性。舉個(gè)不少人遇到過(guò)的實(shí)際例子來(lái)說(shuō):系統(tǒng)出故障了,進(jìn)livecd修復(fù)系統(tǒng),當(dāng)試圖使用vim更改某配置文件的時(shí)候,系統(tǒng)提示說(shuō)vim并沒(méi)有安裝,想要安裝,系統(tǒng)又提示說(shuō)文件系統(tǒng)是只讀的,無(wú)法安裝。其實(shí)沒(méi)有vim還只是小事,用vi或者nano將就一下也就過(guò)去了。但是如果自己千辛萬(wàn)苦下載并刻錄livecd,卻發(fā)現(xiàn)自己修復(fù)系統(tǒng)必備的軟件沒(méi)有且不能安裝,那估計(jì)砸電腦的心都有了吧。既然livecd這么不好用,那為什么不搞一個(gè)跟自己平時(shí)使用的桌面一模一樣的無(wú)盤(pán)系統(tǒng)呢?

要做無(wú)盤(pán)系統(tǒng),一種做法是在另一臺(tái)機(jī)器上搞個(gè)nfs,然后在本機(jī)啟動(dòng)的時(shí)候用nfs當(dāng)做root來(lái)啟動(dòng)(需要在內(nèi)核配置中開(kāi)啟ROOT_NFS選項(xiàng)),這種做法優(yōu)點(diǎn)是內(nèi)存占用相對(duì)較?。ǜ髡呓酉聛?lái)要介紹的方法相比簡(jiǎn)直是小多了),但是配置起來(lái)比較麻煩,而且網(wǎng)絡(luò)延遲跟帶寬也嚴(yán)重制約系統(tǒng)的性能。由于作者的電腦內(nèi)存有128G之多,可以隨便揮霍不需要節(jié)約內(nèi)存,并且作者只想簡(jiǎn)單粗暴地把自己平時(shí)使用的桌面做成無(wú)盤(pán)系統(tǒng)來(lái)啟動(dòng),并不想多折騰。所以,作者最終采用的方案是基于initramfs的。要想理解制作過(guò)程,需要先了解幾個(gè)術(shù)語(yǔ):

ramfs、tmpfs、rootfs以及initramfs

要想理解這個(gè)方案的工作原理,需要先了解一下本小節(jié)標(biāo)題中的這幾個(gè)術(shù)語(yǔ)。這幾個(gè)術(shù)語(yǔ)在內(nèi)核的官方文檔中有很好的解釋?zhuān)谶@里我們只做一個(gè)簡(jiǎn)單的概括。

首先要從Linux的磁盤(pán)緩存機(jī)制說(shuō)起。程序訪(fǎng)問(wèn)文件的時(shí)候,Linux會(huì)把文件讀到內(nèi)存中緩存起來(lái)。磁盤(pán)緩存中的文件,如果沒(méi)被修改過(guò),或者被修改過(guò)但是改動(dòng)已經(jīng)從緩存同步到磁盤(pán)中去了,這種情況下內(nèi)核會(huì)把對(duì)應(yīng)的磁盤(pán)緩存標(biāo)記為干凈(clean)的。對(duì)于被修改過(guò),但是還沒(méi)來(lái)得及同步到磁盤(pán)的文件,內(nèi)核會(huì)將其標(biāo)記為臟(dirty)的。當(dāng)Linux內(nèi)存不足,需要釋放內(nèi)存的時(shí)候,Linux會(huì)將磁盤(pán)緩存中的一些干凈的部分釋放掉,從而將內(nèi)存挪作他用。ramfs是一個(gè)虛擬的文件系統(tǒng),直觀上來(lái)講,它相當(dāng)于直接把磁盤(pán)緩存給掛載到相應(yīng)的節(jié)點(diǎn)上去了:它其中的文件只存活在磁盤(pán)緩存中。并且由于沒(méi)有物理磁盤(pán)可以將數(shù)據(jù)同步出去,所以這些文件的緩存始終是臟的,這也保證了這些文件不會(huì)被內(nèi)核釋放掉。而tmpfs則是對(duì)ramfs的一個(gè)擴(kuò)展,相比于ramfs,它允許限制文件系統(tǒng)的大小,也允許數(shù)據(jù)被搬運(yùn)到swap中去。

rootfs也是一個(gè)虛擬的文件系統(tǒng),它是專(zhuān)門(mén)在啟動(dòng)的時(shí)候使用的一個(gè)特殊的ramfs。要想理解rootfs,需要了解Linux內(nèi)核的啟動(dòng)過(guò)程。這個(gè)過(guò)程位于內(nèi)核源碼init/main.c文件中的kernel_init函數(shù)中,有興趣的讀者可以讀一下以便深入了解。簡(jiǎn)單概括就是:Linux啟動(dòng)的時(shí)候,會(huì)創(chuàng)建一個(gè)rootfs,并把根目錄“/”掛載為rootfs。這個(gè)rootfs將會(huì)伴隨Linux終生:跟init進(jìn)程無(wú)法被終止道理類(lèi)似,rootfs是無(wú)法被卸載的。rootfs創(chuàng)建好以后,Linux內(nèi)核會(huì)把bootloader提供的initramfs文件中的內(nèi)容解壓到rootfs中去,如果解壓好的文件中能找到/init或者用戶(hù)通過(guò)rdinit=內(nèi)核參數(shù)指定的其他init程序,那么內(nèi)核會(huì)執(zhí)行這個(gè)init程序,并將接下來(lái)的初始化工作(比如掛載真正的root、刪除舊的rootfs中的內(nèi)容以節(jié)約內(nèi)存、執(zhí)行真正的root中的init程序)交由這個(gè)init程序負(fù)責(zé)。如果此時(shí)rootfs中無(wú)法找到相應(yīng)的init程序,Linux就會(huì)嘗試掛載真正的root,并執(zhí)行root中的init程序。

基于initramfs的無(wú)盤(pán)系統(tǒng)制作

了解了上述的原理,我們的無(wú)盤(pán)系統(tǒng)制作思路也就清晰了:我們直接把自己的桌面打包成一個(gè)cpio,然后作為initramfs提供給內(nèi)核,然后通過(guò)rdinit參數(shù)告訴內(nèi)核啟動(dòng)systemd即可。具體做法,這里就以Ubuntu為例,并假定Linux分區(qū)被掛載在/mnt中。首先需要把我們的桌面制作成一個(gè)cpio包:

cd /mnt/ubuntufind -mindepth 1 -printf '%P