systemd-nspawn 快速指南

贊 回覆發表於2015-01-16

我目前已從 chroot(譯者注:chroot可以構建類似沙盒的環境,建議各位同學先了解chroot) 遷移到 systemd-nspawn,同時我寫了一篇快速指南。簡單的說,我強烈建議正在使用 systemd 的使用者從 chroot 轉為 systemd-nspawn,因為只要你的核心配置正確的話,它幾乎沒有什麼缺點。

想必在各大發行版中的使用者對 chroot 都不陌生,而且我猜想 Gentoo 使用者要時不時的使用它。

chroot 面臨的挑戰

大多數互動環境下,僅執行chroot還不夠。通常還要掛載 /proc, /sys,另外為了確保不會出現類似“丟失 ptys”之類的錯誤,我們還得 bind(譯者注:bind 是 mount 的一個選項) 掛載 /dev。如果你使用 tmpfs,你可能想要以 tmpfs 型別掛載新的 tmp、 var/tmp。接下來你可能還想將其他的掛載點 bind 到 chroot 中。這些都不是特別難,但是一般情況下要寫一個指令碼來管理它。

現在我按照日常計劃執行備份操作,當然有一些不必備份的資料如 tmp 目錄,或任何 bind 掛載的內容。當我配置了一個新的 chroot 後就意味著我要更新我的備份配置了,但我經常忘記這點,因為大多數時間裡 chroot 掛載點並沒有執行。當這些掛載點仍然存在的情況下執行備份的話,那麼備份中會多出很多不需要的內容。

當 bind 掛載點包含其他掛載點時(比如掛載時使用 -rbind 選項),這種情況下 systemd 的預設處理方式略有不同。在 bind 掛載中解除安裝一些東西時,systemd 會將處於 bind 另一邊的目錄也解除安裝掉。想像一下,如果我解除安裝了 chroot 中以 bind 掛載 /dev 的某個目錄後,發現主機上的 /dev/pts 與 /dev/shm 也不見了,我肯定會很吃驚。不過好像有其他方法可以避免,但是這不是我們此次討論的重點。

Systemd-nspawn 優點

Systemd-nspawn 用於啟動一個容器,並且它的最簡模式就可以像 chroot 那樣執行。預設情況下,它自動配置容器所需的開銷如 /dev, /tmp 等等。通過配合一些選項它也可配置其他的 bind 掛載點。當容器退出後,所有的掛載點都會被清除。

容器執行時,從外部看上去沒什麼變化。事實上,可以從同一個 chroot 產生5個不同的 systemd-nspawn 容器例項,並且除了檔案系統(不包括 /dev, /tmp等,只有 /usr,/etc 的改變會傳遞)外它們之間沒有任何聯絡。你的備份將會忽略 bind 掛載點、tmpfs 及任何掛載在容器中的內容。

它同時具有其它優秀容器的優點,比如 containment - 可以殺死容器內的所有活動但不影響外部,等等。它的安全性並不是無懈可擊的-它的作用僅僅是防止意外的錯誤。

如果你使用的是相容的 sysvinit(它包含了 systemd,openrc),你可以啟動容器。這意味著,你可以在容器中使用 fstab 新增掛載點,執行守護程式等。只需要一個 chroot 的開銷,幾乎就可以獲得虛擬化的所有好處(不需要構建核心等)。在一個看起來像 chroot 的容器中執行systemctl poweroff 看起來很奇怪,但這條命令能夠起作用。

注意,如果不做額外配置的話那麼容器就會共享主機的網路,所以主機上的容器不要執行 sshd。執行一個分離的網路 namespace 不是太難,為了新的例項可以使用DHCP,分離之後記得繫結介面。

操作步驟

讓它工作起來是此次討論中最簡短的部分了。

首先系統核心要支援 namespaces 與 devpts:

CONFIG_UTS_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_DEVPTS_MULTIPLE_INSTANCES=y

像 chroot 那樣啟動 namespace 是非常簡單的:

systemd-nspawn -D .

也可以像 chroot 那樣退出。在內部可以執行 mount 並且可以看到預設它已將 /dev 與 /tmp 準備好了。 ”.“就是 chroot 的路徑,也就是當前路徑。在它內部執行的是 bash。

如果要新增一些 bind 掛載點也非常簡便:

systemd-nspawn -D . --bind /usr/portage

現在,容器中的 /usr/portage 就與主機的對應目錄繫結起來了,我們無需 sync /etc。如果想要繫結到指定的路徑,只要在原路徑後新增 ”:dest“,相當於 chroot 的 root(--bind foo 與 --bind foo:foo是一樣的)。

如果容器具有 init 功能並且可以在內部執行,可以通過新增 -b 選項啟動它:

systemd-nspawn -D . --bind /usr/portage -b

可以觀察到 init 的運作。關閉容器會自動退出。

如果容器內執行了 systemd ,你可以使用 -h 選項將它的日誌重定向到主機的systemd日誌:

systemd-nspawn -D . --bind /usr/portage -j -b

使用 nspawn 註冊容器以便它能夠在 machinectl 中顯示。如此可以方便的在主機上對它進行操作,如啟動新的 getty, ssh 連線,關機等。

如果你正在使用 systemd 那麼甩開 chroot 擁抱 nspawn 吧。


via: http://rich0gentoo.wordpress.com/2014/07/14/quick-systemd-nspawn-guide/

作者:rich0 譯者:SPccman 校對:wxy

本文由 LCTT 原創翻譯,Linux中國 榮譽推出

相關文章