Перейти до змісту

Використання AWS ECR як універсального OCI-репозиторію

Written by:

Igor Gorovyy
DevOps Engineer Lead & Senior Solutions Architect

LinkedIn


w

Вступ

У сучасному світі DevOps та Cloud Native розробки, управління артефактами стає все більш складним завданням. Кожен тип артефакту традиційно вимагав окремого сховища: Docker Hub для контейнерів, Artifactory для бінарних файлів, MLflow для моделей машинного навчання тощо. Це створювало "зоопарк" сервісів, який складно підтримувати та масштабувати.

Завдяки появі Open Container Initiative (OCI), з'явився єдиний стандарт для всіх типів артефактів. Це дозволило компаніям створювати універсальні сховища, які можуть зберігати будь-які артефакти: від Docker образів до моделей машинного навчання.

Amazon Elastic Container Registry (ECR) - це не просто реєстр для Docker-образів, а повноцінне OCI-сумісне сховище. З 2022 року AWS ECR підтримує специфікацію OCI Artifact, що дозволяє зберігати будь-які артефакти, які відповідають цьому стандарту.

У цій статті я розкажу: - Як ефективно використовувати AWS ECR для різних типів артефактів - Як позбутися необхідності в множинних сховищах - Практичні приклади роботи з різними типами артефактів - Найкращі практики та рекомендації з безпеки

Переваги використання ECR як універсального сховища

  1. Єдина точка доступу: Всі артефакти в одному місці з єдиною системою автентифікації
  2. Інтеграція з AWS: Нативна підтримка IAM, CloudWatch, KMS
  3. Економічна ефективність: Єдина система білінгу та оптимізації витрат
  4. Спрощене управління: Загальні політики життєвого циклу та реплікації
  5. Безпека: Вбудоване сканування вразливостей та шифрування

Попередня підготовка

Перш ніж ми перейдемо до практичних прикладів, давайте налаштуємо необхідні інструменти та створимо наш перший репозиторій.

Необхідні інструменти

Для роботи з ECR як універсальним сховищем нам знадобляться:

  • AWS CLI: Для взаємодії з AWS сервісами
  • Helm CLI: Для роботи з Helm чартами
  • ORAS CLI: Для роботи з OCI артефактами
  • Terraform >=1.5: Для інфраструктури як коду

Створення та налаштування репозиторію

Спочатку створимо репозиторій в ECR:

aws ecr create-repository --repository-name my-universal-repo \
  --image-scanning-configuration scanOnPush=true \
  --region eu-central-1

Цей репозиторій буде нашим універсальним сховищем для всіх типів артефактів.

Автентифікація

Для роботи з ECR потрібно авторизуватися:

aws ecr get-login-password \
  | docker login --username AWS --password-stdin <aws_account_id>.dkr.ecr.eu-central-1.amazonaws.com

Робота з різними типами артефактів

Давайте розглянемо, як працювати з різними типами артефактів у нашому універсальному сховищі.

1. Docker образи

Docker образи - це класичний випадок використання ECR. Процес роботи з ними простий та зрозумілий:

# Побудова
docker build -t my-app .

# Тегування
docker tag my-app:latest <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo:my-app-v1

# Завантаження
docker push <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo:my-app-v1

Ключові переваги використання ECR для Docker образів: - Автоматичне сканування вразливостей - Іммутабельні теги - Інтеграція з ECS/EKS - Можливість крос-регіональної реплікації

2. Helm чарти через OCI

Helm 3 додав підтримку OCI, що дозволяє зберігати чарти безпосередньо в ECR без необхідності окремого Helm репозиторію.

# Увімкнути OCI підтримку
export HELM_EXPERIMENTAL_OCI=1

# Створення helm chart
helm create my-chart

# Упакування
helm package my-chart

# Завантаження в ECR
helm push my-chart-0.1.0.tgz oci://<aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo

# Встановлення
helm install mychart oci://<aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo --version 0.1.0

Переваги зберігання Helm чартів в ECR: - Версіонування та контроль доступу - Єдина точка доступу з Docker образами - Можливість використання в GitOps процесах

