Модуль 1.6: Elastic Container Registry (ECR)
Складність: [MEDIUM]
Розділ «Складність: [MEDIUM]»Час на виконання: 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 Private | ECR Public |
|---|---|---|
| Формат URL | {account_id}.dkr.ecr.{region}.amazonaws.com | public.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.
Автентифікація
Розділ «Автентифікація»# Стандартний шлях: передача токена ECR безпосередньо в docker loginaws 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:
# Крок 1: Збірка образу локальноdocker build -t myapp/api:v1.3.0 .
# Крок 2: Тегування для ECRdocker tag myapp/api:v1.3.0 \ 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp/api:v1.3.0
# Крок 3: Завантаження в ECRdocker push 123456789012.dkr.ecr.us-east-1.amazonaws.com/myapp/api:v1.3.0Стратегії тегування та незмінність (Immutability)
Розділ «Стратегії тегування та незмінність (Immutability)»Тегування — це місце, де більшість команд припускаються помилок.
Незмінність тегів (Tag Immutability)
Розділ «Незмінність тегів (Tag Immutability)»Якщо незмінність тегів увімкнена, то після того, як ви завантажили образ із певним тегом, цей тег не можна перезаписати. Це критично для безпеки продакшну.
# Увімкнення незмінності для існуючого репозиторію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.
Basic Scanning
Розділ «Basic Scanning»Використовує open-source двигун Clair для пошуку відомих CVE в пакетах операційної системи. Безкоштовно.
# Увімкнення сканування при завантаженні (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.0Enhanced Scanning
Розділ «Enhanced Scanning»Використовує Amazon Inspector і забезпечує глибший аналіз, включаючи вразливості залежностей додатків (npm, pip, maven тощо). Платно, але знаходить значно більше проблем.
Правила життєвого циклу (Lifecycle Policies)
Розділ «Правила життєвого циклу (Lifecycle Policies)»Без правил життєвого циклу ваше сховище ECR росте безкінечно. Кожен білд у CI створює новий образ, і старі образи накопичуються. При ціні $0.10/ГБ/міс це швидко стає помітним.
Правила життєвого циклу дозволяють автоматично видаляти старі образи.
# Приклад правила: зберігати останні 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" } } ] }'Чи знали ви?
Розділ «Чи знали ви?»-
ECR зберігає образи в S3, але ви не бачите цих бакетів. Кожен шар образу зберігається як окремий об’єкт S3 і дедуплікується в межах акаунта та регіону. Якщо п’ять ваших репозиторіїв використовують однаковий базовий шар (напр.,
ubuntu:22.04), цей шар зберігається лише один раз. Це економить 40-60% місця. -
ECR pull-through cache дозволяє вашому реєстру працювати як проксі для публічних реєстрів (Docker Hub, Quay.io). Це захищає вас від лімітів Docker Hub (100 пулів на 6 годин) та прискорює завантаження за рахунок локального кешування.
-
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, завантажите туди образ, перевірите результати сканування та налаштуєте правила очищення.
# 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.