偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何優(yōu)雅的將Docker Registry中容器鏡像遷移至Harbor

系統(tǒng) Linux
根據(jù)木子在 深入淺出容器鏡像的一生[6] 文章中提到的 registry 的存儲(chǔ)目錄結(jié)構(gòu),我們可以使用如下命令獲取 registry 中的所有鏡像的列表。

 [[441584]]

Registry

Docker Distribution

Docker Distribution[1] 是第一個(gè)是實(shí)現(xiàn)了打包、發(fā)布、存儲(chǔ)和鏡像分發(fā)的工具,起到 Docker registry 的作用。其中 Docker Distribution 中的 spec 規(guī)范[2] 后來(lái)也就成為了 OCI distribution-spec[3] 規(guī)范??梢哉J(rèn)為 Docker Distribution 實(shí)現(xiàn)了大部分 OCI 鏡像分發(fā)的規(guī)范,二者在很大程度上也是兼容的。OCI 的指導(dǎo)思想是先有工業(yè)界的實(shí)踐,再將這些實(shí)踐總結(jié)成技術(shù)規(guī)范,因此盡管 OCI 的 distribution-spec[4] 規(guī)范還沒(méi)有正式發(fā)布(目前版本是v1.0.0-rc1[5]),但以 Docker Distribution 作為基礎(chǔ)的鏡像倉(cāng)庫(kù)已經(jīng)成為普遍采用的方案,Docker registry HTTP API V2 也就成為了事實(shí)上的標(biāo)準(zhǔn)。

Harbor

Harbor 也是采用了 Docker Distribution (docker registry)作為后端鏡像存儲(chǔ),在 Harbor 2.0 之前的版本,鏡像相關(guān)的功能大部分是由 Docker Distribution 來(lái)處理,鏡像和 OCI 等制品的元數(shù)據(jù)是 harbor 組件從 docker registry 中提取出來(lái)的;從 Harbor 2.0 版本之后,鏡像等 OCI 制品相關(guān)的元數(shù)據(jù)由 Harbor 自己來(lái)維護(hù),而且元數(shù)據(jù)是在 PUSH 這些制品時(shí)寫入到 harbor 的數(shù)據(jù)庫(kù)中的。也正因得益于此,Harbor 不再僅僅是個(gè)用來(lái)存儲(chǔ)和管理鏡像的服務(wù),而一個(gè)云原生倉(cāng)庫(kù)服務(wù),能夠存儲(chǔ)和管理符合 OCI 規(guī)范的 Helm Chart、CNAB、OPA Bundle 等 Artifact 。

docker registry to harbor

好了,扯了這么多沒(méi)用的概念,回到本文要解決的問(wèn)題:如何將 docker registry 中的鏡像遷移至 harbor?

假如內(nèi)網(wǎng)環(huán)境中有兩臺(tái)機(jī)器,一臺(tái)機(jī)器上運(yùn)行著 docker registry,域名假設(shè)為 registry.k8s.li 。另一臺(tái)機(jī)器運(yùn)行著 harbor,假設(shè)域名為 harbor.k8s.li?,F(xiàn)在 docker registry 中存放了五千個(gè)鏡像。harbor 是剛剛部署了,里面還沒(méi)有鏡像。在磁盤和網(wǎng)絡(luò)沒(méi)有限制的情況下,如何將 docker registry 中的鏡像遷移到 harbor 中?

獲取 registry 所有鏡像的列表

根據(jù)木子在 深入淺出容器鏡像的一生 🤔[6] 文章中提到的 registry 的存儲(chǔ)目錄結(jié)構(gòu),我們可以使用如下命令獲取 registry 中的所有鏡像的列表。

# 首先進(jìn)入到 registry 存儲(chǔ)的主目錄下 :

  1. cd  /var/lib/registry  
  2. find docker -type d -name "current" | sed 's|docker/registry/v2/repositories/||g;s|/_manifests/tags/|:|g;s|/current||g' > images.list 

方案一:docker retag

