如何编写脚本批量将Nexus内所有镜像迁移推送至Harbor仓库
Nexus批量镜像迁移到Harbor实现方案
前置准备
- 本地已安装docker且服务运行正常
- 拥有Nexus和Harbor两个仓库的读写权限账号
- 提前在Harbor创建好用于存放迁移镜像的目标项目
- 两种方式获取待迁移镜像清单:
方式1:手动整理为
image_list.txt文件,每行存一个完整的Nexus镜像地址,示例如下:nexus.domaine.com/nginx:v1.20 nexus.domaine.com/mysql:8.0 nexus.domaine.com/redis:6.2方式2:通过Nexus OpenAPI自动拉取全量镜像清单,无需手动整理
批量迁移脚本实现
1. 基于本地镜像清单的迁移脚本
将提前整理好的image_list.txt和脚本放在同一目录,脚本内容如下:
#!/bin/bash # 按需修改以下配置参数 NEXUS_DOMAIN="nexus.domaine.com" HARBOR_DOMAIN="harbor.domaine.com" HARBOR_PROJECT="project_name" HARBOR_USER="替换为你的Harbor账号" HARBOR_PWD="替换为你的Harbor密码" NEXUS_USER="替换为你的Nexus账号" NEXUS_PWD="替换为你的Nexus密码" # 登录两个私有仓库 echo "开始登录仓库..." docker login -u ${NEXUS_USER} -p ${NEXUS_PWD} ${NEXUS_DOMAIN} docker login -u ${HARBOR_USER} -p ${HARBOR_PWD} ${HARBOR_DOMAIN} # 逐行处理镜像 while read -r image; do # 跳过空行 if [ -z "${image}" ]; then continue fi # 提取镜像名+标签,拼接Harbor目标地址 image_name_tag=${image#${NEXUS_DOMAIN}/} target_image="${HARBOR_DOMAIN}/${HARBOR_PROJECT}/${image_name_tag}" echo "正在处理镜像: ${image}" # 拉取Nexus镜像 docker pull ${image} if [ $? -ne 0 ]; then echo "拉取镜像${image}失败,跳过处理" continue fi # 打Harbor标签 docker tag ${image} ${target_image} # 推送至Harbor docker push ${target_image} if [ $? -eq 0 ]; then echo "镜像${image}推送成功" # 可选:删除本地镜像节省磁盘空间,不需要可以注释以下行 docker rmi ${image} ${target_image} else echo "镜像${image}推送失败" fi done < image_list.txt echo "所有镜像处理完成"
2. 自动获取Nexus镜像清单的扩展逻辑(适配Nexus 3.x)
如果不想手动整理镜像清单,可以在上述脚本开头加入以下逻辑,自动拉取所有镜像地址写入image_list.txt:
# 需提前安装jq工具用于解析json NEXUS_REPO_NAME="替换为你的Nexus Docker仓库名" NEXUS_API_URL="https://${NEXUS_DOMAIN}/service/rest/v1/search?repository=${NEXUS_REPO_NAME}" # 清空旧的镜像清单 > image_list.txt # 处理API分页拉取全量镜像 while [ -n "${NEXUS_API_URL}" ]; do response=$(curl -u ${NEXUS_USER}:${NEXUS_PWD} -s ${NEXUS_API_URL}) # 提取镜像地址写入文件 echo "${response}" | jq -r '.items[] | .name + ":" + .version' | sed "s/^/${NEXUS_DOMAIN}\//" >> image_list.txt # 获取下一页地址 NEXUS_API_URL=$(echo "${response}" | jq -r '.continuationToken' | awk '{if($0!="null") print "https://'${NEXUS_DOMAIN}'/service/rest/v1/search?repository='${NEXUS_REPO_NAME}'&continuationToken="$0; else print ""}') done
注意事项
- 执行脚本前先给脚本赋予执行权限:
chmod +x migrate_images.sh - 镜像量较大时建议后台执行避免终端断开导致任务中断:
nohup ./migrate_images.sh & - 如果仓库用的是HTTP协议而非HTTPS,需要提前在docker配置文件
/etc/docker/daemon.json中添加insecure-registries配置,将两个仓库域名加入列表后重启docker再执行脚本 - 脚本执行完成后可查看输出日志,单独处理拉取/推送失败的镜像
内容的提问来源于stack exchange,提问作者fatima zahra ben yahya
相关产品推荐
相关产品推荐

