Як видалити AWS ECR без тегів і старіші зображення?

Керування образами контейнерів в Amazon ECR: Чистка застарілих та непозначених зображень

Amazon ECR (Elastic Container Registry) тісно інтегрований з такими сервісами AWS, як Amazon Elastic Kubernetes Service (Amazon EKS), Amazon Elastic Container Service (Amazon ECS) та AWS Lambda, забезпечуючи безперебійний робочий процес від розробки до запуску в експлуатацію.

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

Сучасні застосунки часто будуються на основі мікросервісної архітектури. Мікросервіс – це, по суті, контейнер, який містить весь необхідний код та залежності, що дозволяє додатку працювати швидко та надійно в будь-якому обчислювальному середовищі. Завдяки своїй мобільності, компактності та зручності, контейнери стали основним засобом розповсюдження сучасних застосунків.

Контейнери створюються на основі шаблону, що доступний лише для читання, який називається образом. Ці образи необхідно десь зберігати, щоб вони були доступні для будь-якої авторизованої машини.

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

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

Щодня численні застосунки, розміщені на AWS, завантажують та передають мільйони образів/артефактів у відповідні репозиторії ECR та з них.

У цій статті ми розглянемо методи очищення застарілих та непотрібних образів AWS ECR, а також підтримання чистоти ваших репозиторіїв ECR.

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

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

Простіше кажучи, будь-які образи/артефакти, створені більше п’яти разів, зазвичай вважаються зайвими. Це правило може коригуватися згідно з політикою вашої організації, але в загальному випадку, це не рекомендована практика.

В індустрії програмного забезпечення, теги використовуються для позначення останніх стабільних або останніх п’яти образів. У процесі розробки, образи створюються швидко, і ці теги постійно замінюються новими образами, залишаючи старі образи без тегів і, як наслідок, непотрібними.

Коли ці образи/артефакти мають великий розмір, вони також збільшують ваші витрати на зберігання в ECR. Вартість зберігання в AWS ECR становить “0,10 долара США за ГБ на місяць для даних, що зберігаються в приватних або публічних репозиторіях”.

Ціна може здаватися незначною, але, як кажуть, з краплі складається океан. Зберігання багатьох таких образів протягом тривалого часу може призвести до значного збільшення ваших рахунків AWS.

Тому, пропозиція полягає в тому, щоб видаляти старі та немарковані образи з репозиторіїв ECR. Навіщо зберігати їх і платити за це, якщо вони вам не потрібні?

Ручне видалення образів AWS ECR

Спосіб 1: Графічний інтерфейс

Крок 1: Увійдіть до свого облікового запису Amazon Web Services і перейдіть до репозиторію, який потрібно очистити.

Крок 2: Ви побачите, що репозиторій містить останній тег, який позначає стабільну версію. Інші теги, що ви бачите, можуть бути непозначеними. Щоб видалити образ, виберіть його і натисніть кнопку “Видалити”.

Крок 3: Підтвердіть видалення.

Спосіб 2: Інтерфейс командного рядка (CLI)

Для видалення образів за допомогою CLI, вам знадобляться налаштовані на вашій машині ключі доступу AWS IAM, а також необхідні дозволи IAM для доступу до репозиторіїв.

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

Щоб переконатися, що AWS CLI налаштовано на вашій машині, використайте команду:

aws sts get-caller-identity

Після підтвердження працездатності AWS CLI, використайте наступну команду для видалення немаркованих образів ECR:

aws ecr batch-delete-image --repository-name test-ecr-policy --image-ids imageTag=custom-image-6

Тут ми виконуємо аналогічну дію, як у графічному інтерфейсі. Ми видаляємо образ з тегом `custom-image-6` з репозиторію `test-ecr-policy`.

Спосіб 3: Скрипт

Для цього методу, на вашій машині має бути налаштовано ключ доступу AWS.

Нижче наведено приклад скрипту для видалення немаркованих образів:

import boto3

client = boto3.client('ecr')

response = client.list_images(repositoryName="test-ecr-policy")

untaggedImageList = [image for image in response['imageIds'] if image['imageTag'] == 'custom-build-4']

response2 = client.batch_delete_image(repositoryName="aws-test-ecrpolicy", imageIds=untaggedImageList)

print(response2)

У відповіді буде список ідентифікаторів видалених образів, а також повідомлення про помилки, якщо вони є.

Планове видалення образів ECR

Якщо ви є інженером DevOps або регулярно працюєте з AWS ECR, ви розумієте, наскільки важким може бути ручне видалення образів.

Хоча використання скриптів/команд спрощує цю задачу, ідеальним варіантом було б автоматичне видалення цих образів, без необхідності втручання з вашого боку.

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

Спосіб 1: Графічний інтерфейс

Крок 1: Перейдіть до репозиторію, для якого ви хочете налаштувати політику життєвого циклу. На панелі зліва ви побачите розділ “Політика життєвого циклу”. Натисніть на нього, щоб почати.

Крок 2: Натисніть, щоб створити перше правило.

Крок 3: ECR дозволяє видаляти образи за двома умовами: коли образи стають старшими за вказану кількість днів, або якщо вони позначені/не позначені і ви хочете зберігати їх лише протягом певного періоду часу (наприклад, X днів).

