离线安装Docker 镜像

要在没有网络连接的环境中使用Docker安装镜像,你需要提前下载镜像文件,并通过某种方式将其传输到目标机器上。以下是步骤和示例代码:
在有网络连接的机器上,下载Docker镜像:

docker pull [IMAGE_NAME]:[TAG]

保存镜像为tar文件:

docker save -o [PATH_TO_SAVE]/[IMAGE_NAME].[TAG].tar [IMAGE_NAME]:[TAG]

将tar文件复制到离线的Docker主机上。
在离线的Docker主机上,加载镜像tar文件:

docker load -i [PATH_TO_SAVE]/[IMAGE_NAME].[TAG].tar

现在可以运行镜像:

docker run -d --name [CONTAINER_NAME] [IMAGE_NAME]:[TAG]

请确保替换[IMAGE_NAME], [TAG], [PATH_TO_SAVE][CONTAINER_NAME] 为实际的镜像名、标签、保存路径和容器名。

我这里写了一个脚本来导出docker

#!/bin/bash

GREEN="\033[0;32m"
YELLOW="\033[1;33m"
BLUE="\033[0;34m"
NC="\033[0m"

EXPORT_DIR="docker_images_export_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$EXPORT_DIR"
echo -e "${BLUE}创建导出目录: $EXPORT_DIR${NC}"

images=($(docker images --format "{{.Repository}}:{{.Tag}}" | grep -v "<none>"))
total_images=${#images[@]}

echo -e "${YELLOW}发现 $total_images 个镜像需要导出${NC}"
echo -e "${YELLOW}开始导出过程...${NC}\n"

current=0

for image in "${images[@]}"; do
    current=$((current + 1))
    echo -e "${BLUE}[$current/$total_images] 正在导出: $image${NC}"
    filename=$(echo "$image" | tr "/" "_" | tr ":" "_").tar
    docker save -o "$EXPORT_DIR/$filename" "$image"
    if [ $? -eq 0 ]; then
        size=$(du -h "$EXPORT_DIR/$filename" | cut -f1)
        echo -e "${GREEN}✓ 成功导出: $filename (大小: $size)${NC}\n"
    else
        echo -e "\033[0;31m✗ 导出失败: $image\033[0m\n"
    fi
done

total_size=$(du -sh "$EXPORT_DIR" | cut -f1)

echo -e "${GREEN}导出完成!${NC}"
echo -e "${BLUE}总共导出 $total_images 个镜像${NC}"
echo -e "${BLUE}导出文件位置: $(pwd)/$EXPORT_DIR${NC}"
echo -e "${BLUE}总占用空间: $total_size${NC}"

又写了一个脚本,用于导入docker

#!/bin/bash

GREEN="\033[0;32m"
YELLOW="\033[1;33m"
BLUE="\033[0;34m"
RED="\033[0;31m"
NC="\033[0m"

if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}请使用 sudo 运行此脚本${NC}"
    exit 1
fi

check_docker() {
    if ! command -v docker &> /dev/null; then
        echo -e "${RED}Docker 未安装。是否要安装 Docker? (y/n)${NC}"
        read -r install_docker
        if [ "$install_docker" = "y" ]; then
            echo -e "${YELLOW}正在安装 Docker...${NC}"
            apt-get update
            apt-get install -y docker.io
            systemctl start docker
            systemctl enable docker
        else
            echo -e "${RED}Docker 是必需的。退出安装。${NC}"
            exit 1
        fi
    fi
}

check_docker_service() {
    if ! systemctl is-active --quiet docker; then
        echo -e "${YELLOW}Docker 服务未运行,正在启动...${NC}"
        systemctl start docker
    fi
}

LOG_DIR="docker_import_logs"
mkdir -p "$LOG_DIR"
LOG_FILE="$LOG_DIR/import_$(date +%Y%m%d_%H%M%S).log"

log_message() {
    echo -e "$1" | tee -a "$LOG_FILE"
}

