#!/bin/bash # ============================================================ # Docker 功能测试脚本 # 测试项目: pull / run / commit / export / load / push # ============================================================ set -e RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' info() { echo -e "${BLUE}[INFO]${NC} $*"; } success() { echo -e "${GREEN}[OK]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; } die() { error "$*"; exit 1; } WORK_DIR="/tmp/docker_test_$$" TEST_IMAGE="hello-world" COMMIT_IMAGE="hello-world-committed:test" EXPORT_TAR="$WORK_DIR/hello-world-export.tar" LOAD_TAR="$WORK_DIR/hello-world-load.tar" TEST_CONTAINER="docker_test_$$" mkdir -p "$WORK_DIR" echo "" echo "============================================================" echo " Docker 功能测试脚本" echo "============================================================" echo "" # ---------- 检查 Docker 服务 ---------- info "检查 Docker 服务状态..." if ! docker info &>/dev/null; then die "Docker 服务未运行, 请先启动: systemctl start docker" fi success "Docker 服务正常 ✓" # ---------- 1. docker pull ---------- echo "" echo "------------------------------------------------------------" info "[1/5] 测试 docker pull..." echo "------------------------------------------------------------" # 尝试多个镜像源 PULL_OK=false for mirror_image in \ "hello-world" \ "docker.mirrors.ustc.edu.cn/library/hello-world:latest" \ "mirror.baidubce.com/library/hello-world:latest"; do info "尝试拉取: $mirror_image" if docker pull "$mirror_image" 2>&1; then # 如果不是标准名称,打个tag if [ "$mirror_image" != "hello-world" ]; then docker tag "$mirror_image" hello-world:latest 2>/dev/null || true fi PULL_OK=true success "docker pull 成功 ✓" break else warn "拉取 $mirror_image 失败, 尝试下一个..." fi done if [ "$PULL_OK" = false ]; then # 最后手段: 本地构建一个最小镜像代替 warn "所有镜像源均无法拉取, 改用本地构建最小测试镜像..." SCRATCH_DIR="$WORK_DIR/scratch" mkdir -p "$SCRATCH_DIR" # 写一个静态可执行的 hello 程序 (用 shell 脚本模拟) cat > "$SCRATCH_DIR/hello.sh" <<'HELLO' #!/bin/sh echo "Hello from Docker on ARM64!" echo "Docker pull/commit/export/load 功能测试通过" HELLO chmod +x "$SCRATCH_DIR/hello.sh" cat > "$SCRATCH_DIR/Dockerfile" <<'DOCKERFILE' FROM busybox:latest COPY hello.sh /hello.sh CMD ["/hello.sh"] DOCKERFILE # 先拉 busybox docker pull busybox:latest 2>&1 || die "busybox 也无法拉取, 网络不可用" docker build -t hello-world:latest "$SCRATCH_DIR" 2>&1 success "本地构建 hello-world 镜像成功 ✓" fi # ---------- 2. docker run ---------- echo "" echo "------------------------------------------------------------" info "[2/5] 测试 docker run..." echo "------------------------------------------------------------" docker run --name "$TEST_CONTAINER" "$TEST_IMAGE" 2>&1 \ || docker run --name "$TEST_CONTAINER" hello-world:latest 2>&1 \ || die "docker run 失败" success "docker run 成功 ✓" # ---------- 3. docker commit ---------- echo "" echo "------------------------------------------------------------" info "[3/5] 测试 docker commit..." echo "------------------------------------------------------------" docker commit \ -m "测试 commit: 添加自定义标签" \ -a "docker-test-script" \ "$TEST_CONTAINER" \ "$COMMIT_IMAGE" 2>&1 success "docker commit 成功 -> $COMMIT_IMAGE ✓" # 验证 commit 的镜像存在 docker inspect "$COMMIT_IMAGE" &>/dev/null \ || die "commit 后的镜像不存在" success "commit 镜像验证通过 ✓" # ---------- 4. docker export ---------- echo "" echo "------------------------------------------------------------" info "[4/5] 测试 docker export..." echo "------------------------------------------------------------" docker export "$TEST_CONTAINER" -o "$EXPORT_TAR" 2>&1 EXPORT_SIZE=$(du -sh "$EXPORT_TAR" | cut -f1) success "docker export 成功 -> $EXPORT_TAR ($EXPORT_SIZE) ✓" # ---------- 5. docker save + docker load ---------- echo "" echo "------------------------------------------------------------" info "[5/5] 测试 docker save & load..." echo "------------------------------------------------------------" # save committed 镜像为 tar docker save "$COMMIT_IMAGE" -o "$LOAD_TAR" 2>&1 LOAD_SIZE=$(du -sh "$LOAD_TAR" | cut -f1) success "docker save 成功 -> $LOAD_TAR ($LOAD_SIZE) ✓" # 删除本地镜像再 load,验证完整性 docker rmi "$COMMIT_IMAGE" 2>&1 info "已删除本地镜像 $COMMIT_IMAGE, 准备 load..." docker load -i "$LOAD_TAR" 2>&1 docker inspect "$COMMIT_IMAGE" &>/dev/null \ || die "docker load 后镜像不存在" success "docker load 成功, 镜像已恢复 ✓" # ---------- push 说明 ---------- echo "" echo "------------------------------------------------------------" info "[附] docker push 说明" echo "------------------------------------------------------------" warn "docker push 需要登录镜像仓库, 本脚本不自动执行" echo " 推送到 Docker Hub:" echo " docker login" echo " docker tag $COMMIT_IMAGE <你的用户名>/hello-world:test" echo " docker push <你的用户名>/hello-world:test" echo "" echo " 推送到私有仓库:" echo " docker tag $COMMIT_IMAGE <仓库地址>/hello-world:test" echo " docker push <仓库地址>/hello-world:test" # ---------- 清理 ---------- echo "" echo "------------------------------------------------------------" info "清理测试资源..." echo "------------------------------------------------------------" docker rm "$TEST_CONTAINER" 2>/dev/null && success "容器已清理 ✓" docker rmi "$COMMIT_IMAGE" 2>/dev/null && success "commit 镜像已清理 ✓" rm -rf "$WORK_DIR" && success "临时文件已清理 ✓" # ---------- 汇总 ---------- echo "" echo "============================================================" success "全部测试通过!" echo "============================================================" echo "" echo " 测试结果汇总:" echo " ✓ docker pull - 镜像拉取" echo " ✓ docker run - 容器运行" echo " ✓ docker commit - 容器提交为镜像" echo " ✓ docker export - 容器导出为 tar" echo " ✓ docker save - 镜像保存为 tar" echo " ✓ docker load - 从 tar 加载镜像" echo " - docker push - 需手动配置仓库后执行" echo ""