LXD 2.0 系列(五):鏡像管理
這是 LXD 2.0 系列介紹文章的第五篇。
因?yàn)?lxd 容器管理有很多命令,因此這篇文章會(huì)很長。 如果你想要快速地瀏覽這些相同的命令,你可以嘗試下我們的在線演示!
容器鏡像
如果你以前使用過 LXC,你可能還記得那些 LXC “模板”,基本上都是導(dǎo)出一個(gè)容器文件系統(tǒng)以及一點(diǎn)配置的 shell 腳本。
大多數(shù)模板是通過在本機(jī)上執(zhí)行一個(gè)完整的發(fā)行版自舉來生成該文件系統(tǒng)。這可能需要相當(dāng)長的時(shí)間,并且無法在所有的發(fā)行版上可用,另外可能需要大量的網(wǎng)絡(luò)帶寬。
回到 LXC 1.0,我寫了一個(gè)“下載”模板,它允許用戶下載預(yù)先打包的容器鏡像,用模板腳本在中央服務(wù)器上生成,接著高度壓縮、簽名并通過 https 分發(fā)。我們很多用戶從舊版的容器生成方式切換到了使用這種新的、更快更可靠的創(chuàng)建容器的方式。
使用 LXD,我們通過全面的基于鏡像的工作流程向前邁進(jìn)了一步。所有容器都是從鏡像創(chuàng)建的,我們?cè)?LXD 中具有高級(jí)鏡像緩存和預(yù)加載支持,以使鏡像存儲(chǔ)保持最新。
與 LXD 鏡像交互
在更深入了解鏡像格式之前,讓我們快速了解下 LXD 可以讓你做些什么。
透明地導(dǎo)入鏡像
所有的容器都是由鏡像創(chuàng)建的。鏡像可以來自一臺(tái)遠(yuǎn)程服務(wù)器并使用它的完整 hash、短 hash 或者別名拉取下來,但是最終每個(gè) LXD 容器都是創(chuàng)建自一個(gè)本地鏡像。
這有個(gè)例子:
- lxc launch ubuntu:14.04 c1
- lxc launch ubuntu:75182b1241be475a64e68a518ce853e800e9b50397d2f152816c24f038c94d6e c2
- lxc launch ubuntu:75182b1241be c3
所有這些引用相同的遠(yuǎn)程鏡像(在寫這篇文章時(shí)),在第一次運(yùn)行這些命令其中之一時(shí),遠(yuǎn)程鏡像將作為緩存鏡像導(dǎo)入本地 LXD 鏡像存儲(chǔ),接著從其創(chuàng)建容器。
下一次運(yùn)行其中一個(gè)命令時(shí),LXD 將只檢查鏡像是否仍然是最新的(當(dāng)不是由指紋引用時(shí)),如果是,它將創(chuàng)建容器而不下載任何東西。
現(xiàn)在鏡像被緩存在本地鏡像存儲(chǔ)中,你也可以從那里啟動(dòng)它,甚至不檢查它是否是最新的:
- lxc launch 75182b1241be c4
最后,如果你有個(gè)名為“myimage”的本地鏡像,你可以:
- lxc launch my-image c5
如果你想要改變一些自動(dòng)緩存或者過期行為,在本系列之前的文章中有一些命令。
手動(dòng)導(dǎo)入鏡像
從鏡像服務(wù)器中復(fù)制
如果你想復(fù)制遠(yuǎn)程的某個(gè)鏡像到你本地鏡像存儲(chǔ),但不立即從它創(chuàng)建一個(gè)容器,你可以使用lxc image copy命令。它可以讓你調(diào)整一些鏡像標(biāo)志,比如:
- lxc image copy ubuntu:14.04 local:
這只是簡(jiǎn)單地復(fù)制一個(gè)遠(yuǎn)程鏡像到本地存儲(chǔ)。
如果您想要通過比記住其指紋更容易的方式來記住你引用的鏡像副本,則可以在復(fù)制時(shí)添加別名:
- lxc image copy ubuntu:12.04 local: --alias old-ubuntu
- lxc launch old-ubuntu c6
如果你想要使用源服務(wù)器上設(shè)置的別名,你可以要求 LXD 復(fù)制下來:
- lxc image copy ubuntu:15.10 local: --copy-aliases
- lxc launch 15.10 c7
上面的副本都是一次性拷貝,也就是復(fù)制遠(yuǎn)程鏡像的當(dāng)前版本到本地鏡像存儲(chǔ)中。如果你想要 LXD 保持鏡像最新,就像它在緩存中存儲(chǔ)的那樣,你需要使用 –auto-update 標(biāo)志:
- lxc image copy images:gentoo/current/amd64 local: --alias gentoo --auto-update
導(dǎo)入 tarball
如果某人給你提供了一個(gè)單獨(dú)的 tarball,你可以用下面的命令導(dǎo)入:
- lxc image import <tarball>
如果你想在導(dǎo)入時(shí)設(shè)置一個(gè)別名,你可以這么做:
- lxc image import <tarball> --alias random-image
現(xiàn)在如果你被給了兩個(gè) tarball,要識(shí)別哪個(gè)是含有 LXD 元數(shù)據(jù)的。通常可以通過 tarball 的名稱來識(shí)別,如果不行就選擇最小的那個(gè),元數(shù)據(jù) tarball 包是很小的。 然后將它們一起導(dǎo)入:
- lxc image import <metadata tarball> <rootfs tarball>
從 URL 中導(dǎo)入
lxc image import 也可以與指定的 URL 一起使用。如果你的一臺(tái) https Web 服務(wù)器的某個(gè)路徑中有 LXD-Image-URL 和 LXD-Image-Hash 的標(biāo)頭設(shè)置,那么 LXD 就會(huì)把這個(gè)鏡像拉到鏡像存儲(chǔ)中。
可以參照例子這么做:
- lxc image import https://dl.stgraber.org/lxd --alias busybox-amd64
當(dāng)拉取鏡像時(shí),LXD 還會(huì)設(shè)置一些標(biāo)頭,遠(yuǎn)程服務(wù)器可以檢查它們以返回適當(dāng)?shù)溺R像。 它們是 LXD-Server-Architectures 和 LXD-Server-Version。
這相當(dāng)于一個(gè)簡(jiǎn)陋的鏡像服務(wù)器。 它可以通過任何靜態(tài) Web 服務(wù)器提供一中用戶友好的導(dǎo)入鏡像的方式。
管理本地鏡像存儲(chǔ)
現(xiàn)在我們本地已經(jīng)有一些鏡像了,讓我們瞧瞧可以做些什么。我們已經(jīng)介紹了最主要的部分,可以從它們來創(chuàng)建容器,但是你還可以在本地鏡像存儲(chǔ)上做更多。
列出鏡像
要列出所有的鏡像,運(yùn)行 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) |
- +---------------+--------------+--------+-----------------------------------------+--------+----------+------------------------------+
或者指定一個(gè)鏡像屬性中的鍵值對(duì)來過濾:
- 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
編輯鏡像
編輯鏡像的屬性和標(biāo)志的簡(jiǎn)單方法是使用:
- lxc image edit <alias or fingerprint>
這會(huì)打開默認(rèn)文本編輯器,內(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)閉自動(dòng)更新,或者標(biāo)記一個(gè)鏡像是公共的(后面詳述)。
刪除鏡像
刪除鏡像只需要運(yùn)行:
- lxc image delete <alias or fingerprint>
注意你不必移除緩存對(duì)象,它們會(huì)在過期后被 LXD 自動(dòng)移除(默認(rèn)上,在最后一次使用的 10 天后)。
導(dǎo)出鏡像
如果你想得到目前鏡像的 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 格式,雖然后者在與其他容器或虛擬機(jī)一起運(yùn)行時(shí)更容易重用其文件系統(tǒng)。
LXD 專注于系統(tǒng)容器,不支持任何應(yīng)用程序容器的“標(biāo)準(zhǔn)”鏡像格式,我們也不打算這么做。
我們的鏡像很簡(jiǎn)單,它們是由容器文件系統(tǒng),以及包含了鏡像制作時(shí)間、到期時(shí)間、什么架構(gòu),以及可選的一堆文件模板的元數(shù)據(jù)文件組成。
有關(guān)鏡像格式的最新詳細(xì)信息,請(qǐng)參閱此文檔。
unified 鏡像(一個(gè) tarball)
unified 鏡像格式是 LXD 在生成鏡像時(shí)使用的格式。它們是一個(gè)單獨(dú)的大型 tarball,包含 rootfs 目錄下的容器文件系統(tǒng),在 tarball 根目錄下有 metadata.yaml 文件,任何模板都放到 templates 目錄。
tarball 可以用任何方式壓縮(或者不壓縮)。鏡像散列是壓縮后的 tarball 的 sha256 。
Split 鏡像(兩個(gè) tarball)
這種格式最常用于滾動(dòng)更新鏡像并已經(jīng)有了一個(gè)壓縮文件系統(tǒng) tarball 時(shí)。
它們由兩個(gè)不同的 tarball 組成,第一個(gè)只包含 LXD 使用的元數(shù)據(jù), metadata.yaml 文件在根目錄,任何模板都在 templates 目錄。
第二個(gè) tarball 只包含直接位于其根目錄下的容器文件系統(tǒng)。大多數(shù)發(fā)行版已經(jīng)有這樣的 tarball,因?yàn)樗鼈兂S糜谝龑?dǎo)新機(jī)器。 此鏡像格式允許不經(jīng)修改就重用。
兩個(gè) 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
屬性
兩個(gè)唯一的必填字段是 creation date(UNIX 紀(jì)元時(shí)間)和 architecture。 其他都可以保持未設(shè)置,鏡像就可以正常地導(dǎo)入。
額外的屬性主要是幫助用戶弄清楚鏡像是什么。 例如 description 屬性是在 lxc image list 中可見的。 用戶可以使用其它屬性的鍵/值對(duì)來搜索特定鏡像。
相反,這些屬性用戶可以通過 lxc image edit來編輯,creation date 和 architecture 字段是不可變的。
模板
模板機(jī)制允許在容器生命周期中的某一點(diǎn)生成或重新生成容器中的一些文件。
我們使用 pongo2 模板引擎來做這些,我們將所有我們知道的容器信息都導(dǎo)出到模板。 這樣,你可以使用用戶定義的容器屬性或常規(guī) LXD 屬性來自定義鏡像,從而更改某些特定文件的內(nèi)容。
正如你在上面的例子中看到的,我們使用在 Ubuntu 中使用它們來進(jìn)行 cloud-init 并關(guān)閉一些 init 腳本。
創(chuàng)建你的鏡像
LXD 專注于運(yùn)行完整的 Linux 系統(tǒng),這意味著我們期望大多數(shù)用戶只使用干凈的發(fā)行版鏡像,而不是只用自己的鏡像。
但是有一些情況下,你有自己的鏡像是有必要的。 例如生產(chǎn)服務(wù)器上的預(yù)配置鏡像,或者構(gòu)建那些我們沒有構(gòu)建的發(fā)行版或者架構(gòu)的鏡像。
將容器變成鏡像
目前使用 LXD 構(gòu)造鏡像最簡(jiǎn)單的方法是將容器變成鏡像。
可以這么做:
- 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
你甚至可以將一個(gè)容器過去的快照變成鏡像:
- lxc publish my-container/some-snapshot --alias some-image
手動(dòng)構(gòu)建鏡像
構(gòu)建你自己的鏡像也很簡(jiǎn)單。
- 生成容器文件系統(tǒng)。這完全取決于你使用的發(fā)行版。對(duì)于 Ubuntu 和 Debian,它將用于啟動(dòng)。
- 配置容器中該發(fā)行版正常工作所需的任何東西(如果需要任何東西)。
- 制作該容器文件系統(tǒng)的 tarball,可選擇壓縮它。
- 根據(jù)上面描述的內(nèi)容寫一個(gè)新的 metadata.yaml 文件。
- 創(chuàng)建另一個(gè)包含 metadata.yaml 文件的 tarball。
- 用下面的命令導(dǎo)入這兩個(gè) tarball 作為 LXD 鏡像:lxc image import <metadata tarball> <rootfs tarball> --alias some-name
在一切都正常工作前你可能需要經(jīng)歷幾次這樣的工作,調(diào)整這里或那里,可能會(huì)添加一些模板和屬性。
發(fā)布你的鏡像
所有 LXD 守護(hù)程序都充當(dāng)鏡像服務(wù)器。除非另有說明,否則加載到鏡像存儲(chǔ)中的所有鏡像都會(huì)被標(biāo)記為私有,因此只有受信任的客戶端可以檢索這些鏡像,但是如果要?jiǎng)?chuàng)建公共鏡像服務(wù)器,你需要做的是將一些鏡像標(biāo)記為公開,并確保你的 LXD 守護(hù)進(jìn)程監(jiān)聽網(wǎng)絡(luò)。
只運(yùn)行 LXD 公共服務(wù)器
最簡(jiǎn)單的共享鏡像的方式是運(yùn)行一個(gè)公共的 LXD 守護(hù)進(jìn)程。
你只要運(yùn)行:
- lxc config set core.https_address "[::]:8443"
遠(yuǎn)程用戶就可以添加你的服務(wù)器作為公共服務(wù)器:
- lxc remote add <some name> <IP or DNS> --public
他們就可以像使用任何默認(rèn)的鏡像服務(wù)器一樣使用它們。 由于遠(yuǎn)程服務(wù)器添加了 -public 選項(xiàng),因此不需要身份驗(yàn)證,并且客戶端僅限于使用已標(biāo)記為 public 的鏡像。
要將鏡像設(shè)置成公共的,只需使用 lxc image edit 編輯它們,并將 public 標(biāo)志設(shè)置為 true。
使用一臺(tái)靜態(tài) web 服務(wù)器
如上所述,lxc image import 支持從靜態(tài) https 服務(wù)器下載。 基本要求是:
- 服務(wù)器必須支持具有有效證書的 HTTPS、TLS 1.2 和 EC 算法。
- 當(dāng)訪問 lxc image import 提供的 URL 時(shí),服務(wù)器必須返回一個(gè)包含 LXD-Image-Hash 和 LXD-Image-URL 的 HTTP 標(biāo)頭。
如果你想使它動(dòng)態(tài)化,你可以讓你的服務(wù)器查找 LXD 在請(qǐng)求鏡像時(shí)發(fā)送的 LXD-Server-Architectures 和 LXD-Server-Version 的 HTTP 標(biāo)頭,這可以讓你返回符合該服務(wù)器架構(gòu)的正確鏡像。
構(gòu)建一個(gè)簡(jiǎn)單流服務(wù)器
ubuntu: 和 ubuntu-daily: 遠(yuǎn)端服務(wù)器不使用 LXD 協(xié)議(images: 使用),而是使用稱為簡(jiǎn)單流(simplestreams)的不同協(xié)議。
簡(jiǎn)單流基本上是一個(gè)鏡像服務(wù)器的描述格式,使用 JSON 來描述產(chǎn)品以及相關(guān)產(chǎn)品的文件列表。
它被各種工具,如 OpenStack、Juju、MAAS 等用來查找、下載或者做鏡像系統(tǒng),LXD 將它作為用于鏡像檢索的原生協(xié)議。
雖然這的確不是提供 LXD 鏡像的最簡(jiǎn)單的方法,但是如果你的鏡像也被其它一些工具使用,那這也許值得考慮一下。
關(guān)于簡(jiǎn)單流的更多信息可以在這里找到。
總結(jié)
我希望這篇關(guān)于如何使用 LXD 管理鏡像以及構(gòu)建和發(fā)布鏡像文章讓你有所了解。對(duì)于以前的 LXC 而言,可以在一組全球分布式系統(tǒng)上得到完全相同的鏡像是一個(gè)很大的進(jìn)步,并且引導(dǎo)了更多可復(fù)制性的發(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 。