Linux中國

Fedora 中的容器技術:systemd-nspawn

容器是什麼?

一個容器就是一個用戶空間實例,它能夠在與託管容器的系統(叫做宿主系統)相隔離的環境中運行一個程序或者一個操作系統。這和 chroot虛擬機 的思想非常類似。運行在容器中的進程是由與宿主操作系統相同的內核來管理的,但它們是與宿主文件系統以及其它進程隔離開的。

什麼是 systemd-nspawn?

systemd 項目認為應當將容器技術變成桌面的基礎部分,並且應當和用戶的其餘系統集成在一起。為此,systemd 提供了 systemd-nspawn,這款工具能夠使用多種 Linux 技術創建容器。它也提供了一些容器管理工具。

systemd-nspawnchroot 在許多方面都是類似的,但是前者更加強大。它虛擬化了文件系統、進程樹以及客戶系統中的進程間通信。它的吸引力在於它提供了很多用於管理容器的工具,例如用來管理容器的 machinectl。由 systemd-nspawn 運行的容器將會與 systemd 組件一同運行在宿主系統上。舉例來說,一個容器的日誌可以輸出到宿主系統的日誌中。

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

創建容器

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

一旦你創建完目錄,你需要運行 debootstrap,你可以從 Fedora 倉庫中安裝它。對於 Debian Jessie,你運行下面的命令來初始化一個 Debian 文件系統。

$ debootstrap --arch=amd64 stable ~/DebianJessie

以上默認你的架構是 x86_64。如果不是的話,你必須將架構的名稱改為 amd64。你可以使用 uname -m 得知你的機器架構。

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

$ systemd-nspawn -bD ~/DebianJessie

容器將會在數秒後準備好並運行,當你試圖登錄時就會注意到:你無法使用你的系統上任何賬戶。這是因為 systemd-nspawn 虛擬化了用戶。修復的方法很簡單:將之前的命令中的 -b 移除即可。你將直接進入容器的 root 用戶的 shell。此時,你只能使用 passwd 命令為 root 設置密碼,或者使用 adduser 命令添加一個新用戶。一旦設置好密碼或添加好用戶,你就可以把 -b 標誌添加回去然後繼續了。你會進入到熟悉的登錄控制台,然後你使用設置好的認證信息登錄進去。

以上對於任意你想在容器中運行的發行版都適用,但前提是你需要使用正確的包管理器創建系統。對於 Fedora,你應使用 DNF 而非 debootstrap。想要設置一個最小化的 Fedora 系統,你可以運行下面的命令,要將「/absolute/path/」替換成任何你希望容器存放的位置。

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

設置網路

如果你嘗試啟動一個服務,但它綁定了你宿主機正在使用的埠,你將會注意到這個問題:你的容器正在使用和宿主機相同的網路介面。幸運的是,systemd-nspawn 提供了幾種可以將網路從宿主機分開的方法。

本地網路

第一種方法是使用 --private-network 標誌,它默認僅創建一個迴環設備。這對於你不需要使用網路的環境是非常理想的,例如構建系統和其它持續集成系統。

多個網路介面

如果你有多個網路介面設備,你可以使用 --network-interface 標誌給容器分配一個介面。想要給我的容器分配 eno1,我會添加選項 --network-interface=eno1。當某個介面分配給一個容器後,宿主機就不能同時使用那個介面了。只有當容器徹底關閉後,宿主機才可以使用那個介面。

共享網路介面

對於我們中那些並沒有額外的網路設備的人來說,還有其它方法可以訪問容器。一種就是使用 --port 選項。這會將容器中的一個埠定向到宿主機。使用格式是 協議:宿主機埠:容器埠,這裡的協議可以是 tcp 或者 udp宿主機埠 是宿主機的一個合法埠,容器埠 則是容器中的一個合法埠。你可以省略協議,只指定 宿主機埠:容器埠。我通常的用法類似 --port=2222:22

你可以使用 --network-veth 啟用完全的、僅宿主機模式的網路,這會在宿主機和容器之間創建一個虛擬的網路介面。你也可以使用 --network-bridge 橋接二者的連接。

使用 systemd 組件

如果你容器中的系統含有 D-Bus,你可以使用 systemd 提供的實用工具來控制並監視你的容器。基礎安裝的 Debian 並不包含 dbus。如果你想在 Debian Jessie 中使用 dbus,你需要運行命令 apt install dbus

machinectl

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

其它 systemd 命令

多數 systemd 命令,例如 journalctl, systemd-analyzesystemctl,都支持使用 --machine 選項來指定容器。例如,如果你想查看一個名為 「foobar」 的容器的日誌,你可以使用 journalctl --machine=foobar。你也可以使用 systemctl --machine=foobar status service 來查看運行在這個容器中的服務狀態。

和 SELinux 一起工作

如果你要使用 SELinux 強制模式(Fedora 默認模式),你需要為你的容器設置 SELinux 環境。想要那樣的話,你需要在宿主系統上運行下面兩行命令。

$ semanage fcontext -a -t svirt_sandbox_file_t "/path/to/container(/.*)?"
$ restorecon -R /path/to/container/

確保使用你的容器路徑替換 「/path/to/container」。對於我的容器 "DebianJessie",我會運行下面的命令:

$ semanage fcontext -a -t svirt_sandbox_file_t "/home/johnmh/DebianJessie(/.*)?"
$ restorecon -R /home/johnmh/DebianJessie/

via: https://fedoramagazine.org/container-technologies-fedora-systemd-nspawn/

作者:John M. Harris, Jr. 譯者:ChrisLeeGit 校對:wxy

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


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國