概述
用户业务在上云或者云迁移过程中,需要对镜像进行批量迁移。奈何大部分云厂商并未提供镜像批量迁移的工具,导致业务在上云初期,海量镜像迁移耗时耗力。
基于此背景,腾讯云容器专家团队开发了镜像批量迁移工具:image-transfer,并提供多种场景下的最佳实践操作,形成镜像批量迁移一站式解决方案,帮助业务快速安全上云。该工具支持多种镜像迁移场景:
- 不同云厂商之间的镜像迁移。例,从阿里云镜像仓库ACR迁移到腾讯云镜像仓库TCR。
- 开源/自建镜像仓库迁移上云。例,从harbor镜像仓库迁移到腾讯云镜像仓库TCR。
- 腾讯云TCR个人版(CCR)一键迁移至腾讯云镜像仓库企业版TCR
注(最佳实践见文章末尾)
本文首先介绍业务上云/迁移过程中镜像迁移的痛点。随后详细介绍镜像批量迁移工具image-transfer的设计思想,功能模块。最后详细介绍了基于上述三种镜像迁移场景的最佳实践。帮助业务快速迁移上云。
工具已正式开源,项目地址:https://github.com/tkestack/image-transfer
二进制包下载地址:https://github.com/tkestack/image-transfer/releases
业务上云,镜像怎么迁移?
业务上云主要有几种场景,一是自建idc上云,二是第三方云迁移,三是异地灾备,即混合云。这些场景中,无论是上云还是云迁移,迁移流程主要有如下几步。
- 网络规划。vpc配置,子网划分等。
- 数据迁移。对象存储,文件存储等。
- 应用迁移。业务,配置等。
在数据迁移过程中,如果业务大量使用容器化部署,则需要批量镜像迁移。而目前大部分云厂商的镜像仓库服务没有提供镜像仓库批量迁移的能力。业务想要迁移,只能先在本地下载原镜像,修改tag后,再上传至目的镜像仓库。这个过程存在以下几个缺点:
- 耗时耗力。仅仅对于单个镜像迁移,就需要三步操作,并且需要时刻盯着,若出现失败情况,需进一步处理。
- 完全人肉操作,易出现差错。在对原镜像修改tag时,由于是人为修改,极易操作失误,tag修改错了等。
- 镜像量大时,成本增加,上云进度缓慢。如果有几百上千个镜像,这样人肉操作,迁移进度会十分缓慢,且迁移成本会大大增加。
image-transfer的原理
设计目标
针对镜像迁移的痛点。我们希望开发一种镜像批量迁移工具。它对使用者而言,只需要简单的配置,就可以实现镜像批量迁移,无需人工干预,提高业务上云/迁移的进度,降低成本。具体而言,该工具有以下设计目标。
- 配置简单,无需复杂输入。我们希望对使用者而言这个工具是简单易用的,仅需配置源、目的镜像地址和鉴权,即可完成批量迁移。
- 快速高效迁移海量镜像,降低迁移成本。针对大量的镜像迁移需求,我们希望工具可以高效完成,借助高并发的一些技术,实现快速迁移。
- 一定的容错能力,减少人工干预维护。在迁移过程中,我们希望工具可以进行一些错误的识别和自动修复,尽量减少人工维护,提高运维效率。
- 对运行环境没有依赖,提高工具普适性。我们希望工具是可以在任何linux,mac os,windows操作系统中运行,而不用依赖docker及其他程序。
- 支持腾讯云CCR一键全量迁移模式。目前,腾讯云容器镜像服务TCR企业版正式上线,腾讯云TCR个人版(CCR)将在未来逐步减少维护,直到下线。因此工具需要支持CCR仓库一键全量迁移至TCR企业版。
架构
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工具,实现不同场景下的批量镜像迁移。包含场景如下:
- 不同云厂商之间的镜像迁移。例,从阿里云镜像仓库ACR迁移到腾讯云镜像仓库TCR。
- 开源/自建镜像仓库迁移上云。例,从harbor镜像仓库迁移到腾讯云镜像仓库TCR。
- 腾讯云TCR个人版(CCR)一键迁移至腾讯云镜像仓库企业版TCR
工具安装:
首先对工具进行下载编译,有两种方式,一种是直接获取二进制文件,第二种是下载源码编译。
二进制release包下载地址:https://github.com/tkestack/image-transfer/releases
示例采用下载源码编译进行演示:
编译过程也非常简单,进入源码目录,直接make。
代码语言:javascript复制git clone https://github.com/tkestack/image-transfer.git
cd ./image-transfer
make
编译完成后,会在当前目录生成image-transfer二进制文件。即可使用。接下来进行最佳实践演示。
最佳实践之场景一:不同云厂商之间的镜像迁移
以从阿里云镜像仓库ACR迁移到腾讯云镜像仓库TCR为例。
1. 准备腾讯云镜像仓库TCR以及阿里云镜像仓库ACR的访问凭证信息文件:security.yaml
代码语言:javascript复制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访问凭证如下方法获取:
阿里云镜像仓库ACR的访问凭证如下获取:
2. 准备好需要迁移的镜像规则文件:rule.yaml
代码语言:javascript复制sichenzhao/xxx:1.0: grant-test2.tencentcloudcr.com/grantzhao/xxx
该文件是配置需要传输的源镜像和目的镜像。文件规则是:源镜像地址: 目的镜像地址
其中源镜像地址,可以指定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.运行工具
代码语言:javascript复制./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. 运行结果
最后一行
代码语言:javascript复制 ################# Finished, 0 transfer jobs failed, 0 jobs generate failed #################
表示运行成功。
最佳实践之场景二:开源/自建镜像仓库迁移上云
以从开源镜像仓库docker hub迁移到腾讯云镜像仓库TCR为例。
1. 准备docker hub镜像仓库TCR以及腾讯云镜像仓库TCR的访问凭证信息文件:security.yaml
代码语言:javascript复制grant-test2.tencentcloudcr.com:
username: xxx
password: xxx
registry.hub.docker.com:
username: xxx
password: xxx
2. 准备好需要迁移的镜像规则文件:rule.yaml
代码语言:javascript复制sichenzhao/private-test:xxx: grant-test2.tencentcloudcr.com/grantzhao/sichenzhao
3.运行工具
代码语言:javascript复制./image-transfer --routines=5 --securityFile=./security.yaml --ruleFile=./rule.yaml --ns=default
--registry=grant-test.tencentcloudcr.com --retry=2
4. 运行结果
最后一行
代码语言:javascript复制 ################# Finished, 0 transfer jobs failed, 0 jobs generate failed #################
表示运行成功。
最佳实践之场景三:腾讯云TCR个人版(CCR)一键迁移至腾讯云镜像仓库企业版TCR
该场景下的使用方式和上面两种场景稍有不同。主要表现为输入参数的变化。
1. 准备镜像鉴权配置文件 security.yaml
代码语言:javascript复制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信息。
代码语言:javascript复制ccr:
secretId: xxx
secretKey: xxx
tcr:
secretId: xxx
secretKey: xxx
注意:
- 文件格式如上所示,只允许修改secretId和secretKey项。
- 如果没有ccr的secret信息,则会用tcr的代替。相反如果没有tcr的secret信息,也会用ccr的代替。
其中secret信息按如下方式获取:
包含secretid 和secretkey两个信息
3.运行工具
这里的参数输入与上面两种场景略有区别。
代码语言:javascript复制./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. 运行结果
一键批量迁移时间会很久,因为需要把ccr的全部镜像传输到tcr。
最后可以看到,有16个job失败了。工具最后会列出失败的job的源镜像地址和目的镜像地址。对于这些失败的job,去仓库检查后发现,这些job的tag是失效的。因此传输失败。
总结
本文从问题分析,设计目标,原理解析,最佳实践等方面详细介绍了镜像批量迁移工具:image-transfer。欢迎大家贡献源码,也欢迎提issue需求。