3. Terraform провайдери та модулі

З версії 1.5 Terraform додав нативну підтримку OCI реєстрів для модулів. Це дозволяє використовувати ECR як джерело для модулів та провайдерів.

3.1. Публікація Terraform провайдера/модуля

# Структура модуля
tree my-module/
├── main.tf
├── variables.tf
├── outputs.tf

# Архівація
tar -czf my-module.tar.gz my-module/

# Завантаження через oras
oras push <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo:tf-my-module-v1 \
  --artifact-type application/vnd.terraform.module \
  my-module.tar.gz

3.2. Використання як модуль у Terraform

module "my_module" {
  source = "oci::<aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo:tf-my-module-v1"
}

Переваги зберігання Terraform модулів в ECR: - Версіонування та контроль доступу - Приватні модулі без додаткових сервісів - Інтеграція з існуючими CI/CD pipeline

4. ML моделі

Одна з найцікавіших можливостей - зберігання моделей машинного навчання. ECR може замінити спеціалізовані ML реєстри для багатьох випадків використання.

Базовий приклад:

# Завантаження моделі
oras push <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo:ml-my-model-v1 \
  --artifact-type application/vnd.model.mlflow \
  model.pkl

Розширений приклад з метаданими:

oras push <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/my-universal-repo:ml-my-model-v2 \
  --artifact-type application/vnd.model \
  "model.onnx" \
  "metadata.json"

📌 Важливо розуміти, що ECR не валідує MIME-тип - він просто зберігає артефакт з вказаним типом. Однак інші інструменти можуть використовувати цей тип для фільтрації та ідентифікації артефактів.

Практичні сценарії використання

Давайте розглянемо кілька реальних сценаріїв використання ECR як універсального сховища.

Зберігання та управління ML моделями

Одним з найцікавіших випадків використання ECR є зберігання моделей машинного навчання. Розглянемо це детальніше.

Структура метаданих

Для ефективного управління ML моделями важливо мати добре структуровані метадані. Ось приклад:

{
  "model_name": "resnet50",
  "version": "1.0.0",
  "framework": "onnx",
  "input_shape": [1, 3, 224, 224],
  "output_classes": 1000,
  "trained_on": "imagenet",
  "accuracy_top1": 0.76,
  "accuracy_top5": 0.93,
  "created_at": "2025-07-08T12:00:00Z"
}

Такі метадані дозволяють: - Відстежувати версії моделей - Документувати параметри та характеристики - Спрощувати пошук та вибір потрібної версії - Автоматизувати процеси розгортання

Автоматизація публікації моделей

Для спрощення процесу публікації моделей можна використовувати скрипт:

#!/bin/bash

set -e

# === Аргументи ===
MODEL_FILE=${1:-"model.onnx"}
META_FILE=${2:-"metadata.json"}
TAG=${3:-"resnet50-v1"}

# === Конфігурація AWS ECR ===
AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
REGION=eu-central-1
REPO_NAME=ml-registry
REPO_URL="$AWS_ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/$REPO_NAME"

# === Авторизація ===
aws ecr get-login-password \
  | oras login --username AWS --password-stdin $REPO_URL

# === Push ===
echo "🚀 Завантаження моделі [$MODEL_FILE] та метаданих [$META_FILE] до [$REPO_URL:$TAG]"

oras push $REPO_URL:$TAG \
  --artifact-type application/vnd.model \
  "$MODEL_FILE" \
  "$META_FILE"

echo "✅ Готово. Артефакт завантажено як $REPO_URL:$TAG"

Поширені MIME-типи для ML-артефактів

При роботі з ML моделями важливо правильно вказувати MIME-типи:

MIME тип Призначення
application/vnd.model Загальний ML-артефакт
application/vnd.model.mlflow MLflow модель
application/vnd.model.onnx ONNX-модель
application/vnd.model.torch TorchScript
application/vnd.model.keras Keras-модель

Робота з YOLO моделями

Особливий інтерес представляє робота з популярними моделями комп'ютерного зору, такими як YOLO. Є три основні підходи до їх зберігання в ECR:

