1. docker 镜像分发推送

很多时候我们的服务器即使能联网也无法下载docker镜像,只能依靠VPN服务器来进行下载分发,机器一多还是挺麻烦的。可以优化一下来个脚本,在里面预先配置主机与密码,通过该方式导出镜像再对目标机器推送加载,可以实现不错的效果,后续可以继续优化推送到私有harbor。

#!/bin/bash
set -e

# ============ 依赖检查 ============
if ! command -v sshpass &> /dev/null; then
  echo "❌ 错误:未找到命令 sshpass"
  echo "请先安装 sshpass,例如:"
  echo "  Debian/Ubuntu: sudo apt update && sudo apt install -y sshpass"
  echo "  CentOS/RHEL:   sudo yum install -y epel-release && sudo yum install -y sshpass"
  echo "  Alpine:        apk add sshpass"
  echo "或手动下载离线安装包后安装。"
  exit 1
fi

if ! command -v docker &> /dev/null; then
  echo "❌ 错误:未找到命令 docker,请确保当前机器安装了 Docker"
  exit 1
fi

# ============ 参数检查 ============
if [ $# -ne 1 ]; then
  echo "用法: $0 <镜像名:版本>(例如 nginx:1.25)"
  exit 1
fi

IMAGE_NAME="$1"
IMAGE_BASE=$(echo "$IMAGE_NAME" | cut -d: -f1)
IMAGE_TAG=$(echo "$IMAGE_NAME" | cut -d: -f2)
IMAGE_FILE="${IMAGE_BASE//\//_}-${IMAGE_TAG}"  # 替换 / 为 _,无扩展名

# ============ 节点配置 ============
NODES=(
  "192.168.10.11:123456"
  "192.168.10.12:123456"
)

# ============ 拉取镜像并保存 ============
echo "===> 拉取镜像 $IMAGE_NAME ..."
docker pull "$IMAGE_NAME"

echo "===> 保存镜像为本地文件 $IMAGE_FILE ..."
docker save "$IMAGE_NAME" > "$IMAGE_FILE"

# ============ 分发并加载 ============
for NODE in "${NODES[@]}"; do
  IP="${NODE%%:*}"
  PASS="${NODE##*:}"

  echo "===> 正在传输镜像到节点 $IP:/tmp/$IMAGE_FILE ..."
  sshpass -p "$PASS" scp -o StrictHostKeyChecking=no "$IMAGE_FILE" root@$IP:/tmp/

  echo "===> 在节点 $IP 加载镜像并清理镜像包 ..."
  sshpass -p "$PASS" ssh -o StrictHostKeyChecking=no root@$IP "
    docker load < /tmp/$IMAGE_FILE && rm -f /tmp/$IMAGE_FILE
  "
done

# ============ 本地清理 ============
echo "===> 清理本地文件 $IMAGE_FILE ..."
rm -f "$IMAGE_FILE"

echo "✅ 镜像已成功分发并加载到所有节点。"