天天看點

Fedora 中的容器技術:systemd-nspawn

歡迎來到“fedora 中的容器技術”系列!本文是該系列文章中的第一篇,它将說明你可以怎樣使用 fedora 中各種可用的容器技術。本文将學習 <code>systemd-nspawn</code> 的相關知識。

<a target="_blank"></a>

systemd 項目認為應當将容器技術變成桌面的基礎部分,并且應當和使用者的其餘系統內建在一起。為此,systemd 提供了 <code>systemd-nspawn</code>,這款工具能夠使用多種 linux 技術建立容器。它也提供了一些容器管理工具。

<code>systemd-nspawn</code> 和 <code>chroot</code> 在許多方面都是類似的,但是前者更加強大。它虛拟化了檔案系統、程序樹以及客戶系統中的程序間通信。它的吸引力在于它提供了很多用于管理容器的工具,例如用來管理容器的<code>machinectl</code>。由 <code>systemd-nspawn</code> 運作的容器将會與 systemd 元件一同運作在宿主系統上。舉例來說,一個容器的日志可以輸出到宿主系統的日志中。

在 fedora 24 上,<code>systemd-nspawn</code> 已經從 systemd 軟體包分離出來了,是以你需要安裝 <code>systemd-container</code> 軟體包。一如往常,你可以使用 <code>dnf install systemd-container</code> 進行安裝。

使用 <code>systemd-nspawn</code> 建立一個容器是很容易的。假設你有一個專門為 debian 創造的應用,并且無法在其它發行版中正常運作。那并不是一個問題,我們可以創造一個容器!為了設定容器使用最新版本的 debian(現在是 jessie),你需要挑選一個目錄來放置你的系統。我暫時将使用目錄 <code>~/debianjessie</code>。

一旦你建立完目錄,你需要運作 <code>debootstrap</code>,你可以從 fedora 倉庫中安裝它。對于 debian jessie,你運作下面的指令來初始化一個 debian 檔案系統。

<code>$ debootstrap --arch=amd64 stable ~/debianjessie</code>

以上預設你的架構是 x86_64。如果不是的話,你必須将架構的名稱改為 <code>amd64</code>。你可以使用 <code>uname -m</code> 得知你的機器架構。

一旦設定好你的根目錄,你就可以使用下面的指令來啟動你的容器。

<code>$ systemd-nspawn -bd ~/debianjessie</code>

容器将會在數秒後準備好并運作,當你試圖登入時就會注意到:你無法使用你的系統上任何賬戶。這是因為<code>systemd-nspawn</code> 虛拟化了使用者。修複的方法很簡單:将之前的指令中的 <code>-b</code> 移除即可。你将直接進入容器的 root 使用者的 shell。此時,你隻能使用 <code>passwd</code> 指令為 root 設定密碼,或者使用 <code>adduser</code> 指令添加一個新使用者。一旦設定好密碼或添加好使用者,你就可以把 <code>-b</code> 标志添加回去然後繼續了。你會進入到熟悉的登入控制台,然後你使用設定好的認證資訊登入進去。

以上對于任意你想在容器中運作的發行版都适用,但前提是你需要使用正确的包管理器建立系統。對于 fedora,你應使用 dnf 而非 <code>debootstrap</code>。想要設定一個最小化的 fedora 系統,你可以運作下面的指令,要将“/absolute/path/”替換成任何你希望容器存放的位置。

<code>$ sudo dnf --releasever=24 --installroot=/absolute/path/ install systemd passwd dnf fedora-release</code>

Fedora 中的容器技術:systemd-nspawn

如果你嘗試啟動一個服務,但它綁定了你主控端正在使用的端口,你将會注意到這個問題:你的容器正在使用和主控端相同的網絡接口。幸運的是,<code>systemd-nspawn</code> 提供了幾種可以将網絡從主控端分開的方法。

第一種方法是使用 <code>--private-network</code> 标志,它預設僅建立一個回環裝置。這對于你不需要使用網絡的環境是非常理想的,例如建構系統和其它持續內建系統。

如果你有多個網絡接口裝置,你可以使用 <code>--network-interface</code> 标志給容器配置設定一個接口。想要給我的容器配置設定 <code>eno1</code>,我會添加選項 <code>--network-interface=eno1</code>。當某個接口配置設定給一個容器後,主控端就不能同時使用那個接口了。隻有當容器徹底關閉後,主控端才可以使用那個接口。

對于我們中那些并沒有額外的網絡裝置的人來說,還有其它方法可以通路容器。一種就是使用 <code>--port</code> 選項。這會将容器中的一個端口定向到主控端。使用格式是 <code>協定:主控端端口:容器端口</code>,這裡的協定可以是 <code>tcp</code>或者 <code>udp</code>,<code>主控端端口</code> 是主控端的一個合法端口,<code>容器端口</code> 則是容器中的一個合法端口。你可以省略協定,隻指定 <code>主控端端口:容器端口</code>。我通常的用法類似 <code>--port=2222:22</code>。

你可以使用 <code>--network-veth</code> 啟用完全的、僅主控端模式的網絡,這會在主控端和容器之間建立一個虛拟的網絡接口。你也可以使用 <code>--network-bridge</code> 橋接二者的連接配接。

如果你容器中的系統含有 d-bus,你可以使用 systemd 提供的實用工具來控制并監視你的容器。基礎安裝的 debian 并不包含 <code>dbus</code>。如果你想在 debian jessie 中使用 <code>dbus</code>,你需要運作指令 <code>apt install dbus</code>。

為了能夠輕松地管理容器,systemd 提供了 <code>machinectl</code> 實用工具。使用 <code>machinectl</code>,你可以使用<code>machinectl login name</code> 登入到一個容器中、使用 <code>machinectl status name</code>檢查狀态、使用<code>machinectl reboot name</code> 啟動容器或者使用 <code>machinectl poweroff name</code> 關閉容器。

多數 systemd 指令,例如 <code>journalctl</code>, <code>systemd-analyze</code> 和 <code>systemctl</code>,都支援使用 <code>--machine</code> 選項來指定容器。例如,如果你想檢視一個名為 “foobar” 的容器的日志,你可以使用 <code>journalctl --machine=foobar</code>。你也可以使用 <code>systemctl --machine=foobar status service</code> 來檢視運作在這個容器中的服務狀态。

Fedora 中的容器技術:systemd-nspawn

如果你要使用 selinux 強制模式(fedora 預設模式),你需要為你的容器設定 selinux 環境。想要那樣的話,你需要在宿主系統上運作下面兩行指令。

<code>$ semanage fcontext -a -t svirt_sandbox_file_t "/path/to/container(/.*)?"</code>

<code>$ restorecon -r /path/to/container/</code>

確定使用你的容器路徑替換 “/path/to/container”。對于我的容器 "debianjessie",我會運作下面的指令:

<code>$ semanage fcontext -a -t svirt_sandbox_file_t "/home/johnmh/debianjessie(/.*)?"</code>

<code>$ restorecon -r /home/johnmh/debianjessie/</code>

原文釋出時間為:2016-07-28

本文來自雲栖社群合作夥伴“linux中國”

繼續閱讀