在运维工作中,如何批量将当前目录下所有的 .tar 镜像文件通过 docker load -i 导入到本地 Docker 环境中,并显示进度和结果。
当然可以!以下是一个完整的 Shell 脚本,用于:
- 批量
docker load -i xxx.tar
导入镜像 - 为每个镜像打上指定 Harbor 仓库的标签(tag)
- 推送到 Harbor 镜像仓库
🎯 假设信息(请根据实际情况修改)
- Harbor 地址:
harbor.example.com
- 项目名称:
myproject
- 版本标签:
v3.4.0
(从文件名提取也可自定义) - Harbor 用户名/密码:
admin / Harbor12345
示例:将
alarm-handler-v3.4.0_20250725104119.tar
→ 推送为harbor.example.com/myproject/alarm-handler:v3.4.0
✅ 完整脚本:load_and_push_to_harbor.sh
#!/bin/bash
# ========================================
# 批量导入并推送 Docker 镜像到 Harbor
# 作者: Assistant
# 时间: $(date '+%Y-%m-%d %H:%M')
# ========================================
# 🔧 配置区(请按需修改)
HARBOR_REGISTRY="harbor.example.com" # 替换为你的 Harbor 地址
HARBOR_PROJECT="myproject" # 替换为你的项目名
IMAGE_VERSION="v3.4.0" # 镜像版本标签(可统一设置)
HARBOR_USER="admin" # Harbor 用户名
HARBOR_PASS="Harbor12345" # Harbor 密码(建议使用 token 更安全)
# 统计变量
success_load=0
fail_load=0
success_push=0
fail_push=0
total=0
echo "=========================================="
echo " 开始批量导入并推送到 Harbor"
echo " Registry: $HARBOR_REGISTRY/$HARBOR_PROJECT"
echo " 当前时间: $(date '+%Y-%m-%d %H:%M:%S')"
echo "=========================================="
# 检查是否安装 docker
if ! command -v docker &> /dev/null; then
echo "❌ 错误: docker 未安装或不在 PATH 中。"
exit 1
fi
# 登录 Harbor
echo "🔗 正在登录 Harbor: $HARBOR_REGISTRY"
if docker login "$HARBOR_REGISTRY" -u "$HARBOR_USER" -p "$HARBOR_PASS" > /tmp/docker_login.log 2>&1; then
echo "✅ Harbor 登录成功"
else
echo "❌ Harbor 登录失败,请检查用户名/密码或网络"
cat /tmp/docker_login.log
rm -f /tmp/docker_login.log
exit 1
fi
rm -f /tmp/docker_login.log
# 遍历所有 .tar 文件
for tar_file in *.tar; do
# 跳过无匹配文件
if [ ! -f "$tar_file" ]; then
echo "⚠️ 当前目录没有找到任何 .tar 文件。"
break
fi
total=$((total + 1))
image_base=$(basename "$tar_file" .tar) # 如 alarm-handler-v3.4.0_20250725104119
image_name_part=$(echo "$image_base" | sed -E 's/-v[0-9]+\.[0-9]+\.[0-9]+.*//') # 提取 service 名称
echo
echo "📦 处理文件: $tar_file"
# 1. Load 镜像
echo " ➕ 导入镜像: docker load -i $tar_file"
LOADED_IMAGE=$(docker load -i "$tar_file" 2>/dev/null | grep "Loaded image:" | sed 's/^Loaded image: //')
if [ -z "$LOADED_IMAGE" ]; then
echo " ❌ 导入失败或未识别镜像名"
fail_load=$((fail_load + 1))
continue
else
echo " ✅ 导入成功,镜像名: $LOADED_IMAGE"
success_load=$((success_load + 1))
fi
# 构建目标镜像名
DEST_IMAGE="$HARBOR_REGISTRY/$HARBOR_PROJECT/$image_name_part:$IMAGE_VERSION"
# 2. 打标签
echo " 🏷️ 打标签: $DEST_IMAGE"
if docker tag "$LOADED_IMAGE" "$DEST_IMAGE"; then
echo " ✅ 标签成功"
else
echo " ❌ 打标签失败"
fail_push=$((fail_push + 1))
continue
fi
# 3. 推送到 Harbor
echo " 📤 推送镜像: $DEST_IMAGE"
if docker push "$DEST_IMAGE"; then
echo " ✅ 推送成功"
success_push=$((success_push + 1))
else
echo " ❌ 推送失败"
fail_push=$((fail_push + 1))
fi
done
# 输出统计结果
echo
echo "=========================================="
echo "📊 批量操作完成 summary:"
echo " 总共处理: $total 个文件"
echo " 成功导入: $success_load"
echo " 导入失败: $fail_load"
echo " 成功推送: $success_push"
echo " 推送失败: $fail_push"
echo "=========================================="
# 如果有失败,给出提示
if [ $fail_load -gt 0 ] || [ $fail_push -gt 0 ]; then
echo "💡 建议检查:"
echo " - 镜像文件是否完整(file *.tar)"
echo " - Docker 是否运行(systemctl status docker)"
echo " - Harbor 地址/项目名是否正确"
echo " - 网络是否可达 Harbor"
exit 1
fi
exit 0
🛠 使用方法
- 保存脚本
vim load_and_push_to_harbor.sh
# 粘贴内容后保存
- 修改配置项
HARBOR_REGISTRY="your.harbor.com"
HARBOR_PROJECT="prod/dataexa"
HARBOR_USER="robot\$xxx"
HARBOR_PASS="xxxxx"
🔐 生产环境建议使用 Harbor Robot Account Token 替代明文密码。
- 添加执行权限
chmod +x load_and_push_to_harbor.sh
- 运行脚本
./load_and_push_to_harbor.sh
⚠️ 如果权限不足,可加
sudo
,但注意sudo
下可能无法读取用户配置的 Docker 凭据,推荐用普通用户并加入docker
组。
✅ 示例最终推送效果
原始文件 | 推送后镜像 |
---|---|
alarm-handler-v3.4.0_20250725104119.tar |
harbor.example.com/myproject/alarm-handler:v3.4.0 |
video-handler-v3.4.0_20250725104119.tar |
harbor.example.com/myproject/video-handler:v3.4.0 |
💡 可选增强功能(如需可追加)
- 支持从文件名自动提取版本号(如
v3.4.0
) - 并行推送加速
- 记录日志到文件
- 支持 HTTPS 自签名证书跳过
- 加入
--dry-run
模式预览