方案一可能是大多數(shù)人首先想到的辦法,也是最簡(jiǎn)單粗暴的方法。就是在一臺(tái)機(jī)器上使用 docker pull 下 docker registry 中的所有鏡像,然后再 docker retag 一下,再 docker push 到 harbor 中。

  1. # 假設(shè)其中的一個(gè)鏡像為 library/alpine:latest  
  2. docker pull registry.k8s.li/library/alpine:latest  
  3. docker tag registry.k8s.li/library/alpine:latest harbor.k8s.li/library/alpine:latest  
  4. docker push harbor.k8s.li/library/alpine:latest 

如果你之前讀過(guò)木子曾經(jīng)寫過(guò)的 深入淺出容器鏡像的一生 🤔[7] 和 鏡像搬運(yùn)工 skopeo 初體驗(yàn)[8] 并且已經(jīng)在日常生活中使用 skopeo ,你一定會(huì)很覺著這個(gè)方案很蠢,因?yàn)?docker pull –> docker tag –> docker pull 的過(guò)程中會(huì)對(duì)鏡像的 layer 進(jìn)行解壓縮,但對(duì)于只是將鏡像從一個(gè) registry 復(fù)制到另一個(gè) registry 來(lái)說(shuō),這些過(guò)程中做了很多無(wú)用功。詳細(xì)的原理可以翻看一下剛提到的兩篇文章,在此就不再贅述。

那么對(duì)于追求極致的人來(lái)講肯定不會(huì)采用 docker retag 這么蠢的辦法啦,下面就講一下方案二:

方案二:skopeo

在 鏡像搬運(yùn)工 skopeo 初體驗(yàn)[9] 中介紹過(guò)可以使用 skopeo copy 直接從一個(gè) registry 中復(fù)制鏡像原始的 layer 到另一個(gè) registry 中,期間不會(huì)涉及鏡像 layer 解壓縮操作。至于性能和耗時(shí),比 docker 高到不知道哪里去了 😂。

  • 使用 skopeo copy 
  1. skopeo copy docker://registry.k8s.li/library/alpine:latest \ docker://harbor.k8s.li/library/alpine:latest 
  •  使用 skopeo sync 
  1. skopeo sync --insecure-policy --src-tls-verify=false --dest-tls-verify=false --src docker --dest docker registry.k8s.li/library/alpine:latest harbor.k8s.li/library/alpine:latest 

但還有沒(méi)有更好的辦法?要知道無(wú)論是 docker 和 skopeo 本質(zhì)上都是通過(guò) registry 的 HTTP API 下載和上傳鏡像的,在這過(guò)程中還是多了不少 HTTP 請(qǐng)求的,還有沒(méi)有更好的辦法?

方案三:遷移存儲(chǔ)目錄

文章開篇提到 harbor 的后端鏡像存儲(chǔ)也是使用的 docker registry,那為何不直接將 registry 的存儲(chǔ)目錄打包復(fù)制并解壓到 harbor 的 registry 存儲(chǔ)目錄呢?對(duì)于 harbor 1.x 版本來(lái)講,將 docker 的 registry 存儲(chǔ)目錄遷移到 harbor 的 registry 存儲(chǔ)目錄,然后刪除 harbor 的 redis 數(shù)據(jù),重啟 harbor 就完事兒了。重啟 harbor 之后,harbor 會(huì)調(diào)用后端的 registry 去提取鏡像的元數(shù)據(jù)信息并存儲(chǔ)到 redis 中。這樣就完成了遷移的工作。 

  1. # 切換到 harbor 的存儲(chǔ)目錄  
  2. cd /data/harbor  
  3. # 將 docker registry 備份的 docker 目錄解壓到 harbor 的 registry 目錄下,目錄層級(jí)一定要對(duì)應(yīng)好  
  4. tar -xf docker.tar.gz -C ./registry  
  5. # 刪除 harbor 的 regis 數(shù)據(jù),重啟 harbor 后會(huì)重建 redis 數(shù)據(jù)。  
  6. rm -f redis/dump.rdb 
  7. # 切換到 harbor 的安裝目錄重啟 harbor  
  8. cd /opt/harbor 
  9.  docker-compose restart 

方案四:

