鏡像批量遷移利器:image-transfer

概述

用戶業務在上雲或者雲遷移過程中,需要對鏡像進行批量遷移。基於此背景,騰訊雲容器專家團隊開發了鏡像批量遷移工具:image-transfer。該工具支持多種雲廠商鏡像倉庫之間的批量遷移,同時支持騰訊雲鏡像倉庫 TCR 個人版 CCR 一鍵全量遷移至騰訊雲鏡像倉庫企業版 TCR。
本文首先介紹業務上雲/遷移過程中鏡像遷移的痛點。隨後詳細介紹鏡像批量遷移工具 image-transfer 的設計思想,功能模塊以及最佳實踐。
工具已正式開源,項目地址:https://github.com/tkestack/image-transfer

二進制包下載地址:https://github.com/tkestack/image-transfer/releases

業務上雲,鏡像怎麼遷移?

業務上雲主要有幾種場景,一是自建 idc 上雲,二是第三方雲遷移,三是異地災備,即混合雲。這些場景中,無論是上雲還是雲遷移,遷移流程主要有如下幾步。

  1. 網絡規劃。vpc 配置,子網劃分等。
  2. 數據遷移。對象存儲,文件存儲等。
  3. 應用遷移。業務,配置等。

在數據遷移過程中,如果業務大量使用容器化部署,則需要批量鏡像遷移。而目前大部分雲廠商的鏡像倉庫服務沒有提供鏡像倉庫批量遷移的能力。業務想要遷移,只能先在本地下載原鏡像,修改 tag 後,再上傳至目的鏡像倉庫。這個過程存在以下幾個缺點:

  • 耗時耗力。僅僅對於單個鏡像遷移,就需要三步操作,並且需要時刻盯着,若出現失敗情況,需進一步處理。
  • 完全人肉操作,易出現差錯。在對原鏡像修改 tag 時,由於是人爲修改,極易操作失誤,tag 修改錯了等。
  • 鏡像量大時,成本增加,上雲進度緩慢。如果有幾百上千個鏡像,這樣人肉操作,遷移進度會十分緩慢,且遷移成本會大大增加。

image-transfer 的原理

設計目標

針對鏡像遷移的痛點。我們希望開發一種鏡像批量遷移工具。它對使用者而言,只需要簡單的配置,就可以實現鏡像批量遷移,無需人工干預,提高業務上雲/遷移的進度,降低成本。具體而言,該工具有以下設計目標。

  1. 配置簡單,無需複雜輸入。我們希望對使用者而言這個工具是簡單易用的,僅需配置源、目的鏡像地址和鑑權,即可完成批量遷移。

  2. 快速高效遷移海量鏡像,降低遷移成本。針對大量的鏡像遷移需求,我們希望工具可以高效完成,藉助高併發的一些技術,實現快速遷移。

  3. 一定的容錯能力,減少人工干預維護。在遷移過程中,我們希望工具可以進行一些錯誤的識別和自動修復,儘量減少人工維護,提高運維效率。

  4. 對運行環境沒有依賴,提高工具普適性。我們希望工具是可以在任何 linux,mac os,windows 操作系統中運行,而不用依賴 docker 及其他程序。

  5. 支持騰訊雲 CCR 一鍵全量遷移模式。目前,騰訊雲容器鏡像服務 TCR 企業版正式上線,騰訊雲 TCR 個人版(CCR)將在未來逐步減少維護,直到下線。因此工具需要支持 CCR 倉庫一鍵全量遷移至 TCR 企業版。

  6. 支持自定義 qps 限速。批量遷移鏡像,頻繁的調用鏡像倉庫接口有可能導致鏡像倉庫崩潰,因此需要對 qps 進行限制。

架構

image-transfer 由多個模塊構成,下圖給出了 image-transfer 架構圖。

鏡像批量遷移利器:image-transfer

  • 通用模式輸入(默認):用於接受用戶下發的鏡像遷移任務。包括鏡像遷移配置文件和鑑權配置文件。該模式用於實現雲廠商之間的鏡像遷移。

  • CCR 一鍵遷移模式輸入:需要在工具輸入參數添加 --ccrToTcr=true,該模式用於 CCR 倉庫一鍵全量遷移至 TCR 企業版。除了添加 --ccrToTcr=true 參數,還需鑑權配置文件和騰訊雲 secret 配置文件。

  • pipeline:該模塊是工具處理鏡像遷移的核心。負責處理用戶下發的鏡像遷移任務,包括根據遷移配置文件處理鏡像倉庫的同步規則,以及進行鏡像的分層拉取和傳輸任務。模塊採用了高併發的 pipeline 模型,提高遷移速度。

  • 重試 task:這個階段會重試 pipeline 中傳輸失敗的任務。重試次數可根據用戶輸入參數而定,默認爲 2 次。

Pipeline

