LXD 2.0 系列(一):LXD 入門
這是 LXD 2.0 系列介紹文章的第一篇。
關(guān)于 LXD 幾個(gè)常見問題
什么是 LXD ?
簡單地說, LXD 就是一個(gè)提供了 REST API 的 LXC 容器管理器。
LXD 最主要的目標(biāo)就是使用 Linux 容器而不是硬件虛擬化向用戶提供一種接近虛擬機(jī)的使用體驗(yàn)。
LXD 和 Docker/Rkt 又有什么關(guān)系呢 ?
這是一個(gè)最常被問起的問題,現(xiàn)在就讓我們直接指出其中的不同吧。
LXD 聚焦于系統(tǒng)容器,通常也被稱為架構(gòu)容器。這就是說 LXD 容器實(shí)際上如在裸機(jī)或虛擬機(jī)上運(yùn)行一般運(yùn)行了一個(gè)完整的 Linux 操作系統(tǒng)。
這些容器一般基于一個(gè)干凈的發(fā)布鏡像并會(huì)長時(shí)間運(yùn)行。傳統(tǒng)的配置管理工具和部署工具可以如在虛擬機(jī)、云實(shí)例和物理機(jī)器上一樣與 LXD 一起使用。
相對的, Docker 關(guān)注于短期的、無狀態(tài)的、最小化的容器,這些容器通常并不會(huì)升級或者重新配置,而是作為一個(gè)整體被替換掉。這就使得 Docker 及類似項(xiàng)目更像是一種軟件發(fā)布機(jī)制,而不是一個(gè)機(jī)器管理工具。
這兩種模型并不是完全互斥的。你完全可以使用 LXD 為你的用戶提供一個(gè)完整的 Linux 系統(tǒng),然后他們可以在 LXD 內(nèi)安裝 Docker 來運(yùn)行他們想要的軟件。
為什么要用 LXD?
我們已經(jīng)持續(xù)開發(fā)并改進(jìn) LXC 好幾年了。 LXC 成功的實(shí)現(xiàn)了它的目標(biāo),它提供了一系列很棒的用于創(chuàng)建和管理容器的底層工具和庫。
然而這些底層工具的使用界面對用戶并不是很友好。使用它們需要用戶有很多的基礎(chǔ)知識以理解它們的工作方式和目的。同時(shí),向后兼容舊的容器和部署策略也使得 LXC 無法默認(rèn)使用一些安全特性,這導(dǎo)致用戶需要進(jìn)行更多人工操作來實(shí)現(xiàn)本可以自動(dòng)完成的工作。
我們把 LXD 作為解決這些缺陷的一個(gè)很好的機(jī)會(huì)。作為一個(gè)長時(shí)間運(yùn)行的守護(hù)進(jìn)程, LXD 可以繞開 LXC 的許多限制,比如動(dòng)態(tài)資源限制、無法進(jìn)行容器遷移和高效的在線遷移;同時(shí),它也為創(chuàng)造新的默認(rèn)體驗(yàn)提供了機(jī)會(huì):默認(rèn)開啟安全特性,對用戶更加友好。
LXD 的主要組件
LXD 是由幾個(gè)主要組件構(gòu)成的,這些組件都出現(xiàn)在 LXD 目錄結(jié)構(gòu)、命令行客戶端和 API 結(jié)構(gòu)體里。
容器
LXD 中的容器包括以下及部分:
根文件系統(tǒng)(rootfs)
配置選項(xiàng)列表,包括資源限制、環(huán)境、安全選項(xiàng)等等
設(shè)備:包括磁盤、unix 字符/塊設(shè)備、網(wǎng)絡(luò)接口
一組繼承而來的容器配置文件
屬性(容器架構(gòu)、暫時(shí)的還是持久的、容器名)
運(yùn)行時(shí)狀態(tài)(當(dāng)用 CRIU 來中斷/恢復(fù)時(shí))
快照
容器快照和容器是一回事,只不過快照是不可修改的,只能被重命名,銷毀或者用來恢復(fù)系統(tǒng),但是無論如何都不能被修改。
值得注意的是,因?yàn)槲覀冊试S用戶保存容器的運(yùn)行時(shí)狀態(tài),這就有效的為我們提供了“有狀態(tài)”的快照的功能。這就是說我們可以使用快照回滾容器的狀態(tài),包括快照當(dāng)時(shí)的 CPU 和內(nèi)存狀態(tài)。
鏡像
LXD 是基于鏡像實(shí)現(xiàn)的,所有的 LXD 容器都是來自于鏡像。容器鏡像通常是一些純凈的 Linux 發(fā)行版的鏡像,類似于你們在虛擬機(jī)和云實(shí)例上使用的鏡像。
所以可以「發(fā)布」一個(gè)容器:使用容器制作一個(gè)鏡像并在本地或者遠(yuǎn)程 LXD 主機(jī)上使用。
鏡像通常使用全部或部分 sha256 哈希碼來區(qū)分。因?yàn)檩斎腴L長的哈希碼對用戶來說不方便,所以鏡像可以使用幾個(gè)自身的屬性來區(qū)分,這就使得用戶在鏡像商店里方便搜索鏡像。也可以使用別名來一對一地將一個(gè)用戶好記的名字映射到某個(gè)鏡像的哈希碼上。
LXD 安裝時(shí)已經(jīng)配置好了三個(gè)遠(yuǎn)程鏡像服務(wù)器(參見下面的遠(yuǎn)程一節(jié)):
“ubuntu”:提供穩(wěn)定版的 Ubuntu 鏡像
“ubuntu-daily”:提供 Ubuntu 的每日構(gòu)建鏡像
“images”: 社區(qū)維護(hù)的鏡像服務(wù)器,提供一系列的其它 Linux 發(fā)布版,使用的是上游 LXC 的模板
LXD 守護(hù)進(jìn)程會(huì)從鏡像上次被使用開始自動(dòng)緩存遠(yuǎn)程鏡像一段時(shí)間(默認(rèn)是 10 天),超過時(shí)限后這些鏡像才會(huì)失效。
此外, LXD 還會(huì)自動(dòng)更新遠(yuǎn)程鏡像(除非指明不更新),所以本地的鏡像會(huì)一直是最新版的。
配置
配置文件是一種在一個(gè)地方定義容器配置和容器設(shè)備,然后將其應(yīng)用到一系列容器的方法。
一個(gè)容器可以被應(yīng)用多個(gè)配置文件。當(dāng)構(gòu)建最終容器配置時(shí)(即通常的擴(kuò)展配置),這些配置文件都會(huì)按照他們定義順序被應(yīng)用到容器上,當(dāng)有重名的配置鍵或設(shè)備時(shí),新的會(huì)覆蓋掉舊的。然后本地容器設(shè)置會(huì)在這些基礎(chǔ)上應(yīng)用,覆蓋所有來自配置文件的選項(xiàng)。
LXD 自帶兩種預(yù)配置的配置文件:
“default”配置是自動(dòng)應(yīng)用在所有容器之上,除非用戶提供了一系列替代的配置文件。目前這個(gè)配置文件只做一件事,為容器定義 eth0 網(wǎng)絡(luò)設(shè)備。
“docker”配置是一個(gè)允許你在容器里運(yùn)行 Docker 容器的配置文件。它會(huì)要求 LXD 加載一些需要的內(nèi)核模塊以支持容器嵌套并創(chuàng)建一些設(shè)備。
遠(yuǎn)程
如我之前提到的, LXD 是一個(gè)基于網(wǎng)絡(luò)的守護(hù)進(jìn)程。附帶的命令行客戶端可以與多個(gè)遠(yuǎn)程 LXD 服務(wù)器、鏡像服務(wù)器通信。
默認(rèn)情況下,我們的命令行客戶端會(huì)與下面幾個(gè)預(yù)定義的遠(yuǎn)程服務(wù)器通信:
local:默認(rèn)的遠(yuǎn)程服務(wù)器,使用 UNIX socket 和本地的 LXD 守護(hù)進(jìn)程通信
ubuntu:Ubuntu 鏡像服務(wù)器,提供穩(wěn)定版的 Ubuntu 鏡像
ubuntu-daily:Ubuntu 鏡像服務(wù)器,提供 Ubuntu 的每日構(gòu)建版
images:images.linuxcontainers.org 的鏡像服務(wù)器
所有這些遠(yuǎn)程服務(wù)器的組合都可以在命令行客戶端里使用。
你也可以添加任意數(shù)量的遠(yuǎn)程 LXD 主機(jī),并配置它們監(jiān)聽網(wǎng)絡(luò)。匿名的開放鏡像服務(wù)器,或者通過認(rèn)證可以管理遠(yuǎn)程容器的鏡像服務(wù)器,都可以添加進(jìn)來。
正是這種遠(yuǎn)程機(jī)制使得與遠(yuǎn)程鏡像服務(wù)器交互及在主機(jī)間復(fù)制、移動(dòng)容器成為可能。
安全性
我們設(shè)計(jì) LXD 時(shí)的一個(gè)核心要求,就是在不修改現(xiàn)代 Linux 發(fā)行版的前提下,使容器盡可能的安全。
LXD 通過使用 LXC 庫實(shí)現(xiàn)的主要安全特性有:
內(nèi)核名字空間。尤其是用戶名字空間,它讓容器和系統(tǒng)剩余部分完全分離。LXD 默認(rèn)使用用戶名字空間(和 LXC 相反),并允許用戶在需要的時(shí)候以容器為單位關(guān)閉(將容器標(biāo)為“特權(quán)的”)。
Seccomp 系統(tǒng)調(diào)用。用來隔離潛在危險(xiǎn)的系統(tǒng)調(diào)用。
AppArmor。對 mount、socket、ptrace 和文件訪問提供額外的限制。特別是限制跨容器通信。
Capabilities。阻止容器加載內(nèi)核模塊,修改主機(jī)系統(tǒng)時(shí)間,等等。
CGroups。限制資源使用,防止針對主機(jī)的 DoS 攻擊。
為了對用戶友好,LXD 構(gòu)建了一個(gè)新的配置語言把大部分的這些特性都抽象封裝起來,而不是如 LXC 一般直接將這些特性暴露出來。舉了例子,一個(gè)用戶可以告訴 LXD 把主機(jī)設(shè)備放進(jìn)容器而不需要手動(dòng)檢查他們的主/次設(shè)備號來手動(dòng)更新 CGroup 策略。
和 LXD 本身通信是基于使用 TLS 1.2 保護(hù)的鏈路,只允許使用有限的幾個(gè)被允許的密鑰算法。當(dāng)和那些經(jīng)過系統(tǒng)證書認(rèn)證之外的主機(jī)通信時(shí), LXD 會(huì)提示用戶驗(yàn)證主機(jī)的遠(yuǎn)程指紋(SSH 方式),然后把指紋緩存起來以供以后使用。
REST 接口
LXD 的工作都是通過 REST 接口實(shí)現(xiàn)的。在客戶端和守護(hù)進(jìn)程之間并沒有其他的通訊渠道。
REST 接口可以通過本地的 unix socket 訪問,這只需要經(jīng)過用戶組認(rèn)證,或者經(jīng)過 HTTP 套接字使用客戶端認(rèn)證進(jìn)行通信。
REST 接口的結(jié)構(gòu)能夠和上文所說的不同的組件匹配,是一種簡單、直觀的使用方法。
當(dāng)需要一種復(fù)雜的通信機(jī)制時(shí), LXD 將會(huì)進(jìn)行 websocket 協(xié)商完成剩余的通信工作。這主要用于交互式終端會(huì)話、容器遷移和事件通知。
LXD 2.0 附帶了 1.0 版的穩(wěn)定 API。雖然我們在 1.0 版 API 添加了額外的特性,但是這不會(huì)在 1.0 版 API 端點(diǎn)里破壞向后兼容性,因?yàn)槲覀儠?huì)聲明額外的 API 擴(kuò)展使得客戶端可以找到新的接口。
容器規(guī)?;?/strong>
雖然 LXD 提供了一個(gè)很好的命令行客戶端,但是這個(gè)客戶端并不能管理多個(gè)主機(jī)上大量的容器。在這種使用情況下,我們可以使用 OpenStack 的 nova-lxd 插件,它可以使 OpenStack 像使用虛擬機(jī)一樣使用 LXD 容器。
這就允許在大量的主機(jī)上部署大量的 LXD 容器,然后使用 OpenStack 的 API 來管理網(wǎng)絡(luò)、存儲(chǔ)以及負(fù)載均衡。
額外信息
LXD 的主站在: https://linuxcontainers.org/lxd
LXD 的 GitHub 倉庫: https://github.com/lxc/lxd
LXD 的郵件列表: https://lists.linuxcontainers.org
LXD 的 IRC 頻道: #lxcontainers on irc.freenode.net
如果你不想或者不能在你的機(jī)器上安裝 LXD ,你可以在 web 上試試在線版的 LXD 。