對(duì)于 harbor 2.x 來(lái)講,由于 harbor 強(qiáng)化了 Artifact 的元數(shù)據(jù)管理能力,即元數(shù)據(jù)在 push 或者 sync 到 harbor 時(shí)會(huì)寫入到 harbor 自身的數(shù)據(jù)庫(kù)中。在 harbor 看來(lái)只要數(shù)據(jù)庫(kù)中沒(méi)有這個(gè) Artifact 的 manifest 信息或者沒(méi)有這一層 layer 的信息,harbor 都會(huì)認(rèn)為該 Artifact 或者 layer 不存在,返回 404 的錯(cuò)誤。所以按照方案三直接而將 registry 存儲(chǔ)目錄解壓到 harbor 的 registry 存儲(chǔ)目錄時(shí)行不通的。那么現(xiàn)在看來(lái)只能通過(guò) skopeo copy 的方法將鏡像一個(gè)一個(gè)地 push 到 harbor 中了。

對(duì)于某些特定的場(chǎng)景下,不能像方案二那樣擁有一個(gè) docker registry 的 HTTP 服務(wù),只有一個(gè) docker registry 的壓縮包,這如何將 docker registry 的存儲(chǔ)目錄中的鏡像遷移到 harbor 2.0 中呢?

那么再次邀請(qǐng)我們的 skopeo 大佬出場(chǎng),在 鏡像搬運(yùn)工 skopeo 初體驗(yàn)[10] 中提到過(guò) skopeo 支持的鏡像格式有如下幾種:

IMAGE NAMES example
containers-storage: containers-storage:
dir: dir:/PATH
docker:// docker://k8s.gcr.io/kube-apiserver:v1.17.5
docker-daemon: docker-daemon:alpine:latest
docker-archive: docker-archive:alpine.tar (docker save)
oci: oci:alpine:latest

需要注意的是,這幾種鏡像的名字,對(duì)應(yīng)著鏡像存在的方式,不同存在的方式對(duì)鏡像的 layer 處理的方式也不一樣,比如 docker:// 這種方式是存在 registry 上的,docker-daemon: 是存在本地 docker pull 下來(lái)的,再比如 docker-archive 是通過(guò) docker save 出來(lái)的鏡像。同一個(gè)鏡像有這幾種存在的方式就像水有氣體、液體、固體一樣??梢赃@樣去理解,他們表述的都是同一個(gè)鏡像,只不過(guò)是存在的方式不一樣而已。

既然鏡像是存放在 registry 存儲(chǔ)目錄里的,那么使用 dir 的形式直接從文件系統(tǒng)讀取鏡像,理論上來(lái)講會(huì)比方案二要好一些。雖然 skopeo 支持 dir 格式的鏡像,但 skopeo 目前并不支持直接使用 registry 的存儲(chǔ)目錄,所以還是需要想辦法將 docker registry 存儲(chǔ)目錄里的每一個(gè)鏡像轉(zhuǎn)換成 skopeo dir 的形式。

skopeo dir

那么先來(lái)看一下 skopeo dir 是什么樣子的?

為了方便測(cè)試方案的可行性,先使用 skopeo 命令先從 docker hub 上拉取一個(gè)鏡像,并保存為 dir,命令如下: 

  1. skopeo copy docker://alpine:latest dir:./alpine 

使用 tree 命令查看一下 alpine 文件夾的目錄結(jié)構(gòu),如下: 

  1. ╭─root@sg-02 /var/lib/registry  
  2. ╰─# tree -h alpine  
  3. alpine  
  4. ├── [2.7M]  4c0d98bf9879488e0407f897d9dd4bf758555a78e39675e72b5124ccf12c2580  
  5. ├── [1.4K]  e50c909a8df2b7c8b92a6e8730e210ebe98e5082871e66edd8ef4d90838cbd25  
  6. ├── [ 528]  manifest.json  
  7. └── [  33]  version  
  8. 0 directories, 4 files  
  9. ╭─root@sg-02 /var/lib/registry  
  10. ╰─# file alpine/e50c909a8df2b7c8b92a6e8730e210ebe98e5082871e66edd8ef4d90838cbd25  
  11. alpine/e50c909a8df2b7c8b92a6e8730e210ebe98e5082871e66edd8ef4d90838cbd25: ASCII text, with very long lines, with no line terminators  
  12. ╭─root@sg-02 /var/lib/registry  
  13. ╰─# file alpine/4c0d98bf9879488e0407f897d9dd4bf758555a78e39675e72b5124ccf12c2580  
  14. alpine/4c0d98bf9879488e0407f897d9dd4bf758555a78e39675e72b5124ccf12c2580: gzip compressed data 

