You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化大体积docker.tar文件的Docker镜像加载速度?

优化Docker镜像加载速度的Bash方案

问题背景

我有一个44GB的docker.tar文件,包含大量Docker镜像,需完成加载、重打标签后推送到新仓库的流程。目前已通过并行推送将总耗时从40分钟压缩至20分钟,但加载环节仍有优化空间。此前尝试用split拆分tar文件并行执行docker load,因破坏tar内部结构出现头部错误、意外EOF等问题,现寻求基于Bash的可行优化方案。

可行优化方案

1. 在打包阶段拆分单镜像tar包(推荐)

split直接拆分二进制tar文件会破坏其结构,导致加载失败。正确做法是在Jenkins生成镜像包时,将每个镜像单独保存为tar文件,而非合并成单个大tar:

Jenkins端打包脚本示例

# 从内部仓库拉取镜像后,获取所有需保存的镜像列表
IMAGES=$(docker image list --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>")
mkdir -p individual_images

# 逐个保存镜像为单独的tar文件
for img in $IMAGES; do
  # 替换镜像名中的特殊字符作为文件名
  safe_name=$(echo "$img" | tr '/' '_' | tr ':' '-')
  docker save "$img" -o "individual_images/${safe_name}.tar"
done

# 将individual_images目录打包进CSAR,替代原有的单个docker.tar

用户端并行加载脚本

修改原加载脚本,通过xargs控制并发数(根据CPU/存储性能调整,比如8)并行加载单个镜像tar包:

RED="\033[1;31m"
GREEN="\033[1;32m"
NOCOLOR="\033[0m"
IMAGE_DIR=$1
LOG_FILE="docker_load.log"

logger() { 
   echo -e "`date '+%Y-%m-%d %H:%M:%S:'` $@"  | tee -a ${LOG_FILE}
}

logger "Loading images from [$IMAGE_DIR]..."

# 并行加载单个镜像tar包
find "$IMAGE_DIR" -name "*.tar" | xargs -P 8 -I {} docker load --input {}

# 获取所有镜像列表(过滤表头)
LIST_OF_DOCKER_IMAGES=$(docker image list | awk 'NR>1 {print $1":"$2;}')

2. 改用高速压缩算法加速加载

如果需要压缩镜像包,避免使用默认的gzip,改用lz4这类压缩速度更快的算法,可减少打包和解压时间:

Jenkins端压缩打包

for img in $IMAGES; do
  safe_name=$(echo "$img" | tr '/' '_' | tr ':' '-')
  docker save "$img" | lz4 -z -o "individual_images/${safe_name}.tar.lz4"
done

用户端解压加载

find "$IMAGE_DIR" -name "*.tar.lz4" | xargs -P 8 -I {} lz4 -d -c {} | docker load

3. 跳过已存在的镜像避免重复加载

在加载前检查镜像是否已存在,跳过重复加载可节省大量时间,适合多次执行脚本的场景:

编写检查加载脚本check_and_load.sh

#!/bin/bash
tar_file=$1
LOG_FILE="docker_load.log"

RED="\033[1;31m"
GREEN="\033[1;32m"
NOCOLOR="\033[0m"

logger() { 
   echo -e "`date '+%Y-%m-%d %H:%M:%S:'` $@"  | tee -a ${LOG_FILE}
}

# 从tar包的repositories文件中提取镜像名和标签
img_name=$(tar -xf "$tar_file" repositories -O | jq -r 'keys[]')
img_tag=$(tar -xf "$tar_file" repositories -O | jq -r '.[] | keys[]')
full_img="${img_name}:${img_tag}"

if docker image inspect "$full_img" &>/dev/null; then
  logger "Image ${GREEN}$full_img${NOCOLOR} already exists, skipping load."
else
  logger "Loading ${GREEN}$full_img${NOCOLOR} from $tar_file..."
  docker load --input "$tar_file"
fi

并行执行检查加载

chmod +x check_and_load.sh
find "$IMAGE_DIR" -name "*.tar" | xargs -P 8 -I {} ./check_and_load.sh {}

4. 调整Docker守护进程配置

修改Docker配置提升并发处理能力,将镜像存储路径指向SSD等高速存储:

# /etc/docker/daemon.json
{
  "storage-driver": "overlay2",
  "max-concurrent-downloads": 10,
  "max-concurrent-uploads": 10
}

修改后重启Docker:

systemctl restart docker

内容的提问来源于stack exchange,提问作者Kevin Niland

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 23:38:14