由於工具採用 golang 語言編寫,因此核心處理模塊採用了 go 的 pipeline 高併發模型。整個 pipeline 模塊分爲三個小模塊。

多協程處理鏡像倉庫同步規則

這裏是對用戶輸入的鏡像遷移配置文件進行處理解析,獲取每一個需要傳輸的源鏡像地址(包括 repo 和 tag),以及對應的目的鏡像地址。然後針對每個源鏡像地址和目的鏡像地址組成一個 job。如果鏡像配置文件中沒有指定源鏡像的 tag,則會拉取該 repo 下的所有 tag,再針對每個 tag,組成一個 job。這個過程採用 golang 的多協程方式處理,增加處理速度。協程數量可由用戶在輸入參數指定 --proc,默認是 5 個。每個 job 組成後,會被放入task channel 中,等待被消費。

Task傳輸通道

task 通道可看作一個簡易中間件,由 golang 的 channel 實現,每個 job 被生產後,會被放入該 channel 中,等待被消費。該設計可以保證生產者生產出 job 就會立即被放入消費線,一旦消費端有空閒,即可進行消費處理。提高 job 處理效率。

多協程處理 task

這些協程就是 job 的消費端。拿到 job 後,會首先拉去 job 中源地址的 manifest,判斷是否爲多 manifest 鏡像,接着對每個 blob 進行拉取,再將 blob 傳輸到目的地址,最後再將 manifest 傳輸到目的地址,整個過程都是利用緩存,數據不落盤,提高效率。這個過程採用 golang 的多協程方式處理,增加處理速度。協程數量可由用戶在輸入參數指定 --routines,默認是 5 個。

鏡像遷移最佳實踐

本節將介紹如何利用 image-transfer 工具,實現不同場景下的批量鏡像遷移。包含場景如下:

  1. 不同雲廠商之間的鏡像遷移。例,從阿里雲鏡像倉庫 ACR 遷移到騰訊雲鏡像倉庫 TCR。

  2. 開源/自建鏡像倉庫遷移上雲。例,從 harbor 鏡像倉庫遷移到騰訊雲鏡像倉庫 TCR。

  3. 騰訊雲 TCR 個人版 (CCR) 一鍵遷移至騰訊雲鏡像倉庫企業版 TCR。

工具安裝:

首先對工具進行下載編譯,有兩種方式,一種是直接獲取二進制文件,第二種是下載源碼編譯。

二進制 release 包下載地址:

https://github.com/tkestack/image-transfer/releases

示例採用下載源碼編譯進行演示:

編譯過程也非常簡單,進入源碼目錄,直接 make。

git clone https://github.com/tkestack/image-transfer.git
cd ./image-transfer
make

編譯完成後,會在當前目錄生成 image-transfer 二進制文件。即可使用。接下來進行最佳實踐演示。

最佳實踐之場景一:不同雲廠商之間的鏡像遷移

以從阿里雲鏡像倉庫 ACR 遷移到騰訊雲鏡像倉庫 TCR 爲例。

1. 準備騰訊雲鏡像倉庫 TCR 以及阿里雲鏡像倉庫 ACR 的訪問憑證信息文件:auth.json
   grant-test.tencentcloudcr.com:
   username: xxx
   password: xxx
   grant-test2.tencentcloudcr.com:
   username: xxx
   password: xxx
   registry.cn-hangzhou.aliyuncs.com:
   username: xxx
   password: xxx
   ccr.ccs.tencentyun.com:
   username: xxx
   password: xxx
   registry.hub.docker.com:
   username: xxx
   password: xxx

配置很簡單,輸入需要訪問源鏡像倉庫地址,和目的鏡像倉庫地址。並輸入對應鏡像倉庫的用戶名和密碼即可。

其中 insecure 表示,registry 是否是 http 服務,如果是,insecure 字段需要爲 true,默認是 false,可選。

而目的鏡像倉庫的用戶需要擁有 push 以及創建倉庫權限,如果沒有提供,則默認匿名訪問。

其中騰訊雲 TCR 訪問憑證如下方法獲取:
image.png
阿里雲鏡像倉庫 ACR 的訪問憑證如下獲取:
image.png


2. 準備好需要遷移的鏡像規則文件:rule.yaml
registry.cn-hangzhou.aliyuncs.com/grantzhao/sichenzhao:xx": "grant-test.tencentcloudcr.com/grantzhao/sichenzhao

該文件是配置需要傳輸的源鏡像和目的鏡像。文件規則是:源鏡像地址: 目的鏡像地址
其中源鏡像地址,可以指定 tag,也可以不指定 tag,也可以指定多個 tag。
指定單個 tag 時:目的地址可以包含 tag,也可以不包含。不包含 tag 時則使用源鏡像的 tag。
不指定 tag 時:目的地址必須包含 tag。
指定多個 tag 時:多 tag 之間用英文逗號隔開,比如 grant-test.tencentcloudcr.com/grantzhao/sichenzhao:1.0,2.0,3.0。此時目的地址不能包含 tag,默認使用源地址的 tag。



