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

Модуль 1.6: Elastic Container Registry (ECR)

Час на виконання: 1 година

Розділ «Час на виконання: 1 година»

Перед початком цього модуля ви повинні завершити:

  • Модуль 1.1: Основи IAM та безпеки
  • Основи Docker (збірка та тегування образів)
  • Docker встановлений та запущений локально
  • AWS CLI налаштований з відповідними дозволами

Чому цей модуль важливий

Розділ «Чому цей модуль важливий»

У січні 2024 року фінтех-стартап на стадії зростання випустив планове оновлення свого сервісу обробки платежів. Розгортання пройшло успішно. Але за п’ять хвилин моніторинг “вибухнув”. Додаток падав при запуску з незрозумілою помилкою “exec format error”. Попередній образ контейнера — той, що працював — був перезаписаний, бо команда використовувала тег latest з увімкненою можливістю зміни тегів (mutable tagging). Їхній конвеєр CI випадково пушнув образ архітектури ARM64 замість існуючого AMD64. Ні версійності. Ні незмінності. Жодного способу відкотитися, крім повної перезбірки з коду, що зайняло 22 хвилини, поки платіжний шлюз не працював. Двадцять дві хвилини втрачених транзакцій для фінтех-компанії — це те, що стає причиною дуже неприємних розмов на раді директорів.

Реєстри контейнерів — це один із тих компонентів інфраструктури, які здаються нудними, доки вони не ламаються. Вони стоять між вашим CI-конвеєром та середовищем виконання, зберігаючи кожну версію кожного сервісу, який запускає ваша компанія. Неправильно налаштований реєстр означає, що ви не можете розгорнути додаток, не можете відкотитися і не можете перевірити, чи те, що працює в продакшні, є саме тим, що ви туди відправляли. AWS Elastic Container Registry (ECR) — це керований реєстр контейнерів від Amazon, глибоко інтегрований з ECS, EKS, Lambda та рештою екосистеми AWS.

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


Архітектура та концепції ECR

Розділ «Архітектура та концепції ECR»

ECR — це повністю керований реєстр контейнерів Docker. На відміну від запуску власного реєстру (Docker Registry, Harbor або Nexus), ECR бере на себе зберігання, доступність, шифрування та контроль доступу. Давайте розберемо основні поняття.

Реєстри, Репозиторії та Образи

Розділ «Реєстри, Репозиторії та Образи»
Структура ECR:
AWS Account (123456789012)
|
+-- ECR Registry (один на акаунт у регіоні)
| URL реєстру: 123456789012.dkr.ecr.us-east-1.amazonaws.com
|
+-- Репозиторій: myapp/api
| +-- Образ: sha256:abc123... (тег: v1.2.0)
| +-- Образ: sha256:def456... (тег: v1.2.1)
| +-- Образ: sha256:ghi789... (тег: v1.3.0, тег: latest)
|
+-- Репозиторій: myapp/worker
| +-- Образ: sha256:jkl012... (тег: v2.0.0)
| +-- Образ: sha256:mno345... (тег: v2.1.0)

Реєстр (Registry): Один на акаунт AWS у кожному регіоні. Формат URL завжди {account_id}.dkr.ecr.{region}.amazonaws.com. Ви не можете змінити цей URL.

Репозиторій (Repository): Колекція пов’язаних образів контейнерів, як Git-репозиторій для коду. Конвенція іменування важлива — використовуйте ієрархію через слеш, наприклад team/service або app/component.

Образ (Image): Окремий образ контейнера, ідентифікований за його SHA256-хешем (digest) та опційно одним або кількома тегами. Один образ може мати кілька тегів.

Публічні vs Приватні репозиторії

Розділ «Публічні vs Приватні репозиторії»
ФункціяECR PrivateECR Public
Формат URL{account_id}.dkr.ecr.{region}.amazonaws.compublic.ecr.aws/{alias}
АвтентифікаціяПотрібна для pull та pushПотрібна для push; pull анонімний
Вартість$0.10/ГБ/міс + трафікБезкоштовно (у межах лімітів)
СценарійВнутрішні сервіси, приватний кодOpen source проєкти, базові образи
РегіониУсі комерційні регіониТільки us-east-1 (глобальна доставка)
СкануванняBasic + Enhanced (Inspector)Не підтримується
Правила життєвого циклуТакНі

