摘要:包含的內(nèi)容一個(gè)由可選和四部分組成。對(duì)于這兩種不同類(lèi)型的文件格式,標(biāo)準(zhǔn)定義了兩個(gè)新的,分別是和。最新的標(biāo)準(zhǔn)里面并沒(méi)有涉及到,不過(guò)估計(jì)后續(xù)會(huì)加上。
上一篇介紹了hello-world的大概流程,那么hello-world的image里面到底包含了些什么呢?里面的格式是怎么樣的呢?
image所包含的內(nèi)容以及格式都是有標(biāo)準(zhǔn)的,由Open Containers Initiative(OCI)負(fù)責(zé)維護(hù),地址為image-spec,本文將對(duì)該標(biāo)準(zhǔn)做一個(gè)簡(jiǎn)單的解釋。
image包含的內(nèi)容一個(gè)image由manifest、image index (可選)、filesystem layers和configuration四部分組成。
關(guān)系圖先來(lái)看看構(gòu)成image的四部分的關(guān)系圖:
+-----------------------+ | Image Index(optional) | +-----------------------+ | | 1..* ↓ +----------------------+ | Image Manifest | +----------------------+ | 1..1 | 1..* +---------------+--------------+ | | ↓ ↓ +--------------+ +-------------------+ | Image Config | | Filesystem Layers | +--------------+ +-------------------+
Image Index和Manifest的關(guān)系是"1..*",表示它們是一對(duì)多的關(guān)系
Image Manifest和Config的關(guān)系是"1..1",表示它們是一對(duì)一的關(guān)系
Image Manifest和Filesystem Layers是一對(duì)多的關(guān)系
下面分別介紹它們各自都包含了哪些內(nèi)容。
Filesystem LayersFilesystem Layer包含了文件系統(tǒng)的信息,即該image包含了哪些文件/目錄,以及它們的屬性和數(shù)據(jù)。
包含的內(nèi)容每個(gè)filesystem layer都包含了在上一個(gè)layer上的改動(dòng)情況,主要包含三方面的內(nèi)容:
變化類(lèi)型:是增加、修改還是刪除了文件
文件類(lèi)型:每個(gè)變化發(fā)生在哪種文件類(lèi)型上
文件屬性:文件的修改時(shí)間、用戶(hù)ID、組ID、RWX權(quán)限等
比如在某一層增加了一個(gè)文件,那么這一層所包含的內(nèi)容就是增加的這個(gè)文件的數(shù)據(jù)以及它的屬性,具體的細(xì)節(jié)請(qǐng)參考標(biāo)準(zhǔn)文檔。
打包格式最終每個(gè)layer都會(huì)打包成一個(gè)文件,這個(gè)文件的格式可以是tar和tar+gzip兩種中的一種。
對(duì)于這兩種不同類(lèi)型的文件格式,標(biāo)準(zhǔn)定義了兩個(gè)新的media types,分別是application/vnd.oci.image.layer.v1.tar和application/vnd.oci.image.layer.v1.tar+gzip。
同時(shí)標(biāo)準(zhǔn)還定義了application/vnd.oci.image.layer.nondistributable.v1.tar和application/vnd.oci.image.layer.nondistributable.v1.tar+gzip這兩種對(duì)應(yīng)于nondistributable的格式,其實(shí)這兩種格式和前兩種格式包含的內(nèi)容是一樣的,只是用不同的類(lèi)型名稱(chēng)來(lái)區(qū)分它們的用途,對(duì)于名稱(chēng)中有nondistributable的layer,標(biāo)準(zhǔn)要求這種類(lèi)型的layer不能上傳,只能下載。
Image Config做過(guò)web開(kāi)發(fā)的程序員對(duì)media type應(yīng)該比較熟悉,簡(jiǎn)單點(diǎn)說(shuō),就是當(dāng)客戶(hù)端用http協(xié)議下載一個(gè)文件的時(shí)候,需要在http的首部帶上Accept字段,告訴服務(wù)器端它支持哪些類(lèi)型的文件,服務(wù)器返回文件的時(shí)候,需要在http的首部帶上Content-Type字段,告訴客戶(hù)端返回文件的類(lèi)型,如Accept: text/html,application/xml和Content-Type: text/html。
image config就是一個(gè)json文件,它的media type是application/vnd.oci.image.config.v1+json,這個(gè)json文件包含了對(duì)這個(gè)image的描述。先看看官方網(wǎng)站給的例子:
{ "created": "2015-10-31T22:22:56.015925234Z", "author": "Alyssa P. Hacker", "architecture": "amd64", "os": "linux", "config": { "User": "alice", "ExposedPorts": { "8080/tcp": {} }, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "FOO=oci_is_a", "BAR=well_written_spec" ], "Entrypoint": [ "/bin/my-app-binary" ], "Cmd": [ "--foreground", "--config", "/etc/my-app.d/default.cfg" ], "Volumes": { "/var/job-result-data": {}, "/var/log/my-app-logs": {} }, "WorkingDir": "/home/alice", "Labels": { "com.example.project.git.url": "https://example.com/project.git", "com.example.project.git.commit": "45a939b2999782a3f005621a8d0f29aa387e1d6b" } }, "rootfs": { "diff_ids": [ "sha256:c6f988f4874bb0add23a778f753c65efe992244e148a1d2ec2a8b664fb66bbd1", "sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef" ], "type": "layers" }, "history": [ { "created": "2015-10-31T22:22:54.690851953Z", "created_by": "/bin/sh -c #(nop) ADD file:a3bc1e842b69636f9df5256c49c5374fb4eef1e281fe3f282c65fb853ee171c5 in /" }, { "created": "2015-10-31T22:22:55.613815829Z", "created_by": "/bin/sh -c #(nop) CMD ["sh"]", "empty_layer": true } ] }
這里只介紹幾個(gè)比較重要的屬性,其它的請(qǐng)參考標(biāo)準(zhǔn)文檔
architecture:CPU架構(gòu)類(lèi)型,現(xiàn)在大部分都是amd64,不過(guò)arm64估計(jì)會(huì)慢慢多起來(lái)
os:操作系統(tǒng),本人只用過(guò)linux
config:當(dāng)根據(jù)這個(gè)image啟動(dòng)container時(shí),config里面的配置就是運(yùn)行container時(shí)的默認(rèn)參數(shù),在后續(xù)介紹runtime的時(shí)候再仔細(xì)介紹每一項(xiàng)的意義
rootfs:指定了image所包含的filesystem layers,type的值必須是layers,diff_ids包含了layer的列表(順序排列),每一個(gè)sha256就是每層layer對(duì)應(yīng)tar包的sha256碼
manifestmanifest也是一個(gè)json文件,media type為application/vnd.oci.image.manifest.v1+json,這個(gè)文件包含了對(duì)前面filesystem layers和image config的描述,一看官方網(wǎng)站給出的示例就明白了:
manifest文件中config的sha256就是image的ID,即上面image config文件的sha256值,這里是b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7
{ "schemaVersion": 2, "config": { "mediaType": "application/vnd.oci.image.config.v1+json", "size": 7023, "digest": "sha256:b5b2b2c507a0944348e0303114d8d93aaaa081732b86451d9bce1f432a537bc7" }, "layers": [ { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", "size": 32654, "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f" }, { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", "size": 16724, "digest": "sha256:3c3a4604a545cdc127456d94e421cd355bca5b528f4a9c1905b15da2eb4a4c6b" }, { "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip", "size": 73109, "digest": "sha256:ec4b8955958665577945c89419d1af06b5f7636b4ac3da7f12184802ad867736" } ], "annotations": { "com.example.key1": "value1", "com.example.key2": "value2" } }
config里面包含了對(duì)image config文件的描述,有media type,文件大小,以及sha256碼
layers包含了對(duì)每一個(gè)layer的描述,和對(duì)config文件的描述一樣,也包含了media type,文件大小,以及sha256碼
Image Index(可選)這里layer的sha256和image config文件中的diff_ids有可能不一樣,比如這里的layer文件格式是tar+gzip,那么這里的sha256就是tar+gzip包的sha256碼,而diff_ids是tar+gzip解壓后tar文件的sha256碼
image index也是個(gè)json文件,media type是application/vnd.oci.image.index.v1+json。
其實(shí)到manifest為止,已經(jīng)有了整個(gè)image的完整描述,為什么還需要image index這個(gè)文件呢?主要原因是manifest描述的image只能支持一個(gè)平臺(tái),也沒(méi)法支持多個(gè)tag,加上index文件的目的就是讓這個(gè)image能支持多個(gè)平臺(tái)和多tag。
image index是v1.0.0-rc5才加進(jìn)來(lái)的一個(gè)文件,還不穩(wěn)定,后面可能還會(huì)修改,并且docker現(xiàn)在也不支持該文件,這里看看官方給的示例,先了解一下:
{ "schemaVersion": 2, "manifests": [ { "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 7143, "digest": "sha256:e692418e4cbaf90ca69d05a66403747baa33ee08806650b51fab815ad7fc331f", "platform": { "architecture": "ppc64le", "os": "linux" } }, { "mediaType": "application/vnd.oci.image.manifest.v1+json", "size": 7682, "digest": "sha256:5b0bcabd1ed22e9fb1310cf6c2dec7cdef19f0ad69efa1f392e94a4333501270", "platform": { "architecture": "amd64", "os": "linux", "os.features": [ "sse4" ] } } ], "annotations": { "com.example.key1": "value1", "com.example.key2": "value2" } }
index文件包含了對(duì)image中所有manifest的描述,相當(dāng)于一個(gè)manifest列表,包括每個(gè)manifest的media type,文件大小,sha256碼,支持的平臺(tái)以及平臺(tái)特殊的配置。
比如ubuntu想讓它的image支持amd64和arm64平臺(tái),于是它在兩個(gè)平臺(tái)上都編譯好相應(yīng)的包,然后將兩個(gè)平臺(tái)的layer都放到這個(gè)image的filesystem layers里面,然后寫(xiě)兩個(gè)config文件和兩個(gè)manifest文件,再加上這樣一個(gè)描述不同平臺(tái)manifest的index文件,就可以讓這個(gè)image支持兩個(gè)平臺(tái)了,兩個(gè)平臺(tái)的用戶(hù)可以使用同樣的命令得到自己平臺(tái)想要的那些layer。
image layoutimage index最新的標(biāo)準(zhǔn)里面并沒(méi)有涉及到tag,不過(guò)估計(jì)后續(xù)會(huì)加上。
上面介紹了image所包含的內(nèi)容,在開(kāi)始介紹layout之前,先來(lái)回顧一下上一篇介紹hello-world時(shí)提到的從register服務(wù)器拉image的過(guò)程:
首先獲取image的manifests
根據(jù)manifests文件中config的sha256碼,得到image config文件
遍歷manifests里面的所有l(wèi)ayer,根據(jù)其sha256碼在本地找,如果找到對(duì)應(yīng)的layer,則跳過(guò),否則從服務(wù)器取相應(yīng)layer的壓縮包
等上面的所有步驟完成后,就會(huì)拼出完整的image
從上面的過(guò)程中可以看出,我們從服務(wù)器上取image的時(shí)候不需要知道image manifests和config文件的名字,也不需要知道layer壓縮包的名字。
那么image從服務(wù)器拉下來(lái)后,在本地應(yīng)該怎么存儲(chǔ)呢?文件名稱(chēng)和目錄結(jié)構(gòu)應(yīng)該是怎樣的呢?OCI也有相應(yīng)的標(biāo)準(zhǔn),名字叫image layout,有了這樣的標(biāo)準(zhǔn)之后,我們就可以將整個(gè)image打成一個(gè)包,方便的在不同機(jī)器,不同容器平臺(tái)之間導(dǎo)入導(dǎo)出。
不過(guò)遺憾的是,OCI的這個(gè)標(biāo)準(zhǔn)還在變化中,根據(jù)github上所看到的,v1.0.0-rc5在v1.0.0-rc4上就有較大的修改,并且現(xiàn)在docker也不支持該標(biāo)準(zhǔn)。
docker對(duì)OCI image layout的支持還在開(kāi)發(fā)中,相關(guān)動(dòng)態(tài)請(qǐng)關(guān)注:Support OCI image layout in docker save/load
這里我們看看v1.0.0-rc4的格式,下面是hello-world image的目錄結(jié)構(gòu),了解一下:
dev@debian:~/images/hello-world$ tree . ├── blobs │?? └── sha256 │?? ├── 636fcf0bc8246e08d2df4771dc764d35ea50428b8dfaa904773b0707cb4f6303 │?? ├── 7520415ce76232cdd62ecc345cea5ea44f5b6b144dc62351f2cd2b08382532a3 │?? └── 9b8e3ce88f3a2aaa478cfe613632f38d27be5eddaa002a719fa1bfa9ff4f7f63 ├── oci-layout └── refs └── latestoci-layout
包含image標(biāo)準(zhǔn)的版本信息
dev@debian:~/images/hello-world$ cat ./oci-layout| jq . { "imageLayoutVersion": "1.0.0" }refs
里面的每個(gè)文件就是一個(gè)tag(hello-world的image中只有一個(gè)latest tag),每個(gè)tag都是一個(gè)多帶帶的image,相當(dāng)于一個(gè)image的layout包里面可以包含多個(gè)有關(guān)系的image,文件的內(nèi)容如下:
dev@debian:~/images/hello-world$ cat ./refs/latest | jq . { "mediaType": "application/vnd.oci.image.manifest.v1+json", "digest": "sha256:9b8e3ce88f3a2aaa478cfe613632f38d27be5eddaa002a719fa1bfa9ff4f7f63", "size": 347 }
其實(shí)就是對(duì)manifest文件的描述,根據(jù)sha256就可以在blobs的目錄里面找到相應(yīng)的manifest文件
blobs里面包含了具體文件的內(nèi)容,每個(gè)文件名都是其內(nèi)容的sha256碼,根據(jù)上面refs文件里面的sha256,就能在這里找到對(duì)應(yīng)的manifest文件的內(nèi)容,然后根據(jù)manifest文件的內(nèi)容,就能一步一步的往下找到image config文件和filesystem layers文件。
dev@debian:~/images/hello-world$ file ./blobs/sha256/* ./blobs/sha256/636fcf0bc8246e08d2df4771dc764d35ea50428b8dfaa904773b0707cb4f6303: ASCII text, with very long lines, with no line terminators ./blobs/sha256/7520415ce76232cdd62ecc345cea5ea44f5b6b144dc62351f2cd2b08382532a3: gzip compressed data ./blobs/sha256/9b8e3ce88f3a2aaa478cfe613632f38d27be5eddaa002a719fa1bfa9ff4f7f63: ASCII text, with very long lines, with no line terminators dev@debian:~/images/hello-world$ sha256sum ./blobs/sha256/* 636fcf0bc8246e08d2df4771dc764d35ea50428b8dfaa904773b0707cb4f6303 ./blobs/sha256/636fcf0bc8246e08d2df4771dc764d35ea50428b8dfaa904773b0707cb4f6303 7520415ce76232cdd62ecc345cea5ea44f5b6b144dc62351f2cd2b08382532a3 ./blobs/sha256/7520415ce76232cdd62ecc345cea5ea44f5b6b144dc62351f2cd2b08382532a3 9b8e3ce88f3a2aaa478cfe613632f38d27be5eddaa002a719fa1bfa9ff4f7f63 ./blobs/sha256/9b8e3ce88f3a2aaa478cfe613632f38d27be5eddaa002a719fa1bfa9ff4f7f63下載image
上面介紹image layout時(shí)用到了hello-world的image,它是從哪里來(lái)的呢?
為了快速的構(gòu)建container的rootfs,docker在本地有它自己的一套image管理方式,有自己的layout,并且目前docker save命令也不支持導(dǎo)出OCI格式的image,只能導(dǎo)出docker自己的格式,所以我們只能借助其它的工具得到OCI格式的image。
這里我們用skopeo來(lái)演示一下從docker hub上拉取hello-world的image,并把它在本地存成OCI的layout。
這里生成的layout和最新版本的標(biāo)準(zhǔn)有點(diǎn)差別,和v1.0.0-rc4的標(biāo)準(zhǔn)一致,如果你用同樣的命令得到不一樣的layout,說(shuō)明skopeo有更新,支持了更新的標(biāo)準(zhǔn)。
#這里的所有命令在debian 8.6的環(huán)節(jié)上運(yùn)行通過(guò) #編譯安裝skopeo $ git clone https://github.com/projectatomic/skopeo $GOPATH/src/github.com/projectatomic/skopeo $ sudo apt-get install libgpgme11-dev libdevmapper-dev btrfs-tools go-md2man $ cd $GOPATH/src/github.com/projectatomic/skopeo $ make binary-local $ sudo make install #下載hello-world的image $ skopeo copy docker://hello-world oci:hello-world $ tree hello-world/ hello-world/ ├── blobs │?? └── sha256 │?? ├── 636fcf0bc8246e08d2df4771dc764d35ea50428b8dfaa904773b0707cb4f6303 │?? ├── 7520415ce76232cdd62ecc345cea5ea44f5b6b144dc62351f2cd2b08382532a3 │?? └── 9b8e3ce88f3a2aaa478cfe613632f38d27be5eddaa002a719fa1bfa9ff4f7f63 ├── oci-layout └── refs └── latest結(jié)束語(yǔ)
雖然OCI iamge的標(biāo)準(zhǔn)還處于rc階段,沒(méi)有正式release,并且docker現(xiàn)在也不支持OCI image的layout,不過(guò)相信過(guò)不了多久,OCI image的標(biāo)準(zhǔn)就會(huì)被廣泛支持,先了解一下還是很有必要的。
參考OCI Image Format Specification
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/26899.html
摘要:包含的內(nèi)容本系列主要介紹三個(gè)上的項(xiàng)目由于只介紹核心的東西,所以不會(huì)包含下面這些項(xiàng)目使用語(yǔ)言開(kāi)發(fā),將多個(gè)相關(guān)的容器配置在一起,從而可以同時(shí)創(chuàng)建啟動(dòng)停止和監(jiān)控它們。由于本人時(shí)間安排發(fā)生變化,本系列停止更新,后面不確定是否會(huì)繼續(xù),非常抱歉。 本人docker初學(xué)者,邊學(xué)習(xí)邊總結(jié),一方面加深自己的理解,另一方面希望對(duì)其他想深入了解docker的同學(xué)有所幫助。 由于本人缺乏實(shí)戰(zhàn)經(jīng)驗(yàn),錯(cuò)誤在所難免...
摘要:里面可以通過(guò)等方式得到一個(gè),得到之后在本地是怎么存儲(chǔ)的呢本篇將以為例,簡(jiǎn)述的獲取和存儲(chǔ)方式。鏡像相關(guān)的配置里面和有關(guān)的目錄為,里面存放著的所有信息,可以通過(guò)下面這個(gè)的啟動(dòng)參數(shù)來(lái)修改這個(gè)目錄的路徑。 docker里面可以通過(guò)docker pull、docker build、docker commit、docker load、docker import等方式得到一個(gè)image,得到imag...
摘要:進(jìn)程啟動(dòng)后,就會(huì)按照的標(biāo)準(zhǔn)準(zhǔn)備好相關(guān)運(yùn)行時(shí)環(huán)境,然后啟動(dòng)進(jìn)程。涉及到標(biāo)準(zhǔn)輸入輸出重定向,這里不細(xì)說(shuō)這里是它們之間的交互流程流程對(duì)應(yīng)的文字描述如下客戶(hù)端發(fā)送創(chuàng)建容器請(qǐng)求給,收到請(qǐng)求后,發(fā)現(xiàn)本地沒(méi)有相應(yīng)的額,于是返回失敗。 在程序員的世界里,hello world是個(gè)很特殊的存在,當(dāng)我們接觸一門(mén)新的語(yǔ)言、新的開(kāi)發(fā)庫(kù)或者框架時(shí),第一時(shí)間想了解的一般都是怎么實(shí)現(xiàn)一個(gè)hello world,然后...
摘要:相關(guān)工具本文將用到三個(gè)工具,分別是和。根據(jù)生成的的就是運(yùn)行容器時(shí)需要的東西的集合。使用運(yùn)行該有了后,就可以用來(lái)運(yùn)行該容器了這里直接用的代替命令,如果你自己編譯了的,那么用命令也是一樣的。 上一篇介紹了image的格式,這里我們就來(lái)用一下hello-world這個(gè)image,看怎么輸出和docker run hello-world同樣的內(nèi)容。 相關(guān)工具 本文將用到三個(gè)工具,分別是skop...
閱讀 1864·2021-11-25 09:43
閱讀 2146·2021-11-19 09:40
閱讀 3422·2021-11-18 13:12
閱讀 1739·2021-09-29 09:35
閱讀 661·2021-08-24 10:00
閱讀 2505·2019-08-30 15:55
閱讀 1709·2019-08-30 12:56
閱讀 1815·2019-08-28 17:59