3. 運行工具
   ./image-transfer --routines=5 --securityFile=./security.yaml --ruleFile=./rule.yaml --ns=default \
   --registry=grant-test.tencentcloudcr.com --retry=2 --qps=100

參數解釋:

--ns 指定了一個默認的 ns,若目的倉庫的 ns 爲空,則由該默認的 ns 代替。

--registry指定了一個默認的 registry,若目的倉庫的 registry 爲空,則由該默認的 registry 代替。

--routines=5,表示設置併發數爲 5。默認爲 5。

--retry=2,表示失敗後的重試次數爲 2,默認爲 2。

--securityFile,指定鑑權文件。

--ruleFile,指定鏡像倉庫配置文件。

--qps,限制請求的 qps 不高於100/s。

4. 運行結果

鏡像批量遷移利器:image-transfer
最後一行

################# Finished, 0 transfer jobs failed, 0 jobs generate failed #################

表示運行成功。

最佳實踐之場景二:開源/自建鏡像倉庫遷移上雲

以從開源鏡像倉庫 docker hub 遷移到騰訊雲鏡像倉庫 TCR 爲例。

1. 準備 docker hub 以及騰訊雲鏡像倉庫 TCR 的訪問憑證信息文件:security.yaml
   grant-test2.tencentcloudcr.com:
   username: xxx
   password: xxx
   registry.hub.docker.com:
   username: xxx
   password: xxx
2. 準備好需要遷移的鏡像規則文件:image.json
   sichenzhao/private-test:xxx": "grant-test2.tencentcloudcr.com/grantzhao/sichenzhao
3. 運行工具
   ./image-transfer --routines=5 --securityFile=./security.yaml --ruleFile=./rule.yaml --ns=default \
   --registry=grant-test.tencentcloudcr.com --retry=2
4. 運行結果

鏡像批量遷移利器:image-transfer
最後一行

################# Finished, 0 transfer jobs failed, 0 jobs generate failed #################

表示運行成功。

最佳實踐之場景三:騰訊雲 TCR 個人版(CCR)一鍵遷移至騰訊雲鏡像倉庫企業版 TCR

該場景下的使用方式和上面兩種場景稍有不同。主要表現爲輸入參數的變化。

1. 準備鏡像鑑權配置文件 security.yaml
   grant-test.tencentcloudcr.com:
   username: xxx
   password: xxx
   grant-test2.tencentcloudcr.com:
   username: xxx
   password: xxx
   ccr.ccs.tencentyun.com:
   username: xxx
   password: xxx
2. 準備騰訊雲 secret 配置文件 secret.yaml

對於 TCR 的一鍵遷移模式,不需倉庫的用戶名和密碼作爲訪問鑑權,而是通過騰訊雲的 secret 信息。

   ccr:
   secretId: xxx
   secretKey: xxx
   tcr:
   secretId: xxx
   secretKey: xxx

注意:
文件格式如上所示,只允許修改 secretId 和 secretKey 項。

如果沒有 ccr 的 secret 信息,則會用 tcr 的代替。相反如果沒有 tcr 的 secret 信息,也會用 ccr 的代替。

其中 secret 信息按如下方式獲取:
image.png
包含 secretid 和 secretkey 兩個信息

3. 運行工具

這裏的參數輸入與上面兩種場景略有區別。

   ./image-transfer --ccrToTcr=true --routines=5 --securityFile=./security.yaml --secretFile=./secret.yaml --tcrName=tcr-test \
   --retry=3 --tcrRegion=ap-guangzhou --ccrRegion=ap-guangzhou --qps=3000

參數解釋:

--ccrToTcr=true,表示開啓 TCR 一鍵全量遷移模式。

--secretFile,提供 secret.yaml 配置文件。

--tcrName=tcr-test,指定目的 tcr 倉庫的名字。

--tcrRegion,指定目的 tcr 倉庫所在的地域。

--ccrRegion,指定源 ccr 倉庫所在的地域。

4. 運行結果

鏡像批量遷移利器:image-transfer

一鍵批量遷移時間會很久,因爲需要把 ccr 的全部鏡像傳輸到 tcr。

最後可以看到,有 16 個 job 失敗了。工具最後會列出失敗的 job 的源鏡像地址和目的鏡像地址。對於這些失敗的 job,去倉庫檢查後發現,這些 job 的 tag 是失效的。因此傳輸失敗。

總結

本文從問題分析,設計目標,原理解析,最佳實踐等方面詳細介紹了鏡像批量遷移工具:image-transfer。歡迎大家貢獻源碼,也歡迎提 issue 需求。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章