注意DockerHub有镜像拉取次数限制:Anonymous and Free Docker Hub users are limited to 100 and 200 container image pull requests per six hours.
匿名未用户每六小时可拉取100次,登录用户每六小时可拉取200次。
脚本
#!/bin/sh
# 设置环境变量
ALIYUN_REGISTRY="镜像仓库地址"
ALIYUN_NAME_SPACE="命名空间"
ALIYUN_REGISTRY_USER="用户名"
ALIYUN_REGISTRY_PASSWORD="密码"
# 文件路径
IMAGES_FILE_PATH="./images.txt"
READY_IMAGE_FILE="./ready_image.txt"
TEMP_IMAGE_FILE="./temp_images.txt"
# 清理上次运行生成的临时文件
echo "清理临时文件..."
rm -f "$TEMP_IMAGE_FILE"
# 重启Docker服务
echo "重启Docker服务..."
sudo service docker restart
# 设置Docker Buildx
echo "设置Docker Buildx..."
docker buildx use default || docker buildx create --use
# 登录阿里云Docker镜像仓库
echo "登录阿里云Docker镜像仓库..."
docker login -u "$ALIYUN_REGISTRY_USER" -p "$ALIYUN_REGISTRY_PASSWORD" "$ALIYUN_REGISTRY" || {
echo "登录失败,请检查用户名和密码。"
exit 1
}
# 检查并创建 ready_image.txt 文件
touch "$READY_IMAGE_FILE"
# 过滤需要处理的镜像,忽略注释行和空行,并进行排序
echo "过滤需要处理的镜像..."
sort "$IMAGES_FILE_PATH" | grep -Ev '^\s*$|^\s*#' | sort > "$TEMP_IMAGE_FILE"
sort "$READY_IMAGE_FILE" -o "$READY_IMAGE_FILE"
# 只保留未处理的镜像
comm -23 "$TEMP_IMAGE_FILE" "$READY_IMAGE_FILE" > "$TEMP_IMAGE_FILE.filtered"
mv "$TEMP_IMAGE_FILE.filtered" "$TEMP_IMAGE_FILE"
# 检查 temp_images.txt 是否为空
if [ ! -s "$TEMP_IMAGE_FILE" ]; then
echo "没有需要处理的镜像。"
exit 0
fi
# 统计待处理的镜像数量
total=$(grep -c . "$TEMP_IMAGE_FILE")
current=0
echo "开始处理未处理的镜像,共计 $total 个镜像..."
while IFS= read -r image_name || [ -n "$image_name" ]; do
current=$((current + 1))
original_name=$image_name
echo "处理镜像 $current/$total: $image_name"
# 拉取镜像
echo "拉取镜像: $image_name"
docker pull "$image_name"
echo "镜像已拉取: $image_name"
# 处理镜像信息
platform=$(echo "$image_name" | awk -F'--platform[ =]' '{print $2}' | awk '{print $1}')
if [ -n "$platform" ] && echo "$platform" | grep -q "/"; then
platform_prefix=$(echo "$platform" | sed 's/\//_/g')_
else
platform_prefix=""
fi
image=$(echo "$image_name" | awk '{print $NF}')
image_name_tag=$(echo "$image" | awk -F'/' '{print $NF}' | awk -F'@' '{print $1}')
image_name=$(echo "$image_name_tag" | awk -F':' '{print $1}')
name_space=$(echo "$image" | awk -F'/' '{print $(NF-1)}')
name_space_prefix=""
if [ -n "${duplicate_images[$image_name]}" ] && [ -n "$name_space" ]; then
name_space_prefix="${name_space}_"
fi
# 构建新镜像标签
new_image="${ALIYUN_REGISTRY}/${ALIYUN_NAME_SPACE}/${platform_prefix}${name_space_prefix}${image_name_tag}"
echo "镜像重命名:$new_image"
# 推送镜像
echo "推送镜像: $new_image"
docker tag "$image" "$new_image"
docker push "$new_image"
echo "镜像已推送: $new_image"
# 清理镜像
echo "清理镜像: $new_image"
docker rmi "$new_image"
echo "镜像已清理: $new_image"
# 记录已处理的镜像
echo "$original_name" >> "$READY_IMAGE_FILE"
echo "完成镜像处理 $current/$total: $image_name"
echo "----------------------------------------"
done < "$TEMP_IMAGE_FILE"
# 清理临时文件
rm -f "$TEMP_IMAGE_FILE"
echo "清理原始镜像"
docker image prune -a -f
echo "所有镜像处理完成,共计 $total 个镜像。"
镜像列表示例
# MySQL
mysql
mysql:5.7
mysql:8