LXD 2.0 系列(五):鏡像管理
這是 LXD 2.0 系列介紹文章的第五篇。
因為 lxd 容器管理有很多命令,因此這篇文章會很長。 如果你想要快速地瀏覽這些相同的命令,你可以嘗試下我們的在線演示!
容器鏡像
如果你以前使用過 LXC,你可能還記得那些 LXC “模板”,基本上都是導出一個容器文件系統(tǒng)以及一點配置的 shell 腳本。
大多數(shù)模板是通過在本機上執(zhí)行一個完整的發(fā)行版自舉來生成該文件系統(tǒng)。這可能需要相當長的時間,并且無法在所有的發(fā)行版上可用,另外可能需要大量的網(wǎng)絡帶寬。
回到 LXC 1.0,我寫了一個“下載”模板,它允許用戶下載預先打包的容器鏡像,用模板腳本在中央服務器上生成,接著高度壓縮、簽名并通過 https 分發(fā)。我們很多用戶從舊版的容器生成方式切換到了使用這種新的、更快更可靠的創(chuàng)建容器的方式。
使用 LXD,我們通過全面的基于鏡像的工作流程向前邁進了一步。所有容器都是從鏡像創(chuàng)建的,我們在 LXD 中具有高級鏡像緩存和預加載支持,以使鏡像存儲保持最新。
與 LXD 鏡像交互
在更深入了解鏡像格式之前,讓我們快速了解下 LXD 可以讓你做些什么。
透明地導入鏡像
所有的容器都是由鏡像創(chuàng)建的。鏡像可以來自一臺遠程服務器并使用它的完整 hash、短 hash 或者別名拉取下來,但是最終每個 LXD 容器都是創(chuàng)建自一個本地鏡像。
這有個例子:
- lxc launch ubuntu:14.04 c1
- lxc launch ubuntu:75182b1241be475a64e68a518ce853e800e9b50397d2f152816c24f038c94d6e c2
- lxc launch ubuntu:75182b1241be c3
所有這些引用相同的遠程鏡像(在寫這篇文章時),在第一次運行這些命令其中之一時,遠程鏡像將作為緩存鏡像導入本地 LXD 鏡像存儲,接著從其創(chuàng)建容器。
下一次運行其中一個命令時,LXD 將只檢查鏡像是否仍然是最新的(當不是由指紋引用時),如果是,它將創(chuàng)建容器而不下載任何東西。
現(xiàn)在鏡像被緩存在本地鏡像存儲中,你也可以從那里啟動它,甚至不檢查它是否是最新的:
- lxc launch 75182b1241be c4
最后,如果你有個名為“myimage”的本地鏡像,你可以:
- lxc launch my-image c5
如果你想要改變一些自動緩存或者過期行為,在本系列之前的文章中有一些命令。
手動導入鏡像
從鏡像服務器中復制
如果你想復制遠程的某個鏡像到你本地鏡像存儲,但不立即從它創(chuàng)建一個容器,你可以使用lxc image copy命令。它可以讓你調(diào)整一些鏡像標志,比如:
- lxc image copy ubuntu:14.04 local:
這只是簡單地復制一個遠程鏡像到本地存儲。
如果您想要通過比記住其指紋更容易的方式來記住你引用的鏡像副本,則可以在復制時添加別名:
- lxc image copy ubuntu:12.04 local: --alias old-ubuntu
- lxc launch old-ubuntu c6
如果你想要使用源服務器上設置的別名,你可以要求 LXD 復制下來:
- lxc image copy ubuntu:15.10 local: --copy-aliases
- lxc launch 15.10 c7
上面的副本都是一次性拷貝,也就是復制遠程鏡像的當前版本到本地鏡像存儲中。如果你想要 LXD 保持鏡像最新,就像它在緩存中存儲的那樣,你需要使用 –auto-update 標志:
- lxc image copy images:gentoo/current/amd64 local: --alias gentoo --auto-update
導入 tarball
如果某人給你提供了一個單獨的 tarball,你可以用下面的命令導入:
- lxc image import <tarball>
如果你想在導入時設置一個別名,你可以這么做:
- lxc image import <tarball> --alias random-image
現(xiàn)在如果你被給了兩個 tarball,要識別哪個是含有 LXD 元數(shù)據(jù)的。通??梢酝ㄟ^ tarball 的名稱來識別,如果不行就選擇最小的那個,元數(shù)據(jù) tarball 包是很小的。 然后將它們一起導入:
- lxc image import <metadata tarball> <rootfs tarball>
從 URL 中導入
lxc image import 也可以與指定的 URL 一起使用。如果你的一臺 https Web 服務器的某個路徑中有 LXD-Image-URL 和 LXD-Image-Hash 的標頭設置,那么 LXD 就會把這個鏡像拉到鏡像存儲中。
可以參照例子這么做:
- lxc image import https://dl.stgraber.org/lxd --alias busybox-amd64
當拉取鏡像時,LXD 還會設置一些標頭,遠程服務器可以檢查它們以返回適當?shù)溺R像。 它們是 LXD-Server-Architectures 和 LXD-Server-Version。
這相當于一個簡陋的鏡像服務器。 它可以通過任何靜態(tài) Web 服務器提供一中用戶友好的導入鏡像的方式。
管理本地鏡像存儲
現(xiàn)在我們本地已經(jīng)有一些鏡像了,讓我們瞧瞧可以做些什么。我們已經(jīng)介紹了最主要的部分,可以從它們來創(chuàng)建容器,但是你還可以在本地鏡像存儲上做更多。
列出鏡像
要列出所有的鏡像,運行 lxc image list:
- stgraber@dakara:~$ lxc image list
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | alpine-32 | 6d9c131efab3 | yes | Alpine edge (i386) (20160329_23:52) | i686 | 2.50MB | Mar 30, 2016 at 4:36am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | busybox-amd64 | 74186c79ca2f | no | Busybox x86_64 | x86_64 | 0.79MB | Mar 30, 2016 at 4:33am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | gentoo | 1a134c5951e0 | no | Gentoo current (amd64) (20160329_14:12) | x86_64 | 232.50MB | Mar 30, 2016 at 4:34am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | my-image | c9b6e738fae7 | no | Scientific Linux 6 x86_64 (default) (20160215_02:36) | x86_64 | 625.34MB | Mar 2, 2016 at 4:56am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | old-ubuntu | 4d558b08f22f | no | ubuntu 12.04 LTS amd64 (release) (20160315) | x86_64 | 155.09MB | Mar 30, 2016 at 4:30am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | w (11 more) | d3703a994910 | no | ubuntu 15.10 amd64 (release) (20160315) | x86_64 | 153.35MB | Mar 30, 2016 at 4:31am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
- | | 75182b1241be | no | ubuntu 14.04 LTS amd64 (release) (20160314) | x86_64 | 118.17MB | Mar 30, 2016 at 4:27am (UTC) |
- +---------------+--------------+--------+------------------------------------------------------+--------+----------+------------------------------+
你可以通過別名或者指紋來過濾:
- stgraber@dakara:~$ lxc image list amd64
- +---------------+--------------+--------+-----------------------------------------+--------+----------+------------------------------+
- | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
- +---------------+--------------+--------+-----------------------------------------+--------+----------+------------------------------+
- | busybox-amd64 | 74186c79ca2f | no | Busybox x86_64 | x86_64 | 0.79MB | Mar 30, 2016 at 4:33am (UTC) |
- +---------------+--------------+--------+-----------------------------------------+--------+----------+------------------------------+
- | w (11 more) | d3703a994910 | no | ubuntu 15.10 amd64 (release) (20160315) | x86_64 | 153.35MB | Mar 30, 2016 at 4:31am (UTC) |
- +---------------+--------------+--------+-----------------------------------------+--------+----------+------------------------------+
或者指定一個鏡像屬性中的鍵值對來過濾:
- stgraber@dakara:~$ lxc image list os=ubuntu
- +-------------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
- | ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
- +-------------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
- | old-ubuntu | 4d558b08f22f | no | ubuntu 12.04 LTS amd64 (release) (20160315) | x86_64 | 155.09MB | Mar 30, 2016 at 4:30am (UTC) |
- +-------------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
- | w (11 more) | d3703a994910 | no | ubuntu 15.10 amd64 (release) (20160315) | x86_64 | 153.35MB | Mar 30, 2016 at 4:31am (UTC) |
- +-------------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
- | | 75182b1241be | no | ubuntu 14.04 LTS amd64 (release) (20160314) | x86_64 | 118.17MB | Mar 30, 2016 at 4:27am (UTC) |
- +-------------+--------------+--------+---------------------------------------------+--------+----------+------------------------------+
要了解鏡像的所有信息,你可以使用lxc image info:
- stgraber@castiana:~$ lxc image info ubuntu
- Fingerprint: e8a33ec326ae7dd02331bd72f5d22181ba25401480b8e733c247da5950a7d084
- Size: 139.43MB
- Architecture: i686
- Public: no
- Timestamps:
- Created: 2016/03/15 00:00 UTC
- Uploaded: 2016/03/16 05:50 UTC
- Expires: 2017/04/26 00:00 UTC
- Properties:
- version: 12.04
- aliases: 12.04,p,precise
- architecture: i386
- description: ubuntu 12.04 LTS i386 (release) (20160315)
- label: release
- os: ubuntu
- release: precise
- serial: 20160315
- Aliases:
- - ubuntu
- Auto update: enabled
- Source:
- Server: https://cloud-images.ubuntu.com/releases
- Protocol: simplestreams
- Alias: precise/i386
編輯鏡像
編輯鏡像的屬性和標志的簡單方法是使用:
- lxc image edit <alias or fingerprint>
這會打開默認文本編輯器,內(nèi)容像這樣:
- autoupdate: true
- properties:
- aliases: 14.04,default,lts,t,trusty
- architecture: amd64
- description: ubuntu 14.04 LTS amd64 (release) (20160314)
- label: release
- os: ubuntu
- release: trusty
- serial: "20160314"
- version: "14.04"
- public: false
你可以修改任何屬性,打開或者關(guān)閉自動更新,或者標記一個鏡像是公共的(后面詳述)。
刪除鏡像
刪除鏡像只需要運行:
- lxc image delete <alias or fingerprint>
注意你不必移除緩存對象,它們會在過期后被 LXD 自動移除(默認上,在最后一次使用的 10 天后)。
導出鏡像
如果你想得到目前鏡像的 tarball,你可以使用lxc image export,像這樣:
- stgraber@dakara:~$ lxc image export old-ubuntu .
- Output is in .
- stgraber@dakara:~$ ls -lh *.tar.xz
- -rw------- 1 stgraber domain admins 656 Mar 30 00:55 meta-ubuntu-12.04-server-cloudimg-amd64-lxd.tar.xz
- -rw------- 1 stgraber domain admins 156M Mar 30 00:55 ubuntu-12.04-server-cloudimg-amd64-lxd.tar.xz
鏡像格式
LXD 現(xiàn)在支持兩種鏡像布局,unified 或者 split。這兩者都是有效的 LXD 格式,雖然后者在與其他容器或虛擬機一起運行時更容易重用其文件系統(tǒng)。
LXD 專注于系統(tǒng)容器,不支持任何應用程序容器的“標準”鏡像格式,我們也不打算這么做。
我們的鏡像很簡單,它們是由容器文件系統(tǒng),以及包含了鏡像制作時間、到期時間、什么架構(gòu),以及可選的一堆文件模板的元數(shù)據(jù)文件組成。
有關(guān)鏡像格式的最新詳細信息,請參閱此文檔。
unified 鏡像(一個 tarball)
unified 鏡像格式是 LXD 在生成鏡像時使用的格式。它們是一個單獨的大型 tarball,包含 rootfs 目錄下的容器文件系統(tǒng),在 tarball 根目錄下有 metadata.yaml 文件,任何模板都放到 templates 目錄。
tarball 可以用任何方式壓縮(或者不壓縮)。鏡像散列是壓縮后的 tarball 的 sha256 。
Split 鏡像(兩個 tarball)
這種格式最常用于滾動更新鏡像并已經(jīng)有了一個壓縮文件系統(tǒng) tarball 時。
它們由兩個不同的 tarball 組成,第一個只包含 LXD 使用的元數(shù)據(jù), metadata.yaml 文件在根目錄,任何模板都在 templates 目錄。
第二個 tarball 只包含直接位于其根目錄下的容器文件系統(tǒng)。大多數(shù)發(fā)行版已經(jīng)有這樣的 tarball,因為它們常用于引導新機器。 此鏡像格式允許不經(jīng)修改就重用。
兩個 tarball 都可以壓縮(或者不壓縮),它們可以使用不同的壓縮算法。 鏡像散列是元數(shù)據(jù)的 tarball 和 rootfs 的 tarball 結(jié)合的 sha256。
鏡像元數(shù)據(jù)
典型的 metadata.yaml 文件看起來像這樣:
- architecture: "i686"
- creation_date: 1458040200
- properties:
- architecture: "i686"
- description: "Ubuntu 12.04 LTS server (20160315)"
- os: "ubuntu"
- release: "precise"
- templates:
- /var/lib/cloud/seed/nocloud-net/meta-data:
- when:
- - start
- template: cloud-init-meta.tpl
- /var/lib/cloud/seed/nocloud-net/user-data:
- when:
- - start
- template: cloud-init-user.tpl
- properties:
- default: |
- #cloud-config
- {}
- /var/lib/cloud/seed/nocloud-net/vendor-data:
- when:
- - start
- template: cloud-init-vendor.tpl
- properties:
- default: |
- #cloud-config
- {}
- /etc/init/console.override:
- when:
- - create
- template: upstart-override.tpl
- /etc/init/tty1.override:
- when:
- - create
- template: upstart-override.tpl
- /etc/init/tty2.override:
- when:
- - create
- template: upstart-override.tpl
- /etc/init/tty3.override:
- when:
- - create
- template: upstart-override.tpl
- /etc/init/tty4.override:
- when:
- - create
- template: upstart-override.tpl
屬性
兩個唯一的必填字段是 creation date(UNIX 紀元時間)和 architecture。 其他都可以保持未設置,鏡像就可以正常地導入。
額外的屬性主要是幫助用戶弄清楚鏡像是什么。 例如 description 屬性是在 lxc image list 中可見的。 用戶可以使用其它屬性的鍵/值對來搜索特定鏡像。
相反,這些屬性用戶可以通過 lxc image edit來編輯,creation date 和 architecture 字段是不可變的。
模板
模板機制允許在容器生命周期中的某一點生成或重新生成容器中的一些文件。
我們使用 pongo2 模板引擎來做這些,我們將所有我們知道的容器信息都導出到模板。 這樣,你可以使用用戶定義的容器屬性或常規(guī) LXD 屬性來自定義鏡像,從而更改某些特定文件的內(nèi)容。
正如你在上面的例子中看到的,我們使用在 Ubuntu 中使用它們來進行 cloud-init 并關(guān)閉一些 init 腳本。
創(chuàng)建你的鏡像
LXD 專注于運行完整的 Linux 系統(tǒng),這意味著我們期望大多數(shù)用戶只使用干凈的發(fā)行版鏡像,而不是只用自己的鏡像。
但是有一些情況下,你有自己的鏡像是有必要的。 例如生產(chǎn)服務器上的預配置鏡像,或者構(gòu)建那些我們沒有構(gòu)建的發(fā)行版或者架構(gòu)的鏡像。
將容器變成鏡像
目前使用 LXD 構(gòu)造鏡像最簡單的方法是將容器變成鏡像。
可以這么做:
- lxc launch ubuntu:14.04 my-container
- lxc exec my-container bash
- <do whatever change you want>
- lxc publish my-container --alias my-new-image
你甚至可以將一個容器過去的快照變成鏡像:
- lxc publish my-container/some-snapshot --alias some-image
手動構(gòu)建鏡像
構(gòu)建你自己的鏡像也很簡單。
- 生成容器文件系統(tǒng)。這完全取決于你使用的發(fā)行版。對于 Ubuntu 和 Debian,它將用于啟動。
- 配置容器中該發(fā)行版正常工作所需的任何東西(如果需要任何東西)。
- 制作該容器文件系統(tǒng)的 tarball,可選擇壓縮它。
- 根據(jù)上面描述的內(nèi)容寫一個新的 metadata.yaml 文件。
- 創(chuàng)建另一個包含 metadata.yaml 文件的 tarball。
- 用下面的命令導入這兩個 tarball 作為 LXD 鏡像:lxc image import <metadata tarball> <rootfs tarball> --alias some-name
在一切都正常工作前你可能需要經(jīng)歷幾次這樣的工作,調(diào)整這里或那里,可能會添加一些模板和屬性。
發(fā)布你的鏡像
所有 LXD 守護程序都充當鏡像服務器。除非另有說明,否則加載到鏡像存儲中的所有鏡像都會被標記為私有,因此只有受信任的客戶端可以檢索這些鏡像,但是如果要創(chuàng)建公共鏡像服務器,你需要做的是將一些鏡像標記為公開,并確保你的 LXD 守護進程監(jiān)聽網(wǎng)絡。
只運行 LXD 公共服務器
最簡單的共享鏡像的方式是運行一個公共的 LXD 守護進程。
你只要運行:
- lxc config set core.https_address "[::]:8443"
遠程用戶就可以添加你的服務器作為公共服務器:
- lxc remote add <some name> <IP or DNS> --public
他們就可以像使用任何默認的鏡像服務器一樣使用它們。 由于遠程服務器添加了 -public 選項,因此不需要身份驗證,并且客戶端僅限于使用已標記為 public 的鏡像。
要將鏡像設置成公共的,只需使用 lxc image edit 編輯它們,并將 public 標志設置為 true。
使用一臺靜態(tài) web 服務器
如上所述,lxc image import 支持從靜態(tài) https 服務器下載。 基本要求是:
- 服務器必須支持具有有效證書的 HTTPS、TLS 1.2 和 EC 算法。
- 當訪問 lxc image import 提供的 URL 時,服務器必須返回一個包含 LXD-Image-Hash 和 LXD-Image-URL 的 HTTP 標頭。
如果你想使它動態(tài)化,你可以讓你的服務器查找 LXD 在請求鏡像時發(fā)送的 LXD-Server-Architectures 和 LXD-Server-Version 的 HTTP 標頭,這可以讓你返回符合該服務器架構(gòu)的正確鏡像。
構(gòu)建一個簡單流服務器
ubuntu: 和 ubuntu-daily: 遠端服務器不使用 LXD 協(xié)議(images: 使用),而是使用稱為簡單流(simplestreams)的不同協(xié)議。
簡單流基本上是一個鏡像服務器的描述格式,使用 JSON 來描述產(chǎn)品以及相關(guān)產(chǎn)品的文件列表。
它被各種工具,如 OpenStack、Juju、MAAS 等用來查找、下載或者做鏡像系統(tǒng),LXD 將它作為用于鏡像檢索的原生協(xié)議。
雖然這的確不是提供 LXD 鏡像的最簡單的方法,但是如果你的鏡像也被其它一些工具使用,那這也許值得考慮一下。
關(guān)于簡單流的更多信息可以在這里找到。
總結(jié)
我希望這篇關(guān)于如何使用 LXD 管理鏡像以及構(gòu)建和發(fā)布鏡像文章讓你有所了解。對于以前的 LXC 而言,可以在一組全球分布式系統(tǒng)上得到完全相同的鏡像是一個很大的進步,并且引導了更多可復制性的發(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
如果你不想或者不能在你的機器上安裝 LXD ,你可以在 web 上試試在線版的 LXD 。