從文件名和大小以及文件的內(nèi)省我們可以判斷出,manifest 文件對(duì)應(yīng)的就是鏡像的 manifests 文件;類型為 ASCII text 的文件正是鏡像的 image config 文件,里面包含著鏡像的元數(shù)據(jù)信息。而另一個(gè) gzip compressed data 文件不就是經(jīng)過(guò) gzip 壓縮過(guò)的鏡像 layer 嘛??匆幌?manifest 文件的內(nèi)容也再次印證了這個(gè)結(jié)論:

  •  鏡像的 config 字段對(duì)應(yīng)的正是 e50c909a8df2,而文件類型正是 image.v1+json 文本文件。
  •  鏡像的 layer 字段對(duì)應(yīng)的也正是 4c0d98bf9879 而文件類型正是 .tar.gzip gzip 壓縮文件。 
  1. alpine/4c0d98bf9879488e0407f897d9dd4bf758555a78e39675e72b5124ccf12c2580: gzip compressed data  
  2. ╭─root@sg-02 /var/lib/registry  
  3. ╰─# cat alpine/manifest.json  
  4.  
  5.    "schemaVersion": 2, 
  6.     "mediaType": "application/vnd.docker.distribution.manifest.v2+json",  
  7.    "config": { 
  8.        "mediaType": "application/vnd.docker.container.image.v1+json",  
  9.       "size": 1471, 
  10.        "digest": "sha256:e50c909a8df2b7c8b92a6e8730e210ebe98e5082871e66edd8ef4d90838cbd25"  
  11.    },  
  12.    "layers": [  
  13.       {  
  14.          "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",  
  15.          "size": 2811321,  
  16.          "digest": "sha256:4c0d98bf9879488e0407f897d9dd4bf758555a78e39675e72b5124ccf12c2580"  
  17.       }  
  18.    ]  

從 registry 存儲(chǔ)目錄中摳鏡像出來(lái)

接下來(lái)到本文的精彩的地方了。如何將 registry 存儲(chǔ)里的鏡像提取出來(lái),轉(zhuǎn)換成 skopeo 所支持的 dir 格式。

  •   首先要得到鏡像的 manifests 文件,從 manifests 文件中得到所有的 blob 文件。例如對(duì)于 registry 存儲(chǔ)目錄中的 library/alpine:latest 鏡像。 
  1. ╭─root@sg-02 /var/lib/registry/docker/registry/v2  
  2. ╰─# tree  
  3. ├── blobs  
  4. │   └── sha256  
  5. │       ├── 21  
  6. │       │   └── 21c83c5242199776c232920ddb58cfa2a46b17e42ed831ca9001c8dbc532d22d  
  7. │       │       └── data  
  8. │       ├── a1  
  9. │       │   └── a143f3ba578f79e2c7b3022c488e6e12a35836cd4a6eb9e363d7f3a07d848590  
  10. │       │       └── data  
  11. │       └── be  
  12. │           └── be4e4bea2c2e15b403bb321562e78ea84b501fb41497472e91ecb41504e8a27c  
  13. │               └── data  
  14. └── repositories  
  15.     └── library  
  16.         └── alpine  
  17.             ├── _layers  
  18.             │   └── sha256  
  19.             │       ├── 21c83c5242199776c232920ddb58cfa2a46b17e42ed831ca9001c8dbc532d22d  
  20.             │       │   └── link  
  21.             │       └── be4e4bea2c2e15b403bb321562e78ea84b501fb41497472e91ecb41504e8a27c  
  22.             │           └── link  
  23.             ├── _manifests  
  24.             │   ├── revisions  
  25.             │   │   └── sha256  
  26.             │   │       └── a143f3ba578f79e2c7b3022c488e6e12a35836cd4a6eb9e363d7f3a07d848590  
  27.             │   │           └── link  
  28.             │   └── tags  
  29.             │       └── latest  
  30.             │           ├── current  
  31.             │           │   └── link  
  32.             │           └── index  
  33.             │               └── sha256  
  34.             │                   └── a143f3ba578f79e2c7b3022c488e6e12a35836cd4a6eb9e363d7f3a07d848590  
  35.             │                       └── link  
  36.             └── _uploads  
  37. 26 directories, 8 files 

 1. 通過(guò) repositories/library/alpine/_manifests/tags/latest/current/link 文件得到 manifests 文件的 sha256 值,然后根據(jù)這個(gè) sha256 值去 blobs 找到鏡像的 manifests 文件; 

  1. ╭─root@sg-02 /var/lib/registry/docker/registry/v2/repositories/library/alpine/_manifests/tags/latest/current/  
  2. ╰─# cat link  
  3. sha256:39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01#  

