惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - 仙守

用audit审计去记录谁用了docker docker容器大小使用限制 docker容器的磁盘使用进行限额 sentry私有化部署: 在8c16g上降低资源使用 私有化部署sentry: 获取dsn 私有化部署sentry:卷备份及恢复 私有化部署sentry:镜像构建 docker拉取代理脚本 vscode密钥从windows连接远程linux 基于docker构建es集群 在es中进行update+upsert milvus遍历查询全部数据 简单剖析qwen-agent回答是怎么获取tool的 一个中转代码,底层调用openai,上层模拟openai 一个小工具识别哪个docker占用gpu NLP之预训练语言模型BERT NLP之预训练语言模型GPT NLP之引言 [推荐系统]粗排之FSCD
docker 保存所有镜像
仙守 · 2026-02-06 · via 博客园 - 仙守
  1. 最简单的方法:使用 docker save 和 xargs
# 方法一:直接打包所有镜像
docker save $(docker images -q) -o all_images.tar

# 方法二:包含标签信息
docker save $(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>") -o all_images.tar

# 方法三:包含所有,包括没有标签的镜像
docker images --format "{{.Repository}}:{{.Tag}}" | xargs docker save -o all_images.tar
  1. 更安全的脚本:处理镜像名称中的特殊字符
#!/bin/bash
# save-all-images.sh

# 设置输出文件名
OUTPUT_FILE="all_docker_images_$(date +%Y%m%d_%H%M%S).tar"

echo "开始收集所有镜像..."

# 获取所有镜像列表,处理特殊字符
IMAGE_LIST=()
while IFS= read -r line; do
    # 跳过空行和表头
    if [[ -n "$line" && ! "$line" =~ ^REPOSITORY ]]; then
        # 提取镜像名和标签
        repo_tag=$(echo "$line" | awk '{print $1":"$2}')
        # 跳过 <none>:<none>
        if [[ "$repo_tag" != "<none>:<none>" ]]; then
            IMAGE_LIST+=("$repo_tag")
        fi
    fi
done < <(docker images)

# 如果镜像列表为空
if [ ${#IMAGE_LIST[@]} -eq 0 ]; then
    echo "没有找到任何镜像"
    exit 1
fi

echo "找到 ${#IMAGE_LIST[@]} 个镜像:"
printf '%s\n' "${IMAGE_LIST[@]}"

echo "正在打包到 $OUTPUT_FILE ..."

# 方法A:逐个打包再合并(适用于大量镜像)
if false; then
    # 创建临时目录
    TEMP_DIR=$(mktemp -d)
    echo "使用临时目录: $TEMP_DIR"
    
    # 逐个保存镜像
    for image in "${IMAGE_LIST[@]}"; do
        echo "保存: $image"
        # 替换特殊字符作为文件名
        safe_name=$(echo "$image" | tr '/:' '_-')
        docker save "$image" -o "$TEMP_DIR/${safe_name}.tar"
    done
    
    # 合并所有tar文件
    tar -cf "$OUTPUT_FILE" -C "$TEMP_DIR" .
    
    # 清理临时文件
    rm -rf "$TEMP_DIR"
else
    # 方法B:一次性保存(推荐,但可能命令行过长)
    docker save "${IMAGE_LIST[@]}" -o "$OUTPUT_FILE"
fi

# 验证文件
echo "打包完成!"
echo "文件大小: $(du -h "$OUTPUT_FILE" | cut -f1)"
echo "文件信息:"
file "$OUTPUT_FILE"
  1. 高级脚本:包含分层保存和验证
#!/bin/bash
# docker-save-all.sh

set -e

# 配置
BACKUP_DIR="${BACKUP_DIR:-/tmp/docker-backup}"
OUTPUT_FILE="${BACKUP_DIR}/docker-images-$(date +%Y%m%d-%H%M%S).tar"
LOG_FILE="${BACKUP_DIR}/backup-$(date +%Y%m%d-%H%M%S).log"

# 创建备份目录
mkdir -p "$BACKUP_DIR"

echo "========================================" | tee -a "$LOG_FILE"
echo "Docker 镜像备份开始: $(date)" | tee -a "$LOG_FILE"
echo "========================================" | tee -a "$LOG_FILE"

# 1. 获取镜像列表
echo "1. 获取镜像列表..." | tee -a "$LOG_FILE"
IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>")
IMAGE_COUNT=$(echo "$IMAGES" | wc -l)

echo "找到 $IMAGE_COUNT 个镜像" | tee -a "$LOG_FILE"
echo "$IMAGES" | tee -a "$LOG_FILE"

if [ "$IMAGE_COUNT" -eq 0 ]; then
    echo "没有镜像需要备份" | tee -a "$LOG_FILE"
    exit 0
fi

# 2. 保存镜像列表到文件(用于恢复时参考)
echo "$IMAGES" > "${BACKUP_DIR}/image-list.txt"

# 3. 获取镜像详细信息
echo "2. 获取镜像详细信息..." | tee -a "$LOG_FILE"
docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.Size}}" > "${BACKUP_DIR}/image-details.txt"

# 4. 打包所有镜像
echo "3. 开始打包镜像..." | tee -a "$LOG_FILE"
echo "输出文件: $OUTPUT_FILE" | tee -a "$LOG_FILE"

start_time=$(date +%s)

# 使用 tee 命令同时输出到文件和屏幕
{
    echo "开始保存镜像..."
    docker save $(echo "$IMAGES") -o "$OUTPUT_FILE"
} 2>&1 | tee -a "$LOG_FILE"

end_time=$(date +%s)
duration=$((end_time - start_time))

# 5. 验证打包结果
echo "4. 验证打包文件..." | tee -a "$LOG_FILE"
if [ -f "$OUTPUT_FILE" ]; then
    file_size=$(du -h "$OUTPUT_FILE" | cut -f1)
    echo "文件大小: $file_size" | tee -a "$LOG_FILE"
    
    # 检查tar文件是否有效
    if tar -tf "$OUTPUT_FILE" &>/dev/null; then
        echo "✓ Tar 文件格式正确" | tee -a "$LOG_FILE"
        tar_count=$(tar -tf "$OUTPUT_FILE" | grep "manifest.json" | wc -l)
        echo "包含 $tar_count 个镜像" | tee -a "$LOG_FILE"
    else
        echo "✗ Tar 文件损坏" | tee -a "$LOG_FILE"
        exit 1
    fi
else
    echo "✗ 输出文件不存在" | tee -a "$LOG_FILE"
    exit 1
fi

echo "========================================" | tee -a "$LOG_FILE"
echo "备份完成!" | tee -a "$LOG_FILE"
echo "总耗时: ${duration}秒" | tee -a "$LOG_FILE"
echo "输出文件: $OUTPUT_FILE" | tee -a "$LOG_FILE"
echo "日志文件: $LOG_FILE" | tee -a "$LOG_FILE"
echo "镜像列表: ${BACKUP_DIR}/image-list.txt" | tee -a "$LOG_FILE"
echo "镜像详情: ${BACKUP_DIR}/image-details.txt" | tee -a "$LOG_FILE"
echo "========================================" | tee -a "$LOG_FILE"
  1. 批量处理大量镜像的优化版本
#!/bin/bash
# save-docker-images-batch.sh

# 配置
MAX_ARGS=20  # 每次传递的最大镜像数,避免参数过长
OUTPUT_BASE="docker-images-backup"

# 创建备份目录
BACKUP_DIR="${OUTPUT_BASE}-$(date +%Y%m%d_%H%M%S)"
mkdir -p "$BACKUP_DIR"

echo "备份目录: $BACKUP_DIR"

# 获取所有镜像
mapfile -t IMAGES < <(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>")
TOTAL=${#IMAGES[@]}

echo "总共 $TOTAL 个镜像需要备份"

# 分批处理
BATCH=0
for ((i=0; i<TOTAL; i+=MAX_ARGS)); do
    BATCH=$((BATCH+1))
    END_INDEX=$((i+MAX_ARGS))
    if [ $END_INDEX -gt $TOTAL ]; then
        END_INDEX=$TOTAL
    fi
    
    # 获取当前批次的镜像
    BATCH_IMAGES=("${IMAGES[@]:i:MAX_ARGS}")
    
    echo "处理第 $BATCH 批: ${#BATCH_IMAGES[@]} 个镜像"
    echo "镜像列表: ${BATCH_IMAGES[*]}"
    
    # 保存当前批次
    OUTPUT_FILE="$BACKUP_DIR/batch-${BATCH}.tar"
    docker save "${BATCH_IMAGES[@]}" -o "$OUTPUT_FILE"
    
    # 验证
    if [ -s "$OUTPUT_FILE" ]; then
        size=$(du -h "$OUTPUT_FILE" | cut -f1)
        echo "✓ 批次 $BATCH 完成: $size"
    else
        echo "✗ 批次 $BATCH 失败"
    fi
done

# 创建合并脚本
cat > "$BACKUP_DIR/load-all.sh" << 'EOF'
#!/bin/bash
echo "加载所有Docker镜像..."
for tar_file in batch-*.tar; do
    echo "加载: $tar_file"
    docker load -i "$tar_file"
done
echo "完成!"
EOF

chmod +x "$BACKUP_DIR/load-all.sh"

# 创建恢复说明
cat > "$BACKUP_DIR/README.txt" << EOF
Docker 镜像备份
备份时间: $(date)
镜像总数: $TOTAL
批次数量: $BATCH

恢复方法:
1. 将所有 batch-*.tar 文件复制到目标机器
2. 运行: ./load-all.sh
3. 或者逐个加载: docker load -i batch-*.tar

镜像列表:
$(printf '%s\n' "${IMAGES[@]}")
EOF

echo "备份完成! 目录: $BACKUP_DIR"
echo "恢复时请运行: cd '$BACKUP_DIR' && ./load-all.sh"
  1. 压缩版本(节省空间)
# 直接打包并压缩
docker save $(docker images -q) | gzip > all_images.tar.gz

# 或者使用并行压缩(更快)
docker save $(docker images -q) | pigz -9 > all_images.tar.gz

# 完整脚本
#!/bin/bash
OUTPUT="docker-images-$(date +%Y%m%d).tar.gz"
echo "打包并压缩所有镜像到 $OUTPUT ..."
docker save $(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>") | gzip -c > "$OUTPUT"
echo "完成! 文件大小: $(du -h $OUTPUT | cut -f1)"
  1. 恢复所有镜像
# 从tar文件恢复所有镜像
docker load -i all_images.tar

# 如果使用gzip压缩
gunzip -c all_images.tar.gz | docker load

# 或者
docker load < all_images.tar.gz

# 从分批次备份恢复
for tar_file in batch-*.tar; do
    echo "Loading $tar_file..."
    docker load -i "$tar_file"
done
  1. 一键备份和恢复脚本
#!/bin/bash
# docker-backup-manager.sh

ACTION="$1"
BACKUP_FILE="${2:-docker-images-backup.tar}"

case "$ACTION" in
    "save"|"backup"|"export")
        echo "备份所有Docker镜像到 $BACKUP_FILE ..."
        IMAGES=$(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>")
        if [ -z "$IMAGES" ]; then
            echo "没有找到任何镜像"
            exit 1
        fi
        
        echo "备份以下镜像:"
        echo "$IMAGES"
        
        docker save $IMAGES -o "$BACKUP_FILE"
        
        echo "备份完成!"
        echo "文件大小: $(du -h $BACKUP_FILE | cut -f1)"
        ;;
        
    "load"|"restore"|"import")
        if [ ! -f "$BACKUP_FILE" ]; then
            echo "错误: 备份文件 $BACKUP_FILE 不存在"
            exit 1
        fi
        
        echo "从 $BACKUP_FILE 恢复Docker镜像..."
        docker load -i "$BACKUP_FILE"
        echo "恢复完成!"
        ;;
        
    "list")
        echo "当前Docker镜像:"
        docker images --format "table {{.Repository}}\t{{.Tag}}\t{{.ID}}\t{{.CreatedAt}}\t{{.Size}}"
        ;;
        
    "info")
        if [ -f "$BACKUP_FILE" ]; then
            echo "备份文件信息:"
            echo "大小: $(du -h $BACKUP_FILE | cut -f1)"
            echo "修改时间: $(stat -c %y $BACKUP_FILE)"
            
            # 列出tar中的镜像
            echo "包含的镜像:"
            tar -xf "$BACKUP_FILE" -O manifest.json 2>/dev/null | jq -r '.[].RepoTags[]' 2>/dev/null || \
            echo "无法读取镜像列表,可能格式不支持"
        else
            echo "备份文件不存在"
        fi
        ;;
        
    *)
        echo "用法: $0 {save|load|list|info} [备份文件]"
        echo "示例:"
        echo "  $0 save                         # 备份到 docker-images-backup.tar"
        echo "  $0 save my-backup.tar           # 备份到指定文件"
        echo "  $0 load                         # 从默认文件恢复"
        echo "  $0 load my-backup.tar          # 从指定文件恢复"
        echo "  $0 list                         # 列出当前镜像"
        echo "  $0 info                         # 查看备份文件信息"
        exit 1
        ;;
esac
  1. 使用 Docker 镜像来备份 Docker 镜像(元!)
# Dockerfile.backup
FROM alpine:latest
RUN apk add --no-cache docker-cli
COPY backup.sh /backup.sh
RUN chmod +x /backup.sh
ENTRYPOINT ["/backup.sh"]
# backup.sh
#!/bin/sh
# 挂载Docker socket,备份所有镜像
docker save $(docker images -q) -o /backup/images.tar
echo "备份完成!"

最简单的单行命令

# 备份所有镜像
docker save $(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>") -o all-images.tar

# 恢复所有镜像
docker load -i all-images.tar

注意事项
权限问题:确保有足够的磁盘空间

镜像数量:如果有大量镜像,考虑分批处理

特殊字符:镜像名中的特殊字符可能需要处理

版本兼容性:备份的镜像在不同Docker版本间可能有限制

推荐使用第3个脚本(高级脚本),它包含验证和日志记录,更安全可靠。