main() {
    check_docker
    check_docker_service

    tar_files=(*.tar)
    if [ ! -e "${tar_files[0]}" ]; then
        log_message "${RED}错误:当前目录下没有找到 .tar 文件${NC}"
        exit 1
    fi

    total_files=${#tar_files[@]}
    total_size=$(du -ch "${tar_files[@]}" | tail -n1 | cut -f1)
    log_message "${BLUE}找到 $total_files 个镜像文件需要导入${NC}"
    log_message "${BLUE}总大小: $total_size${NC}"
    log_message "${YELLOW}开始导入过程...${NC}\n"

    current=0
    success_count=0
    failed_count=0
    start_time=$(date +%s)

    for tar_file in "${tar_files[@]}"; do
        current=$((current + 1))
        log_message "${BLUE}[$current/$total_files] 正在导入: $tar_file${NC}"
        file_size=$(du -h "$tar_file" | cut -f1)
        log_message "${YELLOW}文件大小: $file_size${NC}"
        
        if docker load -i "$tar_file" 2>> "$LOG_FILE"; then
            log_message "${GREEN}✓ 成功导入: $tar_file${NC}"
            success_count=$((success_count + 1))
        else
            log_message "${RED}✗ 导入失败: $tar_file${NC}"
            failed_count=$((failed_count + 1))
        fi
        log_message ""
    done

    end_time=$(date +%s)
    duration=$((end_time - start_time))
    minutes=$((duration / 60))
    seconds=$((duration % 60))

    log_message "${GREEN}导入完成!${NC}"
    log_message "${BLUE}总耗时: ${minutes}${seconds}${NC}"
    log_message "${BLUE}成功导入: $success_count 个镜像${NC}"
    if [ $failed_count -gt 0 ]; then
        log_message "${RED}导入失败: $failed_count 个镜像${NC}"
        log_message "${YELLOW}请查看日志文件了解详细信息: $LOG_FILE${NC}"
    fi

    log_message "\n${BLUE}当前系统中的 Docker 镜像列表:${NC}"
    docker images | tee -a "$LOG_FILE"
}

main

docker 不同设备的镜像是否是通用的?

Docker 镜像的 tar 包是跨平台通用的,这是因为:

  1. Docker 镜像的特性

    • Docker 镜像是平台无关的,采用 OCI(Open Container Initiative)标准
    • 镜像内部的文件系统和配置是独立的,与宿主机操作系统无关
    • docker savedocker load 命令产生和使用的格式是标准化的
  2. 但是需要注意

    • 虽然镜像格式是通用的,但镜像本身可能会包含特定架构的二进制文件
    • 需要确保镜像支持目标机器的 CPU 架构(比如 AMD64/x86_64 或 ARM64)

让我们验证一下您的镜像架构:

docker images --format "{{.Repository}}:{{.Tag}} - {{.Architecture}}" | cat

让我们用另一个命令来查看:

docker inspect $(docker images -q) | grep Architecture

我看到您当前的镜像都是 ARM64 架构的,这可能会带来一些注意事项:

  1. 架构兼容性

    • 如果目标 Ubuntu 服务器是 x86_64(AMD64)架构,这些 ARM64 镜像可能无法直接运行
    • 如果目标服务器也是 ARM64 架构(比如 AWS Graviton 或其他 ARM 服务器),则可以直接使用
  2. 解决方案
    a. 如果目标服务器是 x86_64 架构:

    • 建议在相同架构的机器上重新拉取和打包这些镜像
    • 或者使用支持多架构的镜像(multi-arch images)

    b. 如果目标服务器也是 ARM64 架构:

    • 可以直接使用当前的镜像包
  3. 检查目标服务器架构的命令

    uname -m
    # 或
    arch
    
    • 如果显示 x86_64,则是 Intel/AMD 架构
    • 如果显示 aarch64arm64,则是 ARM 架构
  4. 建议

    • 在迁移之前,先确认目标 Ubuntu 服务器的 CPU 架构
    • 如果架构不同,建议:
      1. 在目标架构的机器上重新拉取这些镜像
      2. 使用 docker save 重新打包
      3. 然后再进行迁移
  5. 使用多架构镜像

    • 如果可能,建议使用支持多架构的官方镜像
    • 这样的镜像可以在不同架构的机器上自动选择正确的版本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值