2. 根據(jù) link 文件中的 sha256 值在 blobs 目錄下找到與之對(duì)應(yīng)的文件,blobs 目錄下對(duì)應(yīng)的 manifests 文件為 blobs/sha256/39/39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01/data; 

  1. ╭─root@sg-02 /var/lib/registry/docker/registry/v2/repositories/library/alpine/_manifests/tags/latest/current  
  2. ╰─# cat /var/lib/registry/docker/registry/v2/blobs/sha256/39/39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01/data  
  3.  
  4.    "schemaVersion": 2, 
  5.     "mediaType": "application/vnd.docker.distribution.manifest.v2+json",  
  6.    "config": {  
  7.       "mediaType": "application/vnd.docker.container.image.v1+json",  
  8.       "size": 1507,  
  9.       "digest": "sha256:f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a"  
  10.    },  
  11.    "layers": [  
  12.       {  
  13.          "mediaType": "application/vnd.docker.image.rootfs.diff.tar.gzip",  
  14.          "size": 2813316,  
  15.          "digest": "sha256:cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08"  
  16.       }  
  17.    ]  

 3. 使用正則匹配,過(guò)濾出 manifests 文件中的所有 sha256 值,這些 sha256 值就對(duì)應(yīng)著 blobs 目錄下的 image config 文件和 image layer 文件 

  1. ╭─root@sg-02 /var/lib/registry/docker/registry/v2/repositories/library/alpine/_manifests/tags/latest/current  
  2. ╰─# cat /var/lib/registry/docker/registry/v2/blobs/sha256/39/39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01/data | grep -Eo "\b[a-f0-9]{64}\b" 
  3. f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a  
  4. cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08 

4.  根據(jù) manifests 文件就可以得到 blobs 目錄中鏡像的所有 layer 和 image config 文件,然后將這些文件拼成一個(gè) dir 格式的鏡像,在這里使用 cp 的方式將鏡像從 registry 存儲(chǔ)目錄里 撈 出來(lái) 😂 

  1. # 首先創(chuàng)建一個(gè)文件夾,為了保留鏡像的 name 和 tag,文件夾的名稱就對(duì)應(yīng)的是 NAME:TAG  
  2. ╭─root@sg-02 /var/lib/registry/docker  
  3. ╰─# mkdir -p skopeo/library/alpine:latest  
  4. ╭─root@sg-02 /var/lib/registry/docker  
  5. ╰─# cp /var/lib/registry/docker/registry/v2/blobs/sha256/39/39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01/data skopeo/library/alpine:latest/manifest 
  6. ╭─root@sg-02 /var/lib/registry/docker  
  7. ╰─# cp /var/lib/registry/docker/registry/v2/blobs/sha256/f7/f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a/data skopeo/library/alpine:latest/f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a 
  8. ╭─root@sg-02 /var/lib/registry/docker  
  9. ╰─# cp /var/lib/registry/docker/registry/v2/blobs/sha256/cb/cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08/data skopeo/library/alpine:latest/cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08 
  10. ╭─root@sg-02 /var/lib/registry/docker  
  11. ╰─# tree skopeo/library/alpine:latest  
  12. skopeo/library/alpine:latest  
  13. ├── cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08  
  14. ├── f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a  
  15. └── manifest  
  16. 0 directories, 3 files 

