阿里云开源 image-syncer 工具,容器镜像迁移同步的终极利器
為什么要做這個工具?
由于阿里云上的容器服務 ACK 在使用成本、運維成本、方便性、長期穩定性上大大超過公司自建自維護 Kubernets 集群,有不少公司紛紛想把之前自己維護 Kubernetes 負載遷移到阿里云 ACK 服務上。在遷移過程中,往往會碰到一個不大不小的坑:那就是怎么把已有的容器鏡像平滑的遷移到阿里云鏡像服務 ACR 上。這個問題看起來非常簡單,如果只有三五個鏡像,只要做一次 docker pull/docker push 就能完成,但實際生產中涉及到成千上百個鏡像,幾 T 的鏡像倉庫數據時,遷移過程就變的耗時非常漫長,甚至丟失數據。
阿里云云原生應用平臺的工程師——也就是我們,發現這是一個通用的需求,用戶會在各種容器鏡像倉庫之間做遷移,或者進一步,期望有同步復制的能力,所以我們研發了 image-syncer 這個項目來支持遷云,并同時開源給業界大眾,用來解決通用的容器鏡像批量遷移/同步的問題。
這個工具在實際生產中,已經幫助了多家客戶進行鏡像遷移,其中最大鏡像倉庫的總量達到 3T 以上,同步時能跑滿機器帶寬,進行同步任務的機器磁盤容量沒有要求。
image-syncer 簡介
如上所述,在 k8s 集群遷移場景中,鏡像倉庫之間進行鏡像遷移/同步是基本需求,而使用 docker pull/push 結合腳本的傳統方式進行鏡像同步,有如下幾個局限性:
image-syncer 的定位是一個簡單、易用的批量鏡像遷移/同步工具,支持幾乎所有目前主流的基于 docker registry V2 搭建的鏡像存儲服務,比如 ACR、Docker
Hub、Quay、自建 Harbor 等,目前已經初步經過了 TB 級別的生產環境鏡像遷移驗證,并開源于 https://github.com/AliyunContainerService/image-syncer ,歡迎大家下載使用以及提供寶貴的建議~
工具特性
image-syncer 的特性如下:
1.支持多對多鏡像倉庫同步
2.支持基于 Docker Registry V2 搭建的 docker 鏡像倉庫服務 (如 Docker Hub、 Quay、 阿里云鏡像服務 ACR、 Harbor等)
3.同步只經過內存和網絡,不依賴磁盤存儲,同步速度快
4.增量同步, 通過對同步過的鏡像 blob 信息落盤,不重復同步已同步的鏡像
5.并發同步,可以通過配置文件調整并發數
6.自動重試失敗的同步任務,可以解決大部分鏡像同步中的網絡抖動問題
7.不依賴 docker 以及其他程序
借助 image-syncer,只需要保證 image-syncer 的運行環境與需要同步的 registry 網絡連通,你可以快速地完成從鏡像倉庫的遷移、拷貝以及增量同步,并且對硬件資源幾乎沒有要求(因為 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可以通過命令行參數以及環境變量配置,參考下面的描述} }用戶可以根據配置不同的鏡像同步規則組合,以匹配不同的遷移/同步需求,如將單個鏡像 repo 同步到多個不同的鏡像 repo、將多個源鏡像同步到單個鏡像 repo 中(以 tag 區分)、在同一個 registry 中以不同的名字拷貝一個鏡像 repo 等等。
使用時需要注意,如果匿名訪問作為同步源的 registry 地址,可能存在權限問題無法 pull 鏡像以及無法獲取 tags,這種情況下需要在" auth “中加入有對應權限的賬號密碼;而如果匿名訪問作為同步目標的 registry 地址,可能存在權限問題無法 push 鏡像,同樣也可能需要用戶提供有對應權限的賬號密碼。
image-syncer 同時支持 insecure 的 registry(類比 docker 的-- insecure - registry 參數,在” auth "的相應條目中添加 " insecure ": true ),可以同時在 http 和 https 兩種類型的鏡像服務之間遷移。
image-syncer 還提供了一些簡單的參數來控制程序的運行,包括并發數目控制、重傳次數設置等等:
在同步結束之后,image-syncer
會統計成功和失敗的同步任務數目(每個同步任務代表一個鏡像),并在標準輸出和日志中打印 “Finished, sync tasks failed, tasks generate failed” 的字樣,從而可以獲得同步的結果。更多FAQ參見 FAQs.md
使用示例
ACR(Alibaba Cloud Container Registry)是阿里云提供的容器鏡像托管服務,支持全球20個地域的鏡像全生命周期管理,聯合容器服務等云產品,打造云原生應用的一站式體驗。這里通過將自建 harbor 上的鏡像同步到 ACR,提供 image-syncer 的基本使用示例
從自建 harbor 同步鏡像到 ACR
1.在阿里云控制臺上開通容器鏡像服務,并進入 ACR 控制臺
2.創建命名空間,默認倉庫類型決定了當倉庫不存在時,docker push 自動創建的倉庫類型是公有的還是私有的;如果部分需要同步的目標倉庫不存在,需要打開自動創建倉庫按鈕,讓類似" docker push "的操作能自動創建倉庫
3.創建訪問憑證,對應的賬號即為 docker login 的賬號,如下圖:
4.上面的操作使用的是主賬號,默認擁有全部權限;為了進行權限管理,我們也可以通過創建 RAM 子賬號,并配置對應權限,這里的場景中我們只使用到了創建、更新鏡像倉庫相關權限,最小權限設置如下,訪問控制的資源粒度為 image-syncer 命名空間:
{"Statement": [{"Effect": "Allow","Action": ["cr:CreateRepository","cr:UpdateRepository","cr:PushRepository","cr:PullRepository"],"Resource": ["acs:cr:*:*:repository/image-syncer/*"]}],"Version": "1" }5.同樣,RAM 賬號需要通過 RAM 用戶登陸入口登陸阿里云控制臺,并進入 ACR 控制臺創建訪問憑證(同3.)
6.然后我們可以通過訪問憑證中創建的密碼,完成如下 image-syncer 的同步配置(配置中使用 RAM 子賬號的訪問憑證);這里我們將本地搭建的 harbor( http 服務,要設置 insecure,通過 harbor.myk8s.paas.com:32080 訪問)中的 library/nginx 倉庫同步到華北2(通過為 registry.cn-beijing.aliyuncs.com 訪問)中的 image-syncer 命名空間下,并且保持倉庫名稱為 nginx,config.json 如下:
{"auth": {"harbor.myk8s.paas.com:32080": {"username": "admin","password": "xxxxxxxxx","insecure": true},"registry.cn-beijing.aliyuncs.com": {"username": "acr_pusher@1938562138124787","password": "xxxxxxxx"}},"images": {"harbor.myk8s.paas.com:32080/library/nginx": ""} }7.下載最新的 image-syncer 可執行文件(目前只支持 linux amd64 版本,可以自行編譯),解壓,并運行工具
執行命令:
# 設置默認目標registry為registry.cn-beijing.aliyuncs.com,默認目標namespace為image-syncer # 并發數為10,重試次數為10 # 日志輸出到./log文件下,不存在會自動創建,不指定的話默認會將日志打印到Stderr # 指定配置文件為harbor-to-acr.json,內容如上所述 ./image-syncer --proc=10 --config=./harbor-to-acr.json --registry=registry.cn-beijing.aliyuncs.com --namespace=image-syncer --retries=10 --log=./log一次同步會經歷三個階段:生成同步任務、執行同步任務以及重試失敗任務;其中,每個同步任務都代表了一個需要同步的 tag (鏡像),如果配置文件中某條規則沒有指定 tag,在“生成同步任務”階段會自動 list 源倉庫所有 tag,并生成對應的同步任務,如果生成同步任務失敗,也會在重試階段進行重試,(故意配錯賬號密碼時)執行輸出如下:
正常運行的輸出:
在運行時,image-syncer 會打印出如下的日志信息:
從自建 harbor 同步鏡像到 ACR 企業版
ACR 企業版提供企業級容器鏡像、Helm Chart 安全托管能力,擁有企業級安全獨享特性,具備千節點鏡像分發、全球多地域同步能力。提供云原生應用交付鏈,實現一次應用變更,全球化多場景自動交付。強烈推薦安全需求高、業務多地域部署、擁有大規模集群節點的企業級客戶使用。
同步到 ACR 企業版和 ACR 普通版所需的操作基本相同:
1.創建 ACR 企業版實例
2.創建命名空間,并對默認倉庫類型進行設置,并打開自動創建倉庫的功能
3.配置公網的訪問控制,需要打開 ACR 企業版的訪問入口,并添加公網白名單,使外部能訪問鏡像服務
4.配置訪問憑證,這部分和 ACR 普通版相同
5.使用訪問憑證中創建的密碼,完成如下 image-syncer 的同步配置;與之前同步到ACR共享版不同的是,每個ACR企業版實例有自己單獨的域名(一個公網可見,一個僅專有網絡可見,如果鏡像同步工具運行在個人環境上需要使用公網域名;如果要使用僅專有網絡可見的域名,則將鏡像同步工具運行在阿里云ECS實例上,并且通過配置使域名對該ECS所在的專有網絡可見;這里使用的是公網域名
ruohe-test-registry.cn-shanghai.cr.aliyuncs.com),并且namespace對于每個不同企業版實例之間來說都是隔離的。我們同樣將本地搭建的 harbor(http 服務,要設置i nsecure,通過 harbor.myk8s.paas.com:32080 訪問)中的 library/nginx 倉庫同步到 ACR 企業版實例中 image-syncer 命名空間下,并且保持倉庫名稱為 nginx,config.json 如下:
6.運行工具
執行命令
輸出與前述相同
更多能力
以上的 image-syncer 滿足了你的容器鏡像遷移同步的所有訴求嗎?如果有更多的需求、甚至想共建更多的能力,歡迎訪問 https://github.com/AliyunContainerService/image-syncer 留下 issue,也歡迎加入 Kubernetes 釘釘群討論
【 Kubernetes 釘釘群二維碼】
開源不易,長期的維護項目更不容易,大家覺得好就請給這個項目點個 star,公司內的老板會看這個項目的 star 數量來決定后續能不能投更多的研發資源來維護這個項目,萬分感謝:)
One More Thing
那么,鏡像倉庫能順利遷移,是否遷云就能順利進行呢?答案是——并沒有那么簡單,倉庫只是遷云過程中碰到的問題之一,還需要解決其他痛點。
對于已經在私有云/公有云上已經把業務應用跑在 k8s 上的用戶來說,如何讓業務在遷云過程中不受影響是頭等大事。阿里云云原生應用平臺的解決方案架構師對此已經有了完善的考慮,力助用戶應用高效穩定的遷移到 ACK 服務上。在幫助這些用戶落實遷云方案的同時,我們也在不斷思考如何把這些案例中共性的東西做一些沉淀,總結出一些優秀的解決方案、最佳實踐以及開發一些工具來幫助用戶快速完成遷云的這件事情,這是我們遷移過程中為用戶考慮到的點
如果你有遷移上阿里云 ACK 的需求,請點擊我!期待你的留言~
總結
以上是生活随笔為你收集整理的阿里云开源 image-syncer 工具,容器镜像迁移同步的终极利器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: containerd 与安全沙箱的 Ku
- 下一篇: 一文看懂 K8s 日志系统设计和实践