Автентифікація та завантаження образів (Push)

Розділ «Автентифікація та завантаження образів (Push)»

ECR використовує IAM для автентифікації, але Docker не розуміє IAM нативно. Вам потрібно обміняти ваші креденшали IAM на токен входу Docker.

Terminal window
# Стандартний шлях: передача токена ECR безпосередньо в docker login
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin \
123456789012.dkr.ecr.us-east-1.amazonaws.com
# Токен дійсний протягом 12 годин

Для навантажень ECS та EKS вам не потрібно обробляти автентифікацію вручну. ECS автоматично завантажує образи, використовуючи роль виконання задачі (task execution role). Вузли EKS використовують профіль екземпляра (instance profile) або IRSA.

Збірка та завантаження образів

Розділ «Збірка та завантаження образів»

Повний воркфлоу від Dockerfile до ECR:

Terminal window
# Крок 1: Збірка образу локально
docker build -t myapp/api:v1.3.0 .
# Крок 2: Тегування для ECR
docker tag myapp/api:v1.3.0 \
123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp/api:v1.3.0
# Крок 3: Завантаження в ECR
docker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp/api:v1.3.0

Стратегії тегування та незмінність (Immutability)

Розділ «Стратегії тегування та незмінність (Immutability)»

Тегування — це місце, де більшість команд припускаються помилок.

Незмінність тегів (Tag Immutability)

Розділ «Незмінність тегів (Tag Immutability)»

Якщо незмінність тегів увімкнена, то після того, як ви завантажили образ із певним тегом, цей тег не можна перезаписати. Це критично для безпеки продакшну.

Terminal window
# Увімкнення незмінності для існуючого репозиторію
aws ecr put-image-tag-mutability \
--repository-name myapp/api \
--image-tag-mutability IMMUTABLE
# Тепер спроба пушу тегу v1.3.0, який уже існує, завершиться ПОМИЛКОЮ

Це гарантує, що v1.3.0 завжди посилається на один і той самий код. Це робить відкати (rollbacks) надійними.

Рекомендована стратегія тегування

Розділ «Рекомендована стратегія тегування»

Для продакшну тегуйте кожен образ одночасно семантичною версією та Git SHA. Використовуйте latest тільки як зручний вказівник, який застосовується поруч із версіонованим тегом.

Примітка: latest та IMMUTABLE несумісні, бо latest має змінюватися при кожному пуші. Рішення: використовувати IMMUTABLE для версій і не використовувати latest у цих репозиторіях, або тримати репозиторії mutable, але контролювати версійність через CI.


Сканування на вразливості

Розділ «Сканування на вразливості»

ECR пропонує два рівні сканування: Basic та Enhanced.

Використовує open-source двигун Clair для пошуку відомих CVE в пакетах операційної системи. Безкоштовно.

Terminal window
# Увімкнення сканування при завантаженні (push)
aws ecr put-image-scanning-configuration \
--repository-name myapp/api \
--image-scanning-configuration scanOnPush=true
# Отримання результатів
aws ecr describe-image-scan-findings \
--repository-name myapp/api \
--image-id imageTag=v1.3.0

Використовує Amazon Inspector і забезпечує глибший аналіз, включаючи вразливості залежностей додатків (npm, pip, maven тощо). Платно, але знаходить значно більше проблем.


Правила життєвого циклу (Lifecycle Policies)

Розділ «Правила життєвого циклу (Lifecycle Policies)»

Без правил життєвого циклу ваше сховище ECR росте безкінечно. Кожен білд у CI створює новий образ, і старі образи накопичуються. При ціні $0.10/ГБ/міс це швидко стає помітним.

Правила життєвого циклу дозволяють автоматично видаляти старі образи.