和上面的 skopeo copy 出來(lái)的 dir 文件夾對(duì)比一下,到此為止鏡像所需要的文件就基本上都齊全了,就差一個(gè) version 文件,這個(gè)文件無(wú)關(guān)緊要可以去掉。

5.  再優(yōu)化一下,將步驟 4 中的 cp 操作修改成硬鏈接操作,能極大減少磁盤的 IO 操作。需要注意,硬鏈接文件不能跨分區(qū),所以要和 registry 存儲(chǔ)目錄在同一個(gè)分區(qū)下才行。 

  1. ╭─root@sg-02 /var/lib/registry/docker  
  2. ╰─# ln /var/lib/registry/docker/registry/v2/blobs/sha256/39/39eda93d15866957feaee28f8fc5adb545276a64147445c64992ef69804dbf01/data skopeo/library/alpine:latest/manifest 
  3. ╭─root@sg-02 /var/lib/registry/docker  
  4. ╰─# ln /var/lib/registry/docker/registry/v2/blobs/sha256/f7/f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a/data skopeo/library/alpine:latest/f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a 
  5. ╭─root@sg-02 /var/lib/registry/docker  
  6. ╰─# ln /var/lib/registry/docker/registry/v2/blobs/sha256/cb/cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08/data skopeo/library/alpine:latest/cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08 
  7. ╭─root@sg-02 /var/lib/registry/docker  
  8. ╰─# tree skopeo/library/alpine:latest  
  9. skopeo/library/alpine:latest  
  10. ├── cbdbe7a5bc2a134ca8ec91be58565ec07d037386d1f1d8385412d224deafca08  
  11. ├── f70734b6a266dcb5f44c383274821207885b549b75c8e119404917a61335981a  
  12. └── manifest  
  13. 0 directories, 3 files 

然后使用 skopeo copy 或者 skopeo sync 將鏡像 push 到 harbor

  •   使用 skopeo copy 
  1. skopeo copy  --insecure-policy --src-tls-verify=false --dest-tls-verify=false \  
  2. dir:skopeo/library/alpine:latest docker://harbor.k8s.li/library/alpine:latest 
  •   使用 skopeo sync

需要注意的是,skopeo sync 的方式是同步 project 級(jí)別的,鏡像的 name 和 tag 就對(duì)應(yīng)的是目錄的名稱 

  1. skopeo sync --insecure-policy --src-tls-verify=false --dest-tls-verify=false \  
  2. --src dir --dest docker skopeo/library/ harbor.k8s.li/library/ 

實(shí)現(xiàn)腳本

