September 27, 2023

Синхронизация образов в свой Docker Registry

Есть такой инструмент – skopeo, в числе прочего умеет перепушивать образы из одного регистри в другой, что может быть удобно, если периодически возникает проблема с рейт-лимитом на получение образа. Копировать образ в свой регистри можно было бы и вручную, но не всегда удобно, можно забыть про передачу нужной платформы или у того, кому это срочно надо, нет доступа на пуш. Поэтому в данной заметке предлагаю несложный способ как это можно худо-бедно автоматизировать в Gitlab.

Создаем пустой репозиторий, в файл .gitlab-ci.yml прописываем следующий контент:

---
variables:
  REGISTRY_ADDR: my.registry/aabbccdd

stages:
  - lint
  - sync

lint:
  image: quay.io/skopeo/stable:v1.13.0
  stage: lint
  script:
    - DRY_RUN=1 ./.skopeo.sh

sync:
  image: quay.io/skopeo/stable:v1.13.0
  stage: sync
  script:
    - ./.skopeo.sh
  only:
    refs:
      - master

Чуть ниже создаем файл .skopeo.sh:

#!/usr/bin/env bash

set -o errexit
set -o nounset

for file in *-images.yaml; do
  echo "==> ${file}"
  skopeo sync \
    --scoped \
    --keep-going \
    --src yaml \
    --dry-run="${DRY_RUN:-0}" \
    --dest docker "${file}" "${REGISTRY_ADDR}" \
    --dest-authfile .docker_config.json
done

Обращу внимание, что для пуша могут потребоваться какие-то реквизиты, через аргумент --dest-authfile задается путь к стандартному для Docker файлу с реквизитами в формате JSON, можно так же использовать --dest-registry-token или --dest-creds, все варианты перечислены в справке.

Теперь создаем файл, например, team-infra-images.yaml (файлов может быть несколько, главное, чтобы заканчивались на -images.yaml) с перечнем образов, которые нужно перенести к нам:

---
quay.io:
  images:
    skopeo/stable:
      - v1.13.0
mirror.gcr.io:
  images:
    golang:
      - "1.21"

Теперь, при создании Merge Request у нас будет выполняться dry-run запуск, оставим на всякий случай, чтобы убедиться, что внутри конфигурационных файлов корректный синтаксис. После вливания изменений в основную ветку произойдет проверка источника с получателем, если есть разночтения, то образы будут скопированы в нужный регистри.

Из флагов в команде sync отмечу следующие:

  • --scoped – для включения хоста источника в имя результирующего образа в нашем регистри (например, образ quay.io/skopeo/stable:v1.13.0 будет скопирован не в my.registry/aabbccdd/skopeo/stable:v1.13.0, а в my.registry/aabbccdd/quay.io/skopeo/stable:v1.13.0);
  • --keep-going – продолжать синхронизацию образов, даже если получили ошибку.

Так же можно запланировать периодический запуск, чтобы быть уверенным, что все образы на месте.