Опубликовать образ приложения в ECR

AWSBeginner
Практиковаться сейчас

Введение

Ваша команда готовит небольшое HTTP-приложение к поставке. Упакуйте предоставленный код в образ контейнера, сохраните его в Amazon Elastic Container Registry (ECR) и докажите, что именно сохранённая версия запускается и отвечает на запрос. Не изменяйте отдельный эталонный репозиторий и в конце удалите созданные вами ресурсы.

Сначала пройдите AWS Foundations и основы политик идентификации IAM. Понятия Docker объясняются здесь; писать приложение или иметь личный аккаунт AWS не требуется. Независимая VM предоставляет настроенную AWS CLI, Docker, Dockerfile и исходный код. В верхней области AWS View наблюдайте за репозиториями и тестируйте приложение, а в нижней Terminal выполняйте команды. Обе области читают одно состояние ресурсов.

Связь с сертификацией

Сертификация Задача экзамена Практика
Developer – Associate (DVA-C02) Задача 3.1, навык 3.1.1 Упаковать код приложения и среду выполнения в образ контейнера для развёртывания.

Обзор лабораторной работы

Концептуальная схема: собрать приложение, отправить образ в ECR, затем получить точный digest и запустить Docker-контейнер, отвечающий на HTTP.

Создать неизменяемый репозиторий образов

На этом шаге создайте репозиторий для версии приложения.

Образ объединяет файлы приложения и среду выполнения. Контейнер — работающий экземпляр образа. Реестр хранит и распространяет образы; репозиторий ECR группирует образы одного приложения. Сохранение образа не запускает приложение.

Перейдите в подготовленную рабочую папку и изучите Dockerfile. cat выводит текстовый файл:

cd /home/labex/project
cat application/Dockerfile

FROM выбирает базовый образ Python, COPY добавляет приложение, USER выбирает непривилегированного пользователя, а CMD задаёт команду запуска. Базовая ссылка sha256 фиксирует содержимое базового образа, а не вашего нового образа приложения.

Создайте ct-demo. Тег — читаемое имя, например release-1. IMMUTABLE запрещает заменять существующий тег другим содержимым и сохраняет надёжность имён версий:

aws ecr create-repository \
  --repository-name ct-demo \
  --image-tag-mutability IMMUTABLE

Ответ содержит repositoryUri, адрес для Docker, и imageTagMutability: IMMUTABLE. Сохраните URI в переменной оболочки. $(...) захватывает вывод команды, --query выбирает поле, а --output text возвращает его без кавычек JSON:

REPOSITORY_URI=$(aws ecr describe-repositories \
  --repository-names ct-demo \
  --query 'repositories[0].repositoryUri' \
  --output text)
echo "$REPOSITORY_URI"

Не закрывайте эту сессию Terminal, чтобы сохранить переменные. В верхней AWS View должен появиться ct-demo с нулём образов рядом с ct-reference. Эталонный репозиторий принадлежит другому приложению и не входит в область очистки.

Собрать и опубликовать версию

На этом шаге соберите предоставленное приложение и отправьте образ в ECR.