大叫一聲 shell 大法好!😂 

  1. #!/bin/bash  
  2. REGISTRY_DOMAIN="harbor.k8s.li"  
  3. REGISTRY_PATH="/var/lib/registry"  
  4. # 切換到 registry 存儲(chǔ)主目錄下  
  5. cd ${REGISTRY_PATH}  
  6. gen_skopeo_dir() {  
  7.    # 定義 registry 存儲(chǔ)的 blob 目錄 和 repositories 目錄,方便后面使用  
  8.     BLOB_DIR="docker/registry/v2/blobs/sha256"  
  9.     REPO_DIR="docker/registry/v2/repositories"  
  10.     # 定義生成 skopeo 目錄  
  11.     SKOPEO_DIR="docker/skopeo"  
  12.     # 通過(guò) find 出 current 文件夾可以得到所有帶 tag 的鏡像,因?yàn)橐粋€(gè) tag 對(duì)應(yīng)一個(gè) current 目錄  
  13.     for image in $(find ${REPO_DIR} -type d -name "current"); do  
  14.         # 根據(jù)鏡像的 tag 提取鏡像的名字 
  15.          name=$(echo ${image} | awk -F '/' '{print $5"/"$6":"$9}')  
  16.         link=$(cat ${image}/link | sed 's/sha256://')  
  17.         mfs="${BLOB_DIR}/${link:0:2}/${link}/data"  
  18.         # 創(chuàng)建鏡像的硬鏈接需要的目錄  
  19.         mkdir -p "${SKOPEO_DIR}/${name}"  
  20.         # 硬鏈接鏡像的 manifests 文件到目錄的 manifest 文件  
  21.         ln ${mfs} ${SKOPEO_DIR}/${name}/manifest.json  
  22.         # 使用正則匹配出所有的 sha256 值,然后排序去重  
  23.         layers=$(grep -Eo "\b[a-f0-9]{64}\b" ${mfs} | sort -n | uniq)  
  24.         for layer in ${layers}; do  
  25.           # 硬鏈接 registry 存儲(chǔ)目錄里的鏡像 layer 和 images config 到鏡像的 dir 目錄  
  26.             ln ${BLOB_DIR}/${layer:0:2}/${layer}/data ${SKOPEO_DIR}/${name}/${layer}  
  27.         done  
  28.     done 
  29.  
  30. sync_image() {  
  31.     # 使用 skopeo sync 將 dir 格式的鏡像同步到 harbor  
  32.     for project in $(ls ${SKOPEO_DIR}); do  
  33.         skopeo sync --insecure-policy --src-tls-verify=false --dest-tls-verify=false \  
  34.         --src dir --dest docker ${SKOPEO_DIR}/${project} ${REGISTRY_DOMAIN}/${project}  
  35.     done 
  36.   
  37. gen_skopeo_dir  
  38. sync_image 

其實(shí)魔改一下 skopeo 的源碼也是可以無(wú)縫支持 registry 存儲(chǔ)目錄的,目前正在研究中 😃

對(duì)比

  方法 適用范圍 缺點(diǎn)
docker retag 兩個(gè) registry 之間同步鏡像  
skopeo 兩個(gè) registry 之間同步鏡像  
解壓目錄 registry 存儲(chǔ)目錄到另一個(gè) registry harbor 1.x
skopeo dir registry 存儲(chǔ)目錄到另一個(gè) registry 適用于 harbor 2.x

對(duì)比總結(jié)一下以上幾種方案:

  • 方案一:上手成本低,適用于鏡像數(shù)量比較多少,無(wú)需安裝 skopeo 的情況,缺點(diǎn)是性能較差。
  • 方案二:適用于兩個(gè) registry 之間同步復(fù)制鏡像,如將 docker hub 中的一些公共鏡像復(fù)制到公司內(nèi)網(wǎng)的鏡像倉(cāng)庫(kù)中。
  • 方案三:適用于鏡像倉(cāng)庫(kù)之間進(jìn)行遷移,性能是所有方案里最好的,需要額外注意的是如果目的鏡像倉(cāng)庫(kù)是 harbor 2.x,是無(wú)法使用這種方式的。
  • 方案四:是方案三的妥協(xié)版,為了適配 harbor 2.0 ,因?yàn)樾枰匦聦㈢R像 push 到 harbor ,所以性能上要比方案三差一些。

 

責(zé)任編輯:龐桂玉 來(lái)源: 奇妙的Linux世界
相關(guān)推薦

2021-09-23 10:30:21

Docker RegiHarborLinux

2022-09-16 10:19:36

HarborContainerd

2021-12-21 15:17:53

Kubernetes緩存Linux

2010-09-15 11:00:03

CaffeineMapReduceBigTable

2024-04-30 10:29:54

Docker存儲(chǔ)C盤

2015-08-07 10:10:18

LinuxDocker容器

2022-09-07 09:19:49

Docker健康檢查

2021-10-20 07:18:51

Harbor鏡像項(xiàng)目

2021-07-15 09:47:20

Docker容器命令

2017-03-24 09:24:21

HarborDocker鏡像倉(cāng)庫(kù)

2019-07-16 14:44:52

DockerMySQL操作系統(tǒng)

2015-08-26 15:11:41

Docker容器備份Docker容器遷移

2022-05-02 17:03:32

容器鏡像ReactJS

2018-11-05 09:23:19

開源Docker容器鏡像

2009-06-19 20:33:53

Linux

2021-05-10 08:58:09

Harbor架構(gòu)Registry 服務(wù)

2012-03-21 09:42:08

PHP

2019-07-15 16:00:24

Docker架構(gòu)容器

2019-07-15 10:00:53

DockerJava容器

2013-08-01 09:29:43

云計(jì)算環(huán)境APP云計(jì)算
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)