Давайте подивимося, як це зробити. Ви можете налаштувати видалення немаркованих образів, якщо вони старші за один день або якщо кількість немаркованих образів перевищує одиницю.

Виберіть налаштування, які відповідають вашим потребам. Пам’ятайте, що ці значення можна збільшити. Збережіть зміни, щоб активувати правило життєвого циклу.

Спосіб 2: Інтерфейс командного рядка (CLI)

Команда AWS ECR CLI для встановлення політики життєвого циклу – `put-lifecycle-policy`.

Для початку потрібно створити JSON файл, що містить умови політики. Ви можете назвати його `policy.json` або як вам зручно.

Перш ніж ми почнемо, розглянемо елементи політики життєвого циклу:

rulePriority (Тип: integer, Обов'язково: так):

Порядок правил від нижчого до вищого. Правила застосовуються в порядку зростання пріоритету, починаючи з 1. Кожне правило повинно мати унікальне значення пріоритету.

Правила не повинні мати послідовні значення пріоритету. Будь-які правила з тегами повинні мати найвищий пріоритет і перевірятися в останню чергу.

description (Тип: string, Обов'язково: ні):

Опис призначення правила в політиці життєвого циклу.

tagStatus (Тип: string, Обов'язково: так):

Визначає, чи застосовується правило політики життєвого циклу до тегованих образів, нетегованих образів або до всіх образів. Якщо нічого не вказано, оцінюються всі образи. Якщо вказано “tagged”, потрібне значення `tagPrefixList`. Якщо вказано “untagged”, поле `tagPrefixList` потрібно опустити.

tagPrefixList (Тип: list[string], Обов'язково: так, тільки якщо tagStatus встановлено як tagged):

Якщо `tagStatus` встановлено як “tagged”, ваша політика життєвого циклу вимагає переліку префіксів тегів зображень, розділених комами.

Використовуючи префікс тегу “prod”, ви можете вибрати всі образи, позначені як “prod”, “prod1”, “prod2” тощо. Кілька тегів вибирають лише зображення, які мають всі теги.

countType (Тип: string, Обов'язково: так):

Вкажіть `countNumber`, якщо `countType` має значення `imageCountMoreThan`, щоб обмежити кількість образів у вашому репозиторії.

Вкажіть `countUnit` і `countNumber`, якщо `countType` має значення `SinceImagePushed`, щоб обмежити образи репозиторію за віком.

countUnit (Тип: string, Обов'язково: так, тільки якщо countType встановлено як sinceImagePushed):

Вказуйте одиницю часу, лише якщо `countType` має значення `SinceImagePushed`. Інакше виникне помилка.

countNumber (Тип: integer, Обов'язково: так):

Дозволяються лише додатні цілі числа (0 не є прийнятним значенням). Якщо `countType` має значення `imageCountMoreThan`, це значення визначає максимальну кількість образів для збереження. Якщо `countType` встановлено як `SinceImagePushed`, це значення визначає максимальний вік образу.

type (Тип: string, Обов'язково: так):

Виберіть тип дії. Можливе значення – “expire”.

Ось приклад мого `policy.json`:

{
"rules": [
{
"rulePriority": 1,
"description": "Expire images older than 10 days",
"selection": {
"tagStatus": "untagged",
"countType": "sinceImagePushed",
"countUnit": "days",
"countNumber": 14
},
"action": {
"type": "expire"
}
}
]
}

Налаштуйте його відповідно до вимог вашої організації. `SinceImagePushed` можна замінити на `imageCountMoreThan`.

Команда CLI для застосування цієї політики:

aws ecr put-lifecycle-policy --repository-name "test-ecr-polict" --lifecycle-policy-text "file://policy.json"

Спосіб 3: Скрипт

Для цього методу ми будемо використовувати бібліотеку boto3. Ми можемо використовувати той самий `policy.json` для налаштування. Нижче наведено фрагмент коду:

import boto3

client = boto3.client('ecr')

response = client.put_lifecycle_policy(
registryId='PODES12342',
repositoryName="test-ecr-policy",
lifecyclePolicyText="plicy.json"
)

print(response)

Як застосувати єдину політику до кількох репозиторіїв ECR?

Часто виникає питання, як застосувати одну політику до кількох репозиторіїв.

Налаштування політики вручну є повторюваним і стомлюючим процесом.

Ось фрагмент коду, який можна використовувати для застосування політики до понад 100 репозиторіїв:

from boto3 import Session,client

from os import getenv
AWS_ACCESS_KEY_ID = getenv("ACCESSKEY")

AWS_SECRET_ACCESS_KEY = getenv("SECRETKEY")
session = Session(
aws_access_key_id=AWS_ACCESS_KEY_ID,
aws_secret_access_key=AWS_SECRET_ACCESS_KEY
)

client = client('ecr')

response = client.describe_repositories()

repositories = response['repositories']

globalLifecyclePolicy = 'put your policy here’’

for repo in repositories:

repoName = repo['repositoryName']

client.put_lifecycle_policy( repositoryName = repoName,lifecyclePolicyText = globalLifecyclePolicy)

Висновок

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

Ви також можете експериментувати з альтернативними правилами для тегованих образів, наприклад, узгоджувати критерії з датою завантаження образу.

Ознайомтеся з ключовими термінами AWS, що допоможуть вам у навчанні.