Сохранение и загрузка нескольких Docker образов в один архив

от автора

Добрый день. Возможно, кому-то будет полезна данная информация. Мне в рамках некоторых рабочих задач понадобилось сохранить порядка 50 образов Docker и затем загрузить их в Docker на другом сервере.

За исходным кодом прошу под кат.

Код скрипта для сохранения образов (save-images.sh):

#!/bin/bash list="images.txt" images="images.tar.gz"  usage() {   echo "USAGE: $0 [--image-list images.txt] [--images images.tar.gz]"   echo "  [-l|--image-list path] text file with list of images; one image per line."   echo "  [-i|--images path] tar.gz generated by docker save."   echo "  [-h|--help] Usage message" }  POSITIONAL=() while [[ $# -gt 0 ]]; do   key="$1"   case $key in   -i | --images)     images="$2"     shift # past argument     shift # past value     ;;   -l | --image-list)     list="$2"     shift # past argument     shift # past value     ;;   -h | --help)     help="true"     shift     ;;   *)     usage     exit 1     ;;   esac done  if [[ $help ]]; then   usage   exit 0 fi  pulled="" while IFS= read -r i; do   [ -z "${i}" ] && continue   if docker pull "${i}" >/dev/null 2>&1; then     echo "Image pull success: ${i}"     pulled="${pulled} ${i}"   else     if docker inspect "${i}" >/dev/null 2>&1; then       pulled="${pulled} ${i}"     else       echo "Image pull failed: ${i}"     fi   fi done <"${list}"  echo "Creating ${images} with $(echo ${pulled} | wc -w | tr -d '[:space:]') images" docker save $(echo ${pulled}) | gzip --stdout >${images}

Код для загрузки образов (load-images.sh):

#!/bin/bash images="images.tar.gz" list="images.txt" windows_image_list="" windows_versions="1809" usage() {   echo "USAGE: $0 [--images images.tar.gz] --registry my.registry.com:5000"   echo "  [-l|--image-list path] text file with list of images; one image per line."   echo "  [-i|--images path] tar.gz generated by docker save."   echo "  [-r|--registry registry:port] target private registry:port."   echo "  [--windows-image-list path] text file with list of images used in Windows. Windows image mirroring is skipped when this is empty"   echo "  [--windows-versions version] Comma separated Windows versions. e.g., \"1809,2004,20H2\". (Default \"1809\")"   echo "  [-h|--help] Usage message" }  push_manifest() {   export DOCKER_CLI_EXPERIMENTAL=enabled   manifest_list=()   for i in "${arch_list[@]}"; do     manifest_list+=("$1-${i}")   done    echo "Preparing manifest $1, list[${arch_list[@]}]"   docker manifest create "$1" "${manifest_list[@]}" --amend   docker manifest push "$1" --purge }  while [[ $# -gt 0 ]]; do   key="$1"   case $key in   -r | --registry)     reg="$2"     shift # past argument     shift # past value     ;;   -l | --image-list)     list="$2"     shift # past argument     shift # past value     ;;   -i | --images)     images="$2"     shift # past argument     shift # past value     ;;   --windows-image-list)     windows_image_list="$2"     shift # past argument     shift # past value     ;;   --windows-versions)     windows_versions="$2"     shift # past argument     shift # past value     ;;   -h | --help)     help="true"     shift     ;;   *)     usage     exit 1     ;;   esac done if [[ -z $reg ]]; then   usage   exit 1 fi if [[ $help ]]; then   usage   exit 0 fi  docker load --input ${images}  linux_images=() while IFS= read -r i; do   [ -z "${i}" ] && continue   linux_images+=("${i}") done <"${list}"  arch_list=() if [[ -n "${windows_image_list}" ]]; then   IFS=',' read -r -a versions <<<"$windows_versions"   for version in "${versions[@]}"; do     arch_list+=("windows-${version}")   done    windows_images=()   while IFS= read -r i; do     [ -z "${i}" ] && continue     windows_images+=("${i}")   done <"${windows_image_list}"    # use manifest to publish images only used in Windows   for i in "${windows_images[@]}"; do     if [[ ! " ${linux_images[@]}" =~ " ${i}" ]]; then       case $i in       */*)         image_name="${reg}/${i}"         ;;       *)         image_name="${reg}/${i}"         ;;       esac       push_manifest "${image_name}"     fi   done fi  arch_list+=("linux-amd64") for i in "${linux_images[@]}"; do   [ -z "${i}" ] && continue   arch_suffix=""   use_manifest=false   if [[ (-n "${windows_image_list}") && " ${windows_images[@]}" =~ " ${i}" ]]; then     # use manifest to publish images when it is used both in Linux and Windows     use_manifest=true     arch_suffix="-linux-amd64"   fi   case $i in   */*)     image_name="${reg}/${i}"     ;;   *)     image_name="${reg}/${i}"     ;;   esac    docker tag "${i}" "${image_name}${arch_suffix}"   docker push "${image_name}${arch_suffix}"    if $use_manifest; then     push_manifest "${image_name}"   fi done

Ну и формат списка образов это просто текстовый файл (images.txt):

quay.io/prometheus/prometheus:v2.36.1 quay.io/prometheus/node-exporter:v1.3.1 grafana/grafana:9.0.3

Инструкция по использованию:

Делаем файл save-images.sh исполняемым

chmod +x ./save-images.sh

И запускаем его

./save-images.sh --image-list ./images.txt

На выходе получаем архив images.tar.gz содержащий образы из списка. Для загрузки образов выполняем похожие операции

chmod +x load-images.sh

И загружаем образы из архива

./load-images.sh --image-list ./images.txt --registry <АДРЕС_ЛОКАЛЬНОГО_REGISTRY:ПОРТ>

Весь код доступен на GitHub: https://github.com/ZeroBot-Dot/docker-save-load-multiple-images


ссылка на оригинал статьи https://habr.com/ru/post/692638/