LXC 是 Linux 隔離功能的使用者空間介面。它結合 liblxc 函式庫、命令列工具及發行版範本,以建立系統容器:共享主機核心的隔離 Linux 使用者空間。
LXC 容器可以啟動 init 系統、執行多項服務、維護持久化套件狀態,並提供虛擬網路介面。因此,其運作模型更接近輕量級 Linux 機器,而非 OCI 應用程式容器。然而,LXC 仍是容器執行環境,因為它不會啟動客體核心或模擬硬體。
在虛擬化堆疊中的定位 #
LXC 協調多種核心機制,而不是在單一獨立子系統中實作隔離:
每個容器都會取得一組經選定且隔離的核心視圖:
| 機制 | 在 LXC 容器中的功能 |
|---|---|
| 命名空間 | 隔離程序 ID、掛載點、網路、IPC、主機名稱、使用者、cgroup 視圖及時鐘。 |
| cgroups v2 | 計量並限制 CPU、記憶體、程序數量、I/O 及裝置存取。 |
| Capabilities | 將傳統 root 權限拆分為可個別移除的權限。 |
| Seccomp | 篩選容器程序可使用的系統呼叫。 |
| AppArmor 或 SELinux | 限制透過共享核心仍然可見的主機資源。 |
| 使用者命名空間 | 將容器 UID 和 GID(包括容器 root)對應至非特權主機 ID。 |
命名空間決定程序能看見什麼,而 cgroups 決定程序能消耗多少資源。Capabilities、seccomp 及 Linux 安全模組會加入彼此獨立的限制,因為僅靠命名空間分隔並不足以構成完整的安全政策。
LXC 元件與更廣泛的生態系統 #
數個相關專案各自承擔不同職責:
| 專案 | 職責 |
|---|---|
| LXC | liblxc C 函式庫、lxc-* 生命週期工具、設定格式及發行版範本。 |
| LXCFS | 一種 FUSE 檔案系統,可呈現感知 cgroup 的 /proc 資料,例如容器專屬的 CPU 與記憶體資訊。 |
| Distrobuilder | 依據 YAML 定義建置根檔案系統與映像。 |
| Incus | 較高階的系統容器與虛擬機器管理器,預設使用 LXC 作為容器執行環境。 |
Incus 加入了常駐程式與 REST API,以及受管理的映像、設定檔、儲存集區、網路、專案、叢集和遷移功能。當主機需要直接控制本機容器而不使用管理常駐程式時,LXC 本身仍然適用。
不得將 LXD 和 Incus 視為 LXC 的別名。LXD 最初是建構於 LXC 之上的管理器。Incus 後來從 LXD 分支而來,目前由 Linux Containers 專案維護。
容器生命週期 #
download 範本會從 Linux Containers 映像伺服器取得發行版的根檔案系統。以下命令假設主機發行版已安裝 LXC,並已設定呼叫命令之使用者所需的 UID/GID 範圍與網路:
lxc-create --name web01 --template download -- \
--dist debian --release trixie --arch amd64
lxc-start --name web01 --daemon
lxc-info --name web01
lxc-attach --name web01
lxc-stop --name web01
lxc-destroy --name web01系統全域的預設容器位置為 /var/lib/lxc/<name>/。除非根檔案系統使用其他儲存後端,否則容器目錄會包含其設定與根檔案系統。相關生命週期工具包括:
- 使用
lxc-ls --fancy列出容器及其狀態; - 使用
lxc-console連線至已設定的主控台; - 使用
lxc-freeze和lxc-unfreeze,透過 cgroup freezer 暫停及恢復執行; lxc-copy在後端儲存區支援時複製容器或建立其快照所 要求的作業;以及- 使用
lxc-monitor和lxc-wait觀察狀態變更。
LXC 設定使用 key = value 項目。簡化的設定可以結合識別資訊、儲存、網路、UID 對應及資源控制:
lxc.uts.name = web01
lxc.rootfs.path = dir:/var/lib/lxc/web01/rootfs
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.idmap = u 0 100000 65536
lxc.idmap = g 0 100000 65536
lxc.cgroup2.memory.max = 2147483648
lxc.cgroup2.pids.max = 1024
lxc.cgroup2.cpu.max = 200000 100000設定取決於主機環境。UID/GID 範圍必須符合從屬 ID 配置,網路裝置必須存在,而且執行中的核心必須支援指定的 cgroup 值。LXC 會將許多 cgroup 設定傳遞給核心,而不是將其正規化為執行環境專屬的資源模型。
特權與非特權容器 #
UID 對應決定容器 root 是否也是主機 root:
- 在特權容器中,容器內的 UID 0 從 主機核心的角度來看也是 UID 0。命名空間、移除 capability、seccomp 及強制存取控制可以減少存取權,但上游 LXC 明確不將特權容器視為對 root 安全。
- 在非特權容器中,UID 0 會對應至非零的主機 UID,例如 100000. 因此,使用者命名空間可防止容器 root 擁有 一般主機資源。
例如,對應 u 0 100000 65536 會將容器 UID 0 至 65535 對應至主機 UID 100000 至 165535。newuidmap 和 newgidmap 會安裝由 /etc/subuid 和 /etc/subgid 授權的對應。非特權網路也可以使用權限範圍受嚴格限制的 lxc-user-nic 輔助程式,建立獲准的虛擬介面。
對於不需要主機層級身分或裝置存取的工作負載,應預設使用非特權容器。使用者命名空間無法消除共享核心的風險:可透過獲准系統呼叫觸及的核心漏洞,仍可能跨越容器邊界。
儲存 #
根檔案系統可以是目錄、映像檔、區塊裝置,或受支援的寫入時複製後端。依建置方式及主機設定而定,lxc-create 支援的後端儲存包括目錄、Btrfs、LVM、loop 檔案、ZFS 及 Ceph RBD。
後端選擇會改變運作行為:
| 後端 | 運作特性 |
|---|---|
| 目錄 | 設定最少且可直接存取檔案,但複製容器時必須複製其檔案。 |
| Btrfs 或 ZFS | 當主機檔案系統完成相應設定時,可使用原生快照及高效率複製。 |
| LVM 精簡集區 | 提供區塊裝置隔離、精簡配置及快照支援。 |
| Loop 檔案 | 不需要專用邏輯磁碟區的檔案系統映像,但會增加一層儲存層。 |
| Ceph RBD | 適用於已整合 Ceph 之主機的網路後端區塊儲存。 |
| OverlayFS | 在一或多個下層之上提供可寫入的上層;適合暫時性或複製的根檔案系統。 |
Idmapped mounts 可透過容器的 UID/GID 對應呈現檔案系統擁有權,而不必以遞迴方式變更每個 inode。採用前必須確認核心、檔案系統及 LXC 均提供支援。
網路 #
LXC 可以建立數種網路介面類型:
veth會建立一對 Ethernet 介面,並常將主機端連接至lxcbr0等橋接器;vlan會在主機的父介面上建立 VLAN 介面;macvlan和ipvlan會以不同的 第 2 層或第 3 層語意,將容器連接至父介面;phys會將實體介面移入容器的網路命名空間;empty會建立只有 loopback 的隔離網路命名空間;以及none會保留主機網路命名空間。
橋接器提供連線能力,而非租戶安全性。連接至相同第 2 層網段的容器可以嘗試偽造位址或傳送惡意控制流量。因此,不受信任的租戶需要橋接器隔離、主機端篩選,以及明確的 IPv6 路由器通告控制。
資源與裝置控制 #
LXC 7.0 僅支援 cgroups v2。管理者可以透過 lxc.cgroup2.* 寫入控制器值,例如:
- 使用
memory.max和memory.high控制記憶體限制及壓力; - 使用
cpu.max和cpuset.cpus控制 CPU 頻寬及配置; - 使用
pids.max限制 fork bomb;以及 - 針對受支援區塊裝置的 I/O 控制器設定。
程序在容器中執行,本身並不代表存在資源上限。若未設定明確限制,容器可能與其他工作負載競用主機可用的記憶體、CPU、程序 ID、I/O 及網路容量。
裝置存取也需要審慎處理。在 cgroups v2 上,裝置篩選透過附加至 cgroup 的 eBPF 程式強制執行,而非使用 cgroups v1 的裝置控制檔案。直通 GPU、磁碟或其他裝置會擴大攻擊面,因為容器程序將直接與主機驅動程式互動。
安全模型 #
LXC 隔離採用縱深防禦,而非依賴單一邊界。正式環境設定應:
- 使用 UID/GID 範圍不重疊的非特權容器。
- 套用記憶體、CPU、程序數量及 I/O 控制,因為 LXC 預設不會 施加完整限制。
- 移除工作負載不需要的 capability。
- 載入適當的 seccomp 政策,並在主機發行版支援時保留 AppArmor 或 SELinux 限制。
- 盡量減少 bind mount、裝置直通、共享命名空間及可寫入的 主機路徑。
- 隔離不受信任的網路區段,並篩選面向主機的流量。
- 持續更新主機核心與 LXC 套件,因為每個容器都共享 主機核心。
彼此不信任的容器之間應避免使用重疊的從屬 ID 對應,否則與相同主機 UID 關聯的核心計量與限制可能造成容器間相互干擾。
在 LXC 內巢狀執行另一個容器執行環境,需要額外權限、掛載行為、cgroup 委派或安全政策例外。在 LXC 容器內執行 Docker 可以分隔生命週期與設定狀態,但無法建立虛擬機器等級的安全邊界,因為兩層最終都使用相同的主機核心。
LXC、OCI 容器與虛擬機器 #
LXC、OCI 執行環境及虛擬機器分別解決不同的封裝與隔離問題:
| 屬性 | LXC 系統容器 | OCI 應用程式容器 | 虛擬機器 |
|---|---|---|---|
| 典型單位 | 具有 init 及多項服務的 Linux 使用者空間 | 應用程式程序及其相依項目 | 完整作業系統 |
| 核心 | 與主機共享 | 與主機共享 | 獨立的客體核心 |
| 映像模型 | 發行版 rootfs 或自訂系統映像 | 內容定址的分層 OCI 映像 | 虛擬磁碟及機器映像 |
| 狀態模型 | 常採持久化且可變動的模式 | 常採重新建置及取代的模式 | 常採持久化模式 |
| 管理方式 | 直接使用 lxc-* 工具,或使用 Incus 等管理器 | Docker、containerd、CRI-O、Kubernetes 及相關工具 | Hypervisor 及虛擬機器管理工具 |
| 作業系統限制 | 與主機核心相容的 Linux 使用者空間 | 與主機核心相容的 Linux 使用者空間 | 虛擬硬體支援的客體作業系統 |
| 隔離邊界 | 命名空間、使用者對應、cgroups 及安全政策 | 命名空間、使用者對應、cgroups 及安全政策 | 硬體虛擬化及 hypervisor |
當工作負載以 Linux 機器的形式運作時,應選擇 LXC:例如需要 init 系統、多個協同運作的常駐程式、就地套件管理,或作業系統層級的整合測試環境。
當部署單位是應用程式映像,且交付系統依賴映像登錄庫、分層建置、不可變取代或 Kubernetes 時,應選擇 OCI 執行環境。
當工作負載需要另一個核心、非 Linux 客體、核心模組控制,或需要為敵對租戶提供更強的隔離邊界時,應選擇虛擬機器。效能必須依實際工作負載測量,而不能僅根據類別推斷。
專案狀態 #
截至 2026 年 8 月,LXC 7.0 是目前的長期支援系列,預定支援至 2031 年 6 月。LXC 6.0 仍支援至 2029 年 6 月,LXC 5.0 則支援至 2027 年 6 月。
LXC 7.0 移除了 cgroups v1 支援,也不再支援缺少 pidfds 或新 mount API 的核心。因此,從舊版 LXC 升級的部署環境必須驗證主機核心功能,並遷移剩餘的 cgroups v1 設定。
版本號碼與支援日期描述的是上游版本。Linux 發行版可能採用不同的套件版本、向後移植內容及維護政策。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)