在Kubernetes叢集遷移情境中,鏡像倉庫之間進行鏡像遷移和同步是基本需求,image-syncer工具可以解決通用的容器鏡像批量遷移和鏡像同步複製的問題,將已有的容器鏡像平滑地遷移到阿里雲鏡像服務ACR上。本文主要為您介紹如何通過image-syncer工具遷移容器鏡像。
背景資訊
阿里雲上的Container ServiceACK在使用成本、營運成本、方便性、長期穩定性上大大超過雲廠商自建自維護Kubernetes叢集,有不少雲廠商紛紛想把之前自己維護Kubernetes負載遷移到阿里雲ACK服務上。在遷移過程中,當鏡像個數較少時,可以通過docker pull或docker push命令完成鏡像遷移,如果涉及到成千上百個鏡像,甚至幾TB的鏡像倉庫資料時,遷移過程就變得非常漫長,並且可能遺失資料。此時,使用者在各種容器鏡像倉庫之間遷移時,期望有鏡像同步複製的能力。阿里雲開源image-syncer工具具備此能力並已經協助多家雲廠商成功遷移鏡像,其中最大鏡像倉庫的總量達到3TB以上。同步任務時能跑滿機器頻寬,並且對進行同步任務的機器磁碟容量沒有要求。
image-syncer簡介
在Kubernetes叢集遷移情境中,鏡像倉庫之間進行鏡像遷移和鏡像同步複製是基本需求,而使用docker pull或docker push結合指令碼的傳統方式進行鏡像同步,存在以下幾個局限性:
依賴磁碟儲存,需要及時進行本地鏡像的清理,並且落盤造成多餘的時間開銷,難以勝任生產情境中大量鏡像的遷移任務。
依賴Docker程式,Docker Daemon對Pull和Push的並發數進行了嚴格的限制,無法進行高並發同步。
一些功能只能通過HTTP API進行操作,僅使用Docker CLI無法實現,使指令碼變得複雜。
image-syncer的定位是一個簡單、易用的批量鏡像遷移和鏡像同步複製工具,支援幾乎所有目前主流的基於Docker Registry V2搭建的鏡像儲存服務,例如ACR、Docker、Hub、Quay、自建Harbor等,目前已經初步經過了TB層級的生產環境鏡像遷移驗證,詳情請參見image-syncer。
工具特點
image-syncer提供了以下幾項支援:
支援多對多鏡像倉庫同步。
支援基於Docker Registry V2搭建的Docker鏡像倉庫服務
例如,Docker Hub、Quay、 阿里雲鏡像服務ACR、Harbor等。
鏡像同步複製只經過記憶體和網路,不依賴磁碟儲存,同步速度快。
支援增量同步處理。
通過對同步過的鏡像blob資訊落盤,不會對已同步的鏡像進行重複同步。
支援並發同步。
可以通過設定檔調整並發數。
支援自動重試失敗的同步任務,解決大部分鏡像同步中的網路抖動問題。
不依賴Docker以及其他程式。
通過使用image-syncer,只需要保證image-syncer的運行環境與需要同步的registry網路連通,您可以快速地完成從鏡像倉庫的遷移、複製以及增量同步處理,並且image-syncer對硬體資源幾乎沒有要求(因為image-syncer嚴格控制網路連接數目=並發數,所以只有在單個鏡像層過大的情況下,並發數目過大可能會打滿記憶體,記憶體佔用 <= 並發數x最大鏡像層大小)。除了使用重傳機制規避同步過程中可能出現的偶發問題之外,image-syncer會在運行結束時統計最後同步失敗的鏡像個數,並且列印出詳細的日誌,協助使用者定位同步過程中出現的問題。
準備工作
使用image-syncer時,您只需要提供一個設定檔,內容樣本如下:
{
"auth": { // 認證欄位,其中每個對象為一個registry的一個帳號和。
// 密碼;通常,同步源需要具有pull以及訪問tags許可權。
// 同步目標需要擁有push以及建立倉庫許可權,如果沒有提供,則預設匿名訪問。
"quay.io": { // registry的url,需要和下面images中對應registry的url相同。
"username": "xxx", // 使用者名稱,可選。
"password": "xxxxxxxxx", // 密碼,可選。
"insecure": true // registry是否是http服務,如果是,insecure欄位需要為true,預設是false,可選,支援這個選項需要image-syncer版本 > v1.0.1。
},
"registry.cn-beijing.aliyuncs.com": {
"username": "xxx",
"password": "xxxxxxxxx"
},
"registry.hub.docker.com": {
"username": "xxx",
"password": "xxxxxxxxxx"
}
},
"images": {
// 同步鏡像規則欄位,其中一條規則包括一個源倉庫(鍵)和一個目標倉庫(值)。
// 同步的最大單位是倉庫(repo),不支援通過一條規則同步整個namespace以及registry。
// 源倉庫和目標倉庫的格式與docker pull/push命令使用的鏡像url類似(registry/namespace/repository:tag)。
// 源倉庫和目標倉庫(如果目標倉庫不為空白字串)都至少包含registry/namespace/repository。
// 源倉庫欄位不可為空,如果需要將一個源倉庫同步到多個目標倉庫需要配置多條規則。
// 目標倉庫名可以和源倉庫名不同(tag也可以不同),此時同步功能類似於:docker pull + docker tag + docker push。
"quay.io/coreos/kube-rbac-proxy": "quay.io/ruohe/kube-rbac-proxy",
"xxxx":"xxxxx",
"xxx/xxx/xx:tag1,tag2,tag3":"xxx/xxx/xx"
// 當源倉庫欄位中不包含tag時,表示將該倉庫所有tag同步到目標倉庫,此時目標倉庫不能包含tag。
// 當源倉庫欄位中包含tag時,表示只同步源倉庫中的一個tag到目標倉庫,如果目標倉庫中不包含tag,則預設使用源tag。
// 源倉庫欄位中的tag可以同時包含多個(比如"a/b/c:1,2,3"),tag之間通過","隔開,此時目標倉庫不能包含tag,並且預設使用原來的tag。
// 當目標倉庫為空白字串時,會將源鏡像同步到預設registry的預設namespace下,並且repo以及tag與源倉庫相同,預設registry和預設namespace可以通過命令列參數以及環境變數配置。
}
}