精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

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

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

 [[441584]]

Registry

Docker Distribution

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

Harbor

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

docker registry to harbor

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

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

獲取 registry 所有鏡像的列表

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

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

  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ù)人首先想到的辦法,也是最簡單粗暴的方法。就是在一臺機(jī)器上使用 docker pull 下 docker registry 中的所有鏡像,然后再 docker retag 一下,再 docker push 到 harbor 中。

  1. # 假設(shè)其中的一個鏡像為 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 

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

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

方案二:skopeo

在 鏡像搬運(yùn)工 skopeo 初體驗[9] 中介紹過可以使用 skopeo copy 直接從一個 registry 中復(fù)制鏡像原始的 layer 到另一個 registry 中,期間不會涉及鏡像 layer 解壓縮操作。至于性能和耗時,比 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 

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

方案三:遷移存儲目錄

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

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

方案四:

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

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

那么再次邀請我們的 skopeo 大佬出場,在 鏡像搬運(yùn)工 skopeo 初體驗[10] 中提到過 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

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

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

skopeo dir

那么先來看一下 skopeo dir 是什么樣子的?

為了方便測試方案的可行性,先使用 skopeo 命令先從 docker hub 上拉取一個鏡像,并保存為 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 文件對應(yīng)的就是鏡像的 manifests 文件;類型為 ASCII text 的文件正是鏡像的 image config 文件,里面包含著鏡像的元數(shù)據(jù)信息。而另一個 gzip compressed data 文件不就是經(jīng)過 gzip 壓縮過的鏡像 layer 嘛。看一下 manifest 文件的內(nèi)容也再次印證了這個結(jié)論:

  •  鏡像的 config 字段對應(yīng)的正是 e50c909a8df2,而文件類型正是 image.v1+json 文本文件。
  •  鏡像的 layer 字段對應(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 存儲目錄中摳鏡像出來

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

  •   首先要得到鏡像的 manifests 文件,從 manifests 文件中得到所有的 blob 文件。例如對于 registry 存儲目錄中的 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. 通過 repositories/library/alpine/_manifests/tags/latest/current/link 文件得到 manifests 文件的 sha256 值,然后根據(jù)這個 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 目錄下找到與之對應(yīng)的文件,blobs 目錄下對應(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. 使用正則匹配,過濾出 manifests 文件中的所有 sha256 值,這些 sha256 值就對應(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 文件,然后將這些文件拼成一個 dir 格式的鏡像,在這里使用 cp 的方式將鏡像從 registry 存儲目錄里 撈 出來 😂 

  1. # 首先創(chuàng)建一個文件夾,為了保留鏡像的 name 和 tag,文件夾的名稱就對應(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 出來的 dir 文件夾對比一下,到此為止鏡像所需要的文件就基本上都齊全了,就差一個 version 文件,這個文件無關(guān)緊要可以去掉。

5.  再優(yōu)化一下,將步驟 4 中的 cp 操作修改成硬鏈接操作,能極大減少磁盤的 IO 操作。需要注意,硬鏈接文件不能跨分區(qū),所以要和 registry 存儲目錄在同一個分區(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 級別的,鏡像的 name 和 tag 就對應(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/ 

實現(xiàn)腳本

大叫一聲 shell 大法好!😂 

  1. #!/bin/bash  
  2. REGISTRY_DOMAIN="harbor.k8s.li"  
  3. REGISTRY_PATH="/var/lib/registry"  
  4. # 切換到 registry 存儲主目錄下  
  5. cd ${REGISTRY_PATH}  
  6. gen_skopeo_dir() {  
  7.    # 定義 registry 存儲的 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.     # 通過 find 出 current 文件夾可以得到所有帶 tag 的鏡像,因為一個 tag 對應(yīng)一個 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 存儲目錄里的鏡像 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 

其實魔改一下 skopeo 的源碼也是可以無縫支持 registry 存儲目錄的,目前正在研究中 😃

對比

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

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

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

 

責(zé)任編輯:龐桂玉 來源: 奇妙的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

2024-04-30 10:29:54

Docker存儲C盤

2010-09-15 11:00:03

CaffeineMapReduceBigTable

2015-08-07 10:10:18

LinuxDocker容器

2022-09-07 09:19:49

Docker健康檢查

2021-10-20 07:18:51

Harbor鏡像項目

2021-07-15 09:47:20

Docker容器命令

2022-05-02 17:03:32

容器鏡像ReactJS

2015-08-26 15:11:41

Docker容器備份Docker容器遷移

2019-07-16 14:44:52

DockerMySQL操作系統(tǒng)

2018-11-05 09:23:19

開源Docker容器鏡像

2017-03-24 09:24:21

HarborDocker鏡像倉庫

2009-06-19 20:33:53

Linux

2021-05-10 08:58:09

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

2019-07-15 16:00:24

Docker架構(gòu)容器

2019-07-15 10:00:53

DockerJava容器

2012-03-21 09:42:08

PHP

2022-06-27 05:42:28

Redis數(shù)據(jù)遷移
點贊
收藏

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

亚洲精品欧美综合四区| 欧美亚洲激情| 亚洲va国产天堂va久久en| 国产日本一区二区三区| 免费的毛片视频| 日韩在线欧美| 精品国产乱子伦一区| 久在线观看视频| 99re热久久这里只有精品34| 激情综合色综合久久综合| 欧美福利视频在线| 大又大又粗又硬又爽少妇毛片 | 国产精品久久午夜| 91在线看网站| 夜夜爽妓女8888视频免费观看| 午夜久久免费观看| 精品视频久久久久久久| 制服丝袜中文字幕第一页| 午夜激情在线播放| 日韩一区欧美小说| 欧美日韩一区在线播放| 国产丝袜视频在线观看| 欧美亚洲天堂网| 第一av在线| 国产视频一区在线播放| 91丨九色丨国产在线| 国产成人在线播放视频| 91精品综合久久久久久久久久久 | 成人欧美一区二区三区1314 | 欧美禁忌电影| 日韩片之四级片| 波多结衣在线观看| 国产精选在线| 亚洲乱码中文字幕| 亚洲午夜激情| 国产在线91| 99久久免费精品高清特色大片| 国产欧美一区二区三区四区 | 亚洲视频成人| 欧美肥婆姓交大片| 国产精品三区在线观看| 亚洲动漫精品| 亚洲精品二三区| 深田咏美中文字幕| 免费看一区二区三区| 欧美日韩一区二区不卡| av视屏在线播放| 日本天堂在线播放| www.亚洲.com| 久久久久久夜精品精品免费| 国模精品一区二区三区| 黄色av中文字幕| 国产高清在线观看免费不卡| 成人免费在线网址| 影音先锋国产在线| 免费精品视频在线| 国产精品视频xxxx| 日批视频免费观看| 日本最新不卡在线| 国产精品日韩在线一区| 黄色一级视频免费看| 国产日韩免费| 97精品伊人久久久大香线蕉| 日韩精品成人在线| 国产欧美短视频| 97视频免费在线观看| 国产视频91在线| 先锋a资源在线看亚洲| 日本电影亚洲天堂| 免费av中文字幕| 丝袜美腿高跟呻吟高潮一区| 国产精品黄页免费高清在线观看| 国产一级片免费在线观看| 玖玖精品视频| 国产免费一区二区三区在线观看| 一级做a爰片久久毛片16| 精品一区二区三区免费毛片爱| 91在线观看免费高清完整版在线观看| 精品国产乱码一区二区三| 风间由美性色一区二区三区| 精品视频免费观看| 国产系列在线观看| 亚洲视频免费看| 青草青青在线视频| 日本电影欧美片| 欧美精品色综合| 日韩大尺度视频| 亚欧洲精品视频在线观看| 在线观看国产欧美| 劲爆欧美第一页| 国产精品亚洲综合色区韩国| 国产精品久久久久久搜索| 国产三级三级在线观看| 不卡一区二区三区四区| 色噜噜狠狠色综合网| 菠萝菠萝蜜在线观看| 精品欧美国产一区二区三区| 国产精品久久久久aaaa樱花| 欧洲精品码一区二区三区免费看| av在线播放av| 亚洲综合免费观看高清完整版在线| 国产精品久久..4399| 久久久成人av毛片免费观看| 日韩欧美综合一区| 色婷婷在线影院| 欧美伊人影院| 日韩av黄色在线观看| 国产夫妻性生活视频| 久久亚洲精华国产精华液 | 欧美日韩国内| 国产91精品在线播放| 国产成人av免费看| 久久精品一区蜜桃臀影院| 欧美 亚洲 视频| 97精品国产99久久久久久免费| 日韩视频在线一区二区| 亚洲黄色免费视频| 日韩图片一区| 亚洲自拍中文字幕| 18视频免费网址在线观看| 亚洲一区二区三区视频在线播放| 特级丰满少妇一级| 偷拍亚洲色图| 欧美丰满少妇xxxx| 国产精品爽爽久久久久久| 久久蜜桃av一区二区天堂| 手机看片日韩国产| 99久久精品一区二区成人| 日韩大片在线观看视频| 久久精品99国产精| 国模无码大尺度一区二区三区| 美脚丝袜一区二区三区在线观看| 黄页在线观看免费| 91精品福利在线一区二区三区| 亚洲人成人无码网www国产| 亚洲特级毛片| 91久久精品www人人做人人爽| 91大神xh98hx在线播放| 色综合咪咪久久| 美女又爽又黄视频毛茸茸| 精品96久久久久久中文字幕无| 成人淫片在线看| 秋霞成人影院| 欧美日韩精品免费| 手机av在线不卡| 蜜臀av亚洲一区中文字幕| 日本一区二区免费看| 在线能看的av网址| 日韩av在线精品| 天天干天天干天天操| 99久久婷婷国产| av动漫在线看| 伊人久久大香线蕉综合网蜜芽| 91av成人在线| 欧美一区二区少妇| 福利视频一区二区| 中文字字幕码一二三区| 三级黄色在线视频| 影音先锋成人在线电影| 国产色综合天天综合网 | 欧美特黄不卡| 欧美另类xxx| 成人无码一区二区三区| 亚洲一二三级电影| 中文成人无字幕乱码精品区| 99精品免费视频| 久久资源av| 精品视频一区二区三区四区五区| 国产亚洲欧美日韩一区二区| 狠狠躁夜夜躁人人爽视频| 国产精品午夜在线| 精品亚洲视频在线| 欧美日韩免费| 好看的日韩精品视频在线| 女人高潮被爽到呻吟在线观看| 精品亚洲一区二区| 欧美另类高清videos的特点| 最近日韩中文字幕| 在线播放第一页| 国产日韩高清一区二区三区在线| 日韩精品极品视频在线观看免费| 久久亚洲资源中文字| 欧美多人乱p欧美4p久久| 污污视频在线观看网站| 欧美在线制服丝袜| 老女人性淫交视频| 91影院在线观看| 国产又大又黄又粗又爽| 国产一区观看| 日本一区免费| 蜜臀av粉嫩av懂色av| 日韩久久久久| 91麻豆蜜桃| 韩国美女久久| 久久精品久久精品亚洲人| 亚洲黄色小说网| 一本久道久久综合中文字幕| www.av免费| 26uuu另类欧美亚洲曰本| 亚洲欧美视频二区| 亚洲第一区色| 亚洲成色最大综合在线| av成人app永久免费| 国产成人自拍视频在线观看| 超鹏97在线| 一区二区三区久久精品| 精品毛片一区二区三区| 色激情天天射综合网| 国产亚洲精品女人久久久久久| 欧美极品aⅴ影院| 日本道中文字幕| 久久99精品久久久久久动态图 | 最新成人av网站| 日本一区二区三区四区在线观看| 成人搞黄视频| 91老司机精品视频| 日韩精品影片| 久久久综合av| 超碰在线观看免费版| 中文字幕av一区| 青青草视频在线观看| 欧美mv和日韩mv国产网站| 在线观看亚洲一区二区| 欧美日韩美女在线| 免费一级片视频| 亚洲欧洲日韩综合一区二区| 亚洲精品乱码久久久久久久久久久久 | 国产精品亚洲欧美在线播放| 色哟哟国产精品| 日本少妇毛茸茸高潮| 亚洲精品伦理在线| 国产精品精品软件男同| 欧美国产成人精品| 三级网站在线免费观看| 99视频精品在线| 9.1在线观看免费| 国产成人免费视频一区| 国产精品99久久99久久久二8| 2021亚洲天堂| 中文字幕制服丝袜一区二区三区 | 5月婷婷6月丁香| 亚洲国产高清视频| 99在线观看视频免费| 午夜久久久久| 好吊色视频988gao在线观看| 久久综合av| 亚洲一区二区三区加勒比| 欧美日韩激情| 日韩欧美亚洲精品| 成人激情开心网| 亚洲精品日韩在线观看| 成人羞羞网站入口免费| 视频一区二区在线| 精品国产乱码久久久久久果冻传媒| 蜜桃成人免费视频| 国产精品一区二区av交换| 免费久久一级欧美特大黄| 日韩母乳在线| 日韩精品第一页| 久久影院一区| 国产一二三四五| 午夜精品久久久久99热蜜桃导演| 丁香色欲久久久久久综合网| 亚洲性图久久| 日本精品免费在线观看| 日日夜夜精品免费视频| 爱情岛论坛亚洲首页入口章节| 美女网站色91| 北条麻妃亚洲一区| 成人免费视频免费观看| 久久人人爽人人爽人人片| 国产欧美精品在线观看| 日韩激情小视频| 亚洲一区二区三区四区五区中文 | 性欧美成人播放77777| 国产亚洲欧美日韩俺去了| 成人午夜免费影院| 亚洲精品日产精品乱码不卡| 国产欧美日韩另类| 在线精品视频小说1| 97精品久久人人爽人人爽| 欧美大片免费久久精品三p| 欧美天堂在线视频| 国产亚洲欧洲黄色| 尤物在线网址| 欧美自拍大量在线观看| 巨大黑人极品videos精品| 成人18视频| 精品视频久久| 国产亚洲精品久久久久久久| 亚洲欧美日韩国产综合精品二区 | 亚洲深夜视频| 国产精品jizz在线观看麻豆| 中文字幕成人| 九九九久久久| 91成人国产| 黄色片一级视频| 国产毛片精品一区| 97人妻精品一区二区三区免| 国产精品久久综合| 日本五十熟hd丰满| 6080日韩午夜伦伦午夜伦| 手机在线观看毛片| xvideos国产精品| 鲁鲁在线中文| 国产精品一区二区性色av| 99久热这里只有精品视频免费观看| 欧美高清性xxxxhd| 欧美精品二区| 国产精品视频黄色| 成人av资源在线观看| 欧美老女人性生活视频| 亚洲一区二区三区影院| 一道本在线视频| 亚洲老头老太hd| 宅男网站在线免费观看| 2018中文字幕一区二区三区| 久久免费精品| 一卡二卡3卡四卡高清精品视频| 夜夜嗨网站十八久久| 四虎成人在线播放| 欧美国产一区二区| 日韩伦人妻无码| 日韩午夜精品视频| 在线观看a视频| 日本精品性网站在线观看| 成人另类视频| 伊人久久在线观看| 久久99久久99| 免费一级suv好看的国产网站| 色哟哟一区二区| 性xxxx18| 91极品女神在线| 亚洲天堂av资源在线观看| 中文字幕色一区二区| 欧美aⅴ一区二区三区视频| 欧美图片一区二区| 精品国产999| 亚洲欧美丝袜中文综合| 亚洲国产精品精华液ab| 波多野结衣影院| 亚洲已满18点击进入久久| 96亚洲精品久久久蜜桃| 亚洲午夜未删减在线观看 | 国产无套精品一区二区三区| 亚洲男同1069视频| 国产精品探花视频| 久久影院模特热| 日本精品一区二区三区在线观看视频| 亚洲日本无吗高清不卡| 免费不卡在线观看| jizzjizzjizz国产| 777亚洲妇女| xvideos国产在线视频| 成人网页在线免费观看| 久久久久久久久国产一区| 日本肉体xxxx裸体xxx免费| 国产精品久久国产精麻豆99网站| 中文字幕乱码无码人妻系列蜜桃| 在线视频亚洲欧美| 看片一区二区| 久久免费一级片| 成人丝袜视频网| 少妇一级淫片免费放中国| 亚洲女人天堂av| 8av国产精品爽爽ⅴa在线观看| 亚洲一区二区在| 国产美女在线精品| 国产一级大片在线观看| 日韩av在线免费| 国产 日韩 欧美一区| 亚洲v国产v在线观看| 激情综合色综合久久| 久久免费精彩视频| 日韩av在线不卡| 99只有精品| 日本黄网站色大片免费观看| 国产成人欧美日韩在线电影| 91看片在线播放| 在线观看不卡av| 日韩亚洲精品在线观看| 美女日批免费视频| 中文字幕av一区二区三区| www.久久久久久| 4444欧美成人kkkk| 91偷拍一区二区三区精品| 野花视频免费在线观看| 亚洲国产中文字幕在线视频综合| 欧美女优在线| 国产人妖伪娘一区91| 激情久久五月| 91激情视频在线观看| 日韩三级.com| 91成人在线| 尤物av无码色av无码| 国产精品理论在线观看| 亚洲不卡免费视频| 日韩美女毛茸茸| 欧美国产高清| 变态另类ts人妖一区二区|