Fedora中的容器技術

範大腳腳發表於2017-11-14
容器是什麼?

一個容器就是一個使用者空間例項,它能夠在與託管容器的系統(叫做宿主系統)相隔離的環境中執行一個程式或者一個作業系統。這和”chroot“或虛擬機器的思想非常類似。執行在容器中的程式是由與宿主作業系統相同的核心來管理的,但它們是與宿主檔案系統以及其它程式隔離開的。

什麼是 systemd-nspawn?

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

systemd-nspawn“和”chroot” 在許多方面都是類似的,但是前者更加強大。它虛擬化了檔案系統、程式樹以及客戶系統中的程式間通訊。它的吸引力在於它提供了很多用於管理容器的工具,例如用來管理容器的”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-analyze“和”systemctl“,都支援使用”–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“,我會執行下面的命令:


$ restorecon -R /home/johnmh/DebianJessie/

本文轉自Linux就該這麼學部落格園部落格,原文連結:http://www.cnblogs.com/linuxprobe/p/5743262.html,如需轉載請自行聯絡原作者


相關文章