Перед отправкой Docker должен войти в реестр. Адрес реестра — часть URI до первой косой черты. ${REPOSITORY_URI%%/*} удаляет её и всё после неё:

REGISTRY=${REPOSITORY_URI%%/*}
echo "$REGISTRY"

Получите временный пароль ECR через AWS CLI и передайте его напрямую Docker. Канал | направляет вывод следующей команде; --password-stdin не позволяет паролю попасть в аргументы или вывод Terminal. Не выводите и не сохраняйте его самостоятельно:

aws ecr get-login-password | docker login \
  --username AWS \
  --password-stdin "$REGISTRY"

Docker выводит Login Succeeded. Это разрешает операции, доступные вашей идентификации, но не доступ ко всем репозиториям.

Соберите образ из application. -t присваивает URI и тег версии. Последний аргумент — контекст сборки, каталог с файлами, доступными для COPY:

docker build -t "${REPOSITORY_URI}:release-1" application

Отправьте образ. Docker загружает слои файловой системы и manifest, описывающий содержимое:

docker push "${REPOSITORY_URI}:release-1"

В конце Docker выводит digest sha256:.... Digest идентифицирует точное содержимое, а тег — имя. Даже если репозиторий разрешает менять теги, digest остаётся связанным с исходным содержимым.

Запросите ECR, чтобы подтвердить сохранённую версию:

aws ecr describe-images \
  --repository-name ct-demo \
  --image-ids imageTag=release-1 \
  --query 'imageDetails[0].{Tags:imageTags,Digest:imageDigest}'

Также сохраните digest в переменной:

IMAGE_DIGEST=$(aws ecr describe-images \
  --repository-name ct-demo \
  --image-ids imageTag=release-1 \
  --query 'imageDetails[0].imageDigest' \
  --output text)

Digest ECR должен совпадать с выводом docker push. В верхней AWS View репозиторий ct-demo содержит release-1 и его digest. Приложение ещё не работает; вы запустите его далее.

Запустить точный опубликованный образ

На этом шаге получите образ по digest и проверьте настоящий контейнер приложения.

Сначала удалите локально собранный образ. docker image rm удаляет локальную ссылку, но не образ в ECR. Следующая загрузка получит опубликованную версию:

docker image rm "${REPOSITORY_URI}:release-1"

Объедините URI и digest через @, чтобы выбрать точное содержимое:

docker pull "${REPOSITORY_URI}@${IMAGE_DIGEST}"

Docker сообщает тот же digest и успешную загрузку. Запустите его как ct01-app. --detach запускает в фоне; --publish 127.0.0.1:8081:8000 связывает порт хоста 8081 с портом приложения 8000. Loopback ограничивает прямой доступ этой VM. В образе уже выбран непривилегированный пользователь; --read-only делает корневую файловую систему доступной только для чтения, --cap-drop ALL удаляет Linux capabilities, а no-new-privileges запрещает получать дополнительные привилегии:

docker run --detach \
  --name ct01-app \
  --read-only \
  --cap-drop ALL \
  --security-opt no-new-privileges \
  --memory 256m \
  --publish 127.0.0.1:8081:8000 \
  "${REPOSITORY_URI}@${IMAGE_DIGEST}"

ID контейнера означает, что Docker принял запуск, но не доказывает исправность приложения. Проверьте HTTP: curl --fail завершается ошибкой при HTTP-ошибке; --retry-all-errors повторяет ошибки подключения при запуске, включая краткий сброс соединения:

curl --fail --silent --show-error \
  --retry 5 --retry-all-errors --retry-delay 1 \
  http://127.0.0.1:8081/

Ожидайте JSON с "release": "release-1" и именем хоста контейнера. Посмотрите журналы, чтобы подтвердить настоящий запрос:

docker logs ct01-app

Должно появиться served application request. Имя хоста и время могут отличаться. В верхней AWS View выберите Request application. Ответ также должен содержать release-1; кнопка отправляет настоящий HTTP-запрос контейнеру.

Настоящий снимок AWS View: ECR содержит release-1 и его digest, а Docker-приложение отвечает той же версией. Digest и имя хоста — примеры из этого запуска.

Удалить ресурсы приложения

На этом шаге остановите приложение и удалите его локальный образ и репозиторий ECR, сохранив эталонный репозиторий.

Сначала остановите контейнер:

docker stop ct01-app

Затем удалите его. Удаление контейнера не удаляет образ:

docker rm ct01-app

Теперь работающих контейнеров, использующих образ, нет; удалите локальную ссылку по digest:

docker image rm "${REPOSITORY_URI}@${IMAGE_DIGEST}"

Удалите образ из ECR по digest. imageDigest выбирает точное содержимое независимо от тега:

aws ecr batch-delete-image \
  --repository-name ct-demo \
  --image-ids imageDigest="$IMAGE_DIGEST"

Ответ должен перечислить удалённый образ в imageIds и пустой список failures. Удалите теперь пустой репозиторий приложения:

aws ecr delete-repository --repository-name ct-demo

Убедитесь, что эталонный репозиторий сохранился:

aws ecr describe-repositories \
  --query 'repositories[].repositoryName'

Ожидайте только ct-reference. В завершение удалите сохранённую Docker авторизацию в реестре:

docker logout "$REGISTRY"

В верхней AWS View должны исчезнуть ct-demo и контейнер приложения, а эталонный репозиторий — остаться. Одна лишь HTTP-ошибка не доказывает очистку: вы также проверили инвентарь и удалили настоящий контейнер и образ.

Резюме

Вы создали неизменяемый репозиторий ECR, собрали и опубликовали образ, сравнили digest и запустили именно эту версию. Вы проверили настоящие ответы HTTP и журналы, затем удалили свой контейнер, локальный образ и репозиторий, сохранив репозиторий другого приложения. Следующая лабораторная работа использует определение задачи ECS для выбора и запуска образа.

Подробнее см. в документации AWS: Аутентификация реестра и отправка образов; Предотвращение перезаписи тегов образов.