1. Як Docker образ (рекомендовано для розгортання)

FROM ultralytics/yolov5:latest

# Додаємо нашу модель
COPY best.pt /models/best.pt

CMD ["python3", "detect.py", "--weights", "/models/best.pt", "--source", "0"]

Збірка та публікація:

docker build -t yolo-inference .
docker tag yolo-inference <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/yolo:v5
docker push <aws_id>.dkr.ecr.eu-central-1.amazonaws.com/yolo:v5

2. Як OCI-артефакт через ORAS

oras push <ecr_repo>:yolov5-v1 \
  --artifact-type application/vnd.model.pytorch \
  best.pt \
  metadata.json

Метадані для YOLO моделі:

{
  "model_name": "yolov5",
  "framework": "pytorch",
  "version": "6.2",
  "input_shape": [1, 3, 640, 640],
  "trained_on": "coco",
  "classes": 80
}

3. Як ONNX-модель

YOLOv5 підтримує експорт до ONNX формату:

python export.py --weights best.pt --include onnx

Публікація ONNX версії:

oras push <ecr_repo>:yolov5-onnx \
  --artifact-type application/vnd.model.onnx \
  best.onnx \
  metadata.json

Порівняння підходів

Формат Плюси Мінуси
Docker образ - Готовий до запуску в ECS/EKS/Lambda
- Включає всі залежності
- Простіше розгортання
- Великий розмір
- Менша гнучкість
- Складніше оновлення моделі
.pt + ORAS - Компактний розмір
- Зручно як реєстр моделей
- Легке версіонування
- Потрібно окреме середовище для запуску
- Додаткова конфігурація середовища
ONNX + ORAS - Крос-фреймворк сумісність
- Оптимізована інференс
- Легка інтеграція
- Не всі функції YOLO доступні
- Можливі відмінності в продуктивності

Управління доступом та безпека

IAM політики

Базова політика для читання/запису до ECR:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage",
        "ecr:BatchCheckLayerAvailability",
        "ecr:PutImage",
        "ecr:InitiateLayerUpload",
        "ecr:UploadLayerPart",
        "ecr:CompleteLayerUpload"
      ],
      "Resource": "*"
    }
  ]
}

Доступ між акаунтами

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowCrossAccountPull",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::444455556666:root"
      },
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ]
    }
  ]
}

Розрахунок витрат на сховище OCI-артефактів

Ціноутворення ECR складається з трьох компонентів:

  1. Зберігання: $0.10 за ГБ-місяць
  2. Передача даних:
  3. Вхідний трафік: Безкоштовно
  4. Вихідний трафік: Залежить від регіону AWS та об'єму
  5. API-запити:
  6. Перші 10 мільйонів запитів на місяць: $0.01 за запит
  7. Понад 10 мільйонів запитів: $0.008 за запит

Поради щодо оптимізації витрат

  • Використовуйте політики життєвого циклу для видалення невикористовуваних артефактів
  • Впровадьте стратегію тегування образів
  • Враховуйте витрати на мультирегіональну реплікацію
  • Використовуйте AWS Organizations для консолідованого білінгу
  • Відстежуйте витрати за допомогою AWS Cost Explorer

Політики життєвого циклу для очищення

Приклад політики: Зберігати останні 30 днів

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Зберігати тільки образи, завантажені за останні 30 днів",
      "selection": {
        "tagStatus": "any",
        "countType": "sinceImagePushed",
        "countUnit": "days",
        "countNumber": 30
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

Приклад політики: Зберігати останні N образів

{
  "rules": [
    {
      "rulePriority": 1,
      "description": "Зберігати останні 10 образів",
      "selection": {
        "tagStatus": "tagged",
        "tagPrefixList": ["v"],
        "countType": "imageCountMoreThan",
        "countNumber": 10
      },
      "action": {
        "type": "expire"
      }
    }
  ]
}

Інструкції по роботі через веб-консоль

  1. Створення репозиторію:
  2. Відкрийте AWS Console → ECR
  3. Натисніть "Create repository"
  4. Виберіть "Private" або "Public"
  5. За потреби увімкніть "Tag immutability"
  6. Увімкніть "Scan on push" для безпеки

  7. Керування дозволами:

  8. Виберіть репозиторій
  9. Вкладка "Permissions"
  10. Редагуйте/додайте політику репозиторію

  11. Перегляд артефактів:

  12. Перегляд образів та тегів
  13. Перегляд деталей шарів
  14. Перевірка результатів сканування
  15. Доступ до команд завантаження

CI/CD інтеграція

GitHub Actions

name: Публікація до ECR

on:
  push:
    branches: [ main ]
    paths:
      - 'models/**'
      - 'charts/**'
      - 'terraform/**'

jobs:
  publish:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v2

    - name: Налаштування облікових даних AWS
      uses: aws-actions/configure-aws-credentials@v1
      with:
        aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
        aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
        aws-region: eu-central-1

    - name: Вхід до Amazon ECR
      id: login-ecr
      uses: aws-actions/amazon-ecr-login@v1

    - name: Публікація артефактів
      env:
        ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
        ECR_REPOSITORY: my-universal-repo
        IMAGE_TAG: ${{ github.sha }}
      run: |
        # Публікація Docker образів
        if [ -f Dockerfile ]; then
          docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
          docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
        fi

        # Публікація Helm чартів
        if [ -d charts ]; then
          for chart in charts/*; do
            if [ -d "$chart" ]; then
              helm package $chart
              helm push ${chart##*/}-*.tgz oci://$ECR_REGISTRY/$ECR_REPOSITORY
            fi
          done
        fi

        # Публікація ML моделей
        if [ -d models ]; then
          for model in models/*.onnx; do
            if [ -f "$model" ]; then
              oras push $ECR_REGISTRY/$ECR_REPOSITORY:${model##*/}-$IMAGE_TAG \
                --artifact-type application/vnd.model.onnx \
                "$model" \
                "${model%.*}.json"
            fi
          done
        fi

Terraform конфігурація

resource "aws_ecr_repository" "universal_repo" {
  name                 = "my-universal-repo"
  image_tag_mutability = "IMMUTABLE"

  image_scanning_configuration {
    scan_on_push = true
  }

  encryption_configuration {
    encryption_type = "KMS"
    kms_key = aws_kms_key.ecr_key.arn
  }

  tags = {
    Environment = "production"
    Purpose     = "universal-artifacts"
  }
}

resource "aws_ecr_lifecycle_policy" "cleanup_policy" {
  repository = aws_ecr_repository.universal_repo.name

  policy = jsonencode({
    rules = [
      {
        rulePriority = 1
        description  = "Зберігати останні 10 версій кожного артефакту"
        selection = {
          tagStatus     = "tagged"
          tagPrefixList = ["v"]
          countType     = "imageCountMoreThan"
          countNumber   = 10
        }
        action = {
          type = "expire"
        }
      },
      {
        rulePriority = 2
        description  = "Видаляти неактивні артефакти старші 90 днів"
        selection = {
          tagStatus = "untagged"
          countType = "sinceImagePushed"
          countUnit = "days"
          countNumber = 90
        }
        action = {
          type = "expire"
        }
      }
    ]
  })
}

Висновки та рекомендації

  1. Планування структури:
  2. Розробіть чітку стратегію іменування
  3. Визначте політики життєвого циклу
  4. Документуйте процеси та стандарти

  5. Безпека:

  6. Використовуйте найменші необхідні привілеї
  7. Регулярно оновлюйте політики безпеки
  8. Налаштуйте сканування вразливостей

  9. Автоматизація:

  10. Створіть повторювані процеси
  11. Використовуйте CI/CD для публікації
  12. Автоматизуйте тестування та валідацію

  13. Моніторинг:

  14. Відстежуйте використання ресурсів
  15. Налаштуйте сповіщення
  16. Регулярно аналізуйте витрати

AWS ECR як універсальне OCI-сховище надає потужну та гнучку платформу для управління різноманітними артефактами. Правильне налаштування та використання дозволяє значно спростити процеси розробки та розгортання, одночасно забезпечуючи високий рівень безпеки та контролю.

Посилання на документацію