Terminal window
# Приклад правила: зберігати останні 10 образів із префіксом "v"
aws ecr put-lifecycle-policy \
--repository-name myapp/api \
--lifecycle-policy-text '{
"rules": [
{
"rulePriority": 1,
"description": "Зберігати останні 10 версій",
"selection": {
"tagStatus": "tagged",
"tagPrefixList": ["v"],
"countType": "imageCountMoreThan",
"countNumber": 10
},
"action": { "type": "expire" }
}
]
}'

  1. ECR зберігає образи в S3, але ви не бачите цих бакетів. Кожен шар образу зберігається як окремий об’єкт S3 і дедуплікується в межах акаунта та регіону. Якщо п’ять ваших репозиторіїв використовують однаковий базовий шар (напр., ubuntu:22.04), цей шар зберігається лише один раз. Це економить 40-60% місця.

  2. ECR pull-through cache дозволяє вашому реєстру працювати як проксі для публічних реєстрів (Docker Hub, Quay.io). Це захищає вас від лімітів Docker Hub (100 пулів на 6 годин) та прискорює завантаження за рахунок локального кешування.

  3. Amazon Inspector може знаходити вразливості в 15+ мовах програмування, а не тільки в пакетах ОС. Образ Node.js може мати 3 вразливості в системі та 28 — у npm-пакетах. Basic сканування знайде тільки 3, Enhanced — усі 31.


ПомилкаЧому це стаєтьсяЯк виправити
Тег latest як єдиний тегЦе дефолт Docker і здається простимЗавжди тегуйте версією або Git SHA. latest — тільки для зручності
Забули про авторизаціюТокени ECR діють лише 12 годинДодайте aws ecr get-login-password на початок кожного CI-конвеєра
Немає правил життєвого циклуКоманди не думають про ціну сховищаНалаштуйте видалення старих образів (напр. залишати останні 20) з першого дня
Зміна тегів у продакшніЦе дефолт ECR, і це небезпечноУвімкніть IMMUTABLE теги для продакшн репозиторіїв
Пуш образів через регіониОбраз у США, а кластер в ЄвропіНалаштуйте реплікацію ECR. Міжрегіональний pull дорогий та повільний

1. Чому не можна використовувати тег `latest` разом із увімкненою незмінністю тегів (IMMUTABLE)?

Незмінність тегів означає, що як тільки тег призначено образу, його не можна перепризначити іншому образу. Тег latest за конвенцією має завжди вказувати на останній завантажений образ — тобто він має перезаписуватися при кожному пуші. Ці дві концепції суперечать одна одній. Якщо ви один раз завантажите latest в immutable-репозиторій, усі наступні спроби пушу цього тегу будуть відхилені.

2. Як ECR допомагає економити на зберіганні схожих образів?

Завдяки дедуплікації шарів. Образи складаються з шарів, і ECR зберігає кожен унікальний шар лише один раз в межах регіону. Якщо ви маєте 50 мікросервісів на базі одного образу Python, базові шари Python будуть займати місце лише одного образу, а не п’ятдесяти.


Практична вправа: Збірка, завантаження та сканування

Розділ «Практична вправа: Збірка, завантаження та сканування»

У цій вправі ви створите репозиторій ECR, завантажите туди образ, перевірите результати сканування та налаштуєте правила очищення.

Terminal window
# 1. Створення репозиторію з найкращими практиками
aws ecr create-repository \
--repository-name kubedojo/exercise \
--image-scanning-configuration scanOnPush=true \
--image-tag-mutability IMMUTABLE
# 2. Авторизація Docker (замініть регіон та ID акаунта)
aws ecr get-login-password --region us-east-1 | \
docker login --username AWS --password-stdin YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com
# 3. Збірка та пуш (використовуйте будь-який локальний Dockerfile)
docker build -t YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kubedojo/exercise:v1.0.0 .
docker push YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/kubedojo/exercise:v1.0.0
# 4. Перегляд результатів сканування
aws ecr describe-image-scan-findings \
--repository-name kubedojo/exercise \
--image-id imageTag=v1.0.0

Далі: Модуль 1.7: Elastic Container Service (ECS) та Fargate — тепер, коли ви вмієте зберігати образи, час їх запускати. Ви навчитеся розгортати контейнери в AWS за допомогою ECS та безсерверного рушія Fargate.