溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Registr容器鏡像服務(wù)端怎么實現(xiàn)

發(fā)布時間:2022-01-11 17:33:19 來源:億速云 閱讀:136 作者:iii 欄目:云計算

今天小編給大家分享一下Registr容器鏡像服務(wù)端怎么實現(xiàn)的相關(guān)知識點,內(nèi)容詳細(xì),邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

相關(guān)開源項目

目前容器鏡像服務(wù)相關(guān)的開源項目主要有以下兩個。

  • Registry 

  • Harbor 

Registry具有基本的鏡像上傳、下載以及對接第三方鑒權(quán)的能力。Harbor則基于Registry做了相應(yīng)的企業(yè)級擴展的項目。提供了更多權(quán)限、審計、鏡像等功能,目前是CNCF孵化項目之一。其他詳情參考相關(guān)文章。這篇文章主要講解Registry項目的存儲細(xì)節(jié)。

鏡像細(xì)節(jié)

在了解服務(wù)端之前,我們來了解一下客戶端的鏡像容器的存儲環(huán)境。

聯(lián)合文件系統(tǒng) UnionFS(Union File System)

Docker的存儲驅(qū)動的實現(xiàn)是基于UnionFS。簡單列舉一下UnionFS下存儲鏡像的一些特點。

首先,UnionFS是一個分層的文件系統(tǒng)。一個Docker鏡像可能有多個層組成(注意他們是有順序的)。

其次,只有頂層是可寫的,其它層都是只讀的。這樣的機制帶來的好處是鏡像層可以被多個鏡像共享。對于Docker鏡像來說,所有層都是只讀的。當(dāng)一個鏡像運行時,會在該鏡像上增加一個容器層。十個相同的鏡像啟動,僅僅是增加十個容器層。銷毀容器時也僅僅是銷毀一個容器層而已。

  • UnionFS是一個分層的文件系統(tǒng)。一個Docker鏡像可能有多個層組成(注意他們是有順序的)。

  • 只有頂層是可寫的,其它層都是只讀的。這樣的機制帶來的好處是鏡像層可以被多個鏡像共享。對于Docker鏡像來說,所有層都是只讀的。當(dāng)一個鏡像運行時,會在該鏡像上增加一個容器層。十個相同的鏡像啟動,僅僅是增加十個容器層。銷毀容器時也僅僅是銷毀一個容器層而已。


    • 當(dāng)容器需要讀取文件的時候:從最上層鏡像開始查找,往下找,找到文件后讀取并放入內(nèi)存,若已經(jīng)在內(nèi)存中了,直接使用。(即,同一臺機器上運行的docker容器共享運行時相同的文件)。

    • 當(dāng)容器需要添加文件的時候:直接在最上面的容器層可寫層添加文件,不會影響鏡像層。

    • 當(dāng)容器需要修改文件的時候:從上往下層尋找文件,找到后,復(fù)制到容器可寫層,然后,對容器來說,可以看到的是容器層的這個文件,看不到鏡像層里的文件。容器在容器層修改這個文件。

    • 當(dāng)容器需要刪除文件的時候:從上往下層尋找文件,找到后在容器中記錄刪除。即,并不會真正的刪除文件,而是軟刪除。這將導(dǎo)致鏡像體積只會增加,不會減少。

由此可以思考很多安全和鏡像優(yōu)化上的問題。

  • 在鏡像構(gòu)建中記錄敏感信息然后再下一個構(gòu)建指令中刪除安全嗎?(不安全)

  • 在鏡像構(gòu)建中安裝軟件包然后再下一個構(gòu)建指令中清理軟件包能減小鏡像體積嗎?(并不能)

UnionFS一般有兩種實現(xiàn)方案:1. 基于文件實現(xiàn)。文件整體的覆蓋重寫。2. 基于塊實現(xiàn),對文件的修改只修改少量塊。

鏡像的服務(wù)端存儲細(xì)節(jié)

提供一個鏡像元信息(manifest)用于參考:

?  ~ docker pull ccr.ccs.tencentyun.com/paas/service-controller:7b1c981c7b1c981c: Pulling from paas/service-controllerDigest: sha256:e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419Status: Image is up to date for ccr.ccs.tencentyun.com/paas/service-controller:7b1c981cccr.ccs.tencentyun.com/paas/service-controller:7b1c981c
{   "schemaVersion": 2,   "mediaType": "application/vnd.docker.distribution.manifest.v2+json",   "config": {      "mediaType": "application/vnd.docker.container.image.v1+json",      "size": 4671,      "digest": "sha256:785f4150a5d9f62562f462fa2d8b8764df4215f0f2e3a3716c867aa31887f827"   },   "layers": [      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 44144090,         "digest": "sha256:e80174c8b43b97abb6bf8901cc5dade4897f16eb53b12674bef1eae6ae847451"      },      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 529,         "digest": "sha256:d1072db285cc5eb2f3415891381631501b3ad9b1a10da20ca2e932d7d8799988"      },      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 849,         "digest": "sha256:858453671e6769806e0374869acce1d9e5d97f5020f86139e0862c7ada6da621"      },      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 170,         "digest": "sha256:3d07b1124f982f6c5da7f1b85a0a12f9574d6ce7e8a84160cda939e5b3a1faad"      },      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 8461461,         "digest": "sha256:994dade28a14b2eac1450db7fa2ba53998164ed271b1e4b0503b1f89de44380c"      },      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 22178452,         "digest": "sha256:60a5bd5c14d0f37da92d2a5e94d6bbfc1e2a942d675aee24f055ced76e8a208f"      },      {         "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",         "size": 22178452,         "digest": "sha256:60a5bd5c14d0f37da92d2a5e94d6bbfc1e2a942d675aee24f055ced76e8a208f"      }   ]}

*接下來是本文最為重要的內(nèi)容,通過對上面這張圖的理解,我們就可以了解到Registry服務(wù)端存儲的細(xì)節(jié)。*

  • 圖中藍(lán)色的是服務(wù)端存儲的目錄。文字是目錄名稱,這個名稱是固定的。

  • 圖中紫色的是服務(wù)端存儲的文件。文字是文件名稱,link文件的內(nèi)容都是一個sha256的哈希值。data文件存儲了真正的元文件和鏡像層。

  • 圖中橙色的是服務(wù)端的動態(tài)目錄。目錄的名稱和倉庫名、鏡像標(biāo)簽或者sha256有關(guān)的。

整個圖是從上往下的。舉個例子,我們上面描述的manifest如果是存儲在服務(wù)端的話(文件哈希:sha256:e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419)。它存儲的路徑應(yīng)該是:/docker/registry/v2/blobs/sha256/e8/e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419/data。對應(yīng)圖上應(yīng)該是沿著左側(cè)一直向下。

我們開始拆解分析其結(jié)構(gòu)細(xì)節(jié)。

  • 左側(cè)是鏡像所有內(nèi)容的實際存儲,其幾乎占據(jù)的絕大部分儲存的空間,包括了鏡像層和鏡像元信息Manifest。


    • 例如鏡像層sha256:e80174c8b43b97abb6bf8901cc5dade4897f16eb53b12674bef1eae6ae847451的存儲位置,應(yīng)該在/docker/registry/v2/blobs/sha256/e8/e80174c8b43b97abb6bf8901cc5dade4897f16eb53b12674bef1eae6ae847451/data

Registr容器鏡像服務(wù)端怎么實現(xiàn)

  • 右側(cè)是鏡像元信息存儲的地方。鏡像元信息是按照命名空間和倉庫名稱分兩級目錄存儲的。


    • revisions包含了倉庫下曾經(jīng)上傳過的所有版本的鏡像元信息

    • tags包含了倉庫中的所有標(biāo)簽


    • current記錄了當(dāng)前標(biāo)簽指向的鏡像

    • index目錄則記錄了標(biāo)簽指向的歷史鏡像。

    • 每一個倉庫下面又分為_layers_manifests兩個部分

    • _layers負(fù)責(zé)記錄該倉庫引用了哪些鏡像層文件。

    • _manifests負(fù)責(zé)記錄鏡像的元信息


    • 對上述提供的manifest計算sha256,會得到元信息文件的哈希值sha256:e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419,這個元信息的存儲位置應(yīng)該在/docker/registry/v2/blobs/sha256/e8/e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419/data

舉個鏡像下載的例子:

我們想要知道ccr.ccs.tencentyun.com/paas/service-controller:7b1c981c這個鏡像現(xiàn)在的元信息,如何在服務(wù)端存儲中找到。

  1. 找到/docker/registry/v2/paas/service-controller/_manifests/tags/7b1c981c/current/link文件。里面有元信息的sha256信息。內(nèi)容應(yīng)該是sha256:e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419

  2. 找到實際存儲文件(/docker/registry/v2/blobs/sha256/e8/e8b84ce6c245f04e6e453532d676f7c7f0a94b3122f93a89a58f9ae49939e419/data)。前文中給出了該文件的json內(nèi)容。

  3. 根據(jù)源文件信息,客戶端依次下載對應(yīng)文件就可以了。(鑒權(quán)過程參考參考文檔)

  • ImageConfig

    sha256:785f4150a5d9f62562f462fa2d8b8764df4215f0f2e3a3716c867aa31887f827

  • ImageLayer

    sha256:e80174c8b43b97abb6bf8901cc5dade4897f16eb53b12674bef1eae6ae847451 sha256:d1072db285cc5eb2f3415891381631501b3ad9b1a10da20ca2e932d7d8799988 sha256:858453671e6769806e0374869acce1d9e5d97f5020f86139e0862c7ada6da621 sha256:3d07b1124f982f6c5da7f1b85a0a12f9574d6ce7e8a84160cda939e5b3a1faad sha256:994dade28a14b2eac1450db7fa2ba53998164ed271b1e4b0503b1f89de44380c sha256:60a5bd5c14d0f37da92d2a5e94d6bbfc1e2a942d675aee24f055ced76e8a208f

Tips:

  1. 很明顯同樣的鏡像層文件在存儲中只會有一個副本。使用相同基礎(chǔ)鏡像將節(jié)省大量的存儲成本。

  2. 如果想要算上述元信息文件的哈希值,請保證你復(fù)制的文件內(nèi)容尾部沒有EOL。[noeol]

基于存儲的幾個問題

鏡像構(gòu)建如何優(yōu)化?

根據(jù)UnionFS的特性,針對性的進(jìn)行優(yōu)化:

  1. 構(gòu)建時,一個構(gòu)建指令會生成一個鏡像層,盡量避免在鏡像層中出現(xiàn)垃圾文件,例如在安裝軟件之后刪除軟件包。

  2. 刪除敏感資源并不能使得該內(nèi)容真正消失,避免敏感內(nèi)容造成的安全問題。例如編譯鏡像最后刪除代碼是無效的欺騙自己的行為。

  3. 通過多階段構(gòu)建,減少中間產(chǎn)物以及編譯環(huán)境中的依賴內(nèi)容。

上傳到服務(wù)端鏡像,再上傳到其他倉庫需要重新上傳嗎?

**需要,在Registry的設(shè)計中倉庫是權(quán)限的最小單位,用戶是根據(jù)倉庫進(jìn)行權(quán)限管理與隔離的。**考慮如果這里忽略了這一塊的設(shè)計,鏡像層存在就避免重復(fù)上傳的話,客戶端可以通過構(gòu)造虛假鏡像元信息的方式,越權(quán)獲取到其他用戶的鏡像。_layers中記錄了倉庫有權(quán)限獲取的所有鏡像層的目的就在于此。

鏡像復(fù)制場景下如何優(yōu)化?

復(fù)制鏡像的場景和上傳場景的區(qū)別在于,源鏡像是用戶確實已經(jīng)擁有的。這里可以通過上述問題的思考進(jìn)行復(fù)制的優(yōu)化,當(dāng)鏡像層在目的地址已經(jīng)存在時,直接標(biāo)記倉庫擁有該層避免不必要的上傳。

鏡像歷史版本

根據(jù)存儲結(jié)構(gòu)的特點,可以較為輕松的回答這個問題。理論上只要不做Registry GC,不刪除倉庫元信息,倉庫歷史版本的鏡像都會在倉庫中一直保存的。

云服務(wù)的存儲對接

Registry作為一個開源軟件,適配各種云存儲產(chǎn)品屬于標(biāo)配功能了。Registry提供了標(biāo)準(zhǔn)的存儲驅(qū)動接口,只要實現(xiàn)了這一套接口就能適配運行起來了。

以上就是“Registr容器鏡像服務(wù)端怎么實現(xiàn)”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學(xué)習(xí)更多的知識,請關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI