Поиск по сайту:

Автоматизация непрерывной доставки в контейнерах с помощью CodeBuild, ECR и CodeDeploy


Непрерывная интеграция/непрерывная доставка (CI/CD) — это процесс автоматизации обновлений приложений, от изменений в системе управления версиями до автоматизированных сборок и автоматизированных развертываний на ваших серверах. AWS предоставляет для этого сервис под названием CodePipeline, который можно настроить для работы с контейнерами.

Непрерывная доставка в контейнерах

Контейнеры немного сложнее, чем традиционные приложения. Многие контейнерные приложения фактически используют два образа контейнера. Первый, называемый базовым образом, представляет собой пользовательский образ AMI с предварительно загруженными зависимостями и другими приложениями. Это сделано для ускорения сборки, потому что, если вы просто обновляете код своего приложения, вам не нужно переустанавливать NGINX и любое другое программное обеспечение в контейнере. Второй образ — это реальный образ приложения, который расширяет базовый образ и содержит ваш собственный код.

Таким образом, конвейер CI/CD, который мы настроим, фактически будет состоять из двух конвейеров. Первый будет следить за изменениями в базовом образе и запускать перестройку и обновление ECR, когда это произойдет. Второй конвейер будет содержать два исходных этапа: один отслеживает изменения в репозитории ECR базового образа, а другой отслеживает обновления в исходном коде образа приложения. Таким образом, если вы просто обновляете образ приложения, базовый образ не нуждается в перестроении.

С двумя конвейерами CodePipeline будет запускать обновления приложений одним из двух способов:

  • Изменения в образе приложения вызовут перестроение образа приложения с использованием последнего базового образа, который не нужно перестраивать. Обновление будет отправлено в ECR с необязательным развертыванием в ECS или другой контейнерной службе.
  • Изменения в базовом образе вызовут повторную сборку базового образа, которая развернет обновления в ECR. Это, в свою очередь, вызовет перестроение образа приложения, который будет отправлен в ECR, а затем в ECS.

Однако эта двухконвейерная установка может понадобиться не всем приложениям, и если вы просто используете готовый базовый образ ОС, такой как Ubuntu, вам понадобится только один конвейер для обработки всего.

Настройка роли IAM

Во-первых, вам нужно настроить роль службы, чтобы предоставить CodeBuild необходимые разрешения для взаимодействия с другими службами AWS (например, ECR) от вашего имени. Откройте консоль управления IAM, затем создайте новую роль в разделе «Роли». Выберите «AWS Service» и выберите CodeBuild в списке.

Для политик вам нужно создать новую политику со следующими разрешениями:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "CloudWatchLogsPolicy",
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "CodeCommitPolicy",
      "Effect": "Allow",
      "Action": [
        "codecommit:GitPull"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "S3GetObjectPolicy",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:GetObjectVersion"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "S3PutObjectPolicy",
      "Effect": "Allow",
      "Action": [
        "s3:PutObject"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "ECRPullPolicy",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchCheckLayerAvailability",
        "ecr:GetDownloadUrlForLayer",
        "ecr:BatchGetImage"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "ECRAuthPolicy",
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken"
      ],
      "Resource": [
        "*"
      ]
    },
    {
      "Sid": "S3BucketIdentity",
      "Effect": "Allow",
      "Action": [
        "s3:GetBucketAcl",
        "s3:GetBucketLocation"
      ],
      "Resource": 
        "*"
    }
  ]
}

Вставьте это на вкладке JSON в редакторе политик. Дайте ему имя и прикрепите к роли. Вы также можете прикрепить готовую политику,  AmazonEC2ContainerRegistryPowerUser.

Как только эти две политики присоединены, дайте роли имя и нажмите «Создать».

Настройка системы управления версиями и CodeBuild

CodePipeline поддерживает извлечение обновлений кода из GitHub, BitBucket и собственной системы управления версиями CodeCommit AWS. У вас будет лучший опыт использования CodeCommit в качестве вторичного репозитория выпуска, но GitHub будет работать нормально. Если вы используете GitLab или другого поставщика, вам нужно будет использовать CodeCommit для отправки обновлений.

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

Для базового образа вам нужно создать файл спецификации сборки, по сути, список команд, которые CodeBuild будет выполнять при создании вашего образа. Вы можете ввести это вручную при настройке CodeBuild, но лучше сохранить его в виде файла с именем buildspec.yml в корне репозитория.

Ваша точная конфигурация может варьироваться в зависимости от требований вашего приложения, но она должна выглядеть примерно так:

version: 0.2

phases:
  pre_build:
    commands:
      - echo Logging in to Amazon ECR...
      - aws --version
      - $(aws ecr get-login --region $AWS_DEFAULT_REGION --no-include-email)
      - REPOSITORY_URI=012345678910.dkr.ecr.us-east-1.amazonaws.com/base-image
      - COMMIT_HASH=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)
      - IMAGE_TAG=${COMMIT_HASH:=latest}
  build:
    commands:
      - echo Build started on `date`
      - echo Building the Docker image...
      - docker build -t $REPOSITORY_URI:latest .
      - docker tag $REPOSITORY_URI:latest $REPOSITORY_URI:$IMAGE_TAG
  post_build:
    commands:
      - echo Build completed on `date`
      - echo Pushing the Docker images...
      - docker push $REPOSITORY_URI:latest
      - docker push $REPOSITORY_URI:$IMAGE_TAG

В этом примере выполняется вход в ECR, установка тега изображения на идентификатор сборки CodeBuild, сборка образа Docker, а затем отправка изменений в репозиторий ECR. Вам нужно изменить объявление переменной REPOSITORY_URI, указав URI вашего целевого репозитория ECR.

Сохраните его как buildspec.yml и поместите в корень репозитория базового образа и репозитория образа приложения. Вы можете протестировать свою спецификацию сборки, вручную инициировав сборку из консоли CodeBuild, или просто перейти к настройке конвейера и исправить любые ошибки, которые могут возникнуть.

Настройка конвейера

Приведя в порядок спецификацию сборки, откройте консоль CodePipeline и создайте новый конвейер для базового образа. Дайте ему имя и позвольте ему создать новую роль службы. Для этапа управления исходным кодом выберите тип, который вы используете, а также репозиторий и ветку. При желании вы можете настроить дополнительную ветку для отслеживания релизов, и CodePipeline будет игнорировать изменения в master.

Для этапа сборки выберите «Создать проект». Это вызовет диалоговое окно, в котором вы можете настроить CodeBuild.

Обычно вам нужно связать CodeBuild с системой управления версиями, но это автоматически обрабатывается конвейером при создании нового проекта таким образом. Вам нужно будет настроить среду, в которой выполняется ваша сборка — вы можете выбрать собственный образ Docker, загруженный всеми необходимыми программами для сборки, или вы можете установить их вручную на этапе предварительной сборки вашего buildspec.yml. Если вам не нужно ничего особенного, вы можете выбрать Amazon Linux 2 и среду выполнения по умолчанию, которая поставляется с большинством сред выполнения языков программирования, а также предустановленным Docker.

Вы также захотите выбрать роль службы, которую вы создали ранее:

Наконец, вы можете вручную изменить имя файла buildspec, если вы не хотите, чтобы он находился в корневом каталоге исходного кода или если вам нужно различать несколько файлов. Вы также можете вставить сюда команды сборки вручную, но мы советуем отслеживать это как файл на git.

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

Настройка конвейера образов приложений

Далее вы настроите дополнительный конвейер для образа вашего приложения. Создайте новый конвейер из консоли и выберите «ECR» в качестве источника. Выберите базовый репозиторий образов и оставьте тег изображения пустым, что по умолчанию будет последним.

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

Этап развертывания является необязательным. Без этого изменения в базовом образе или образе приложения просто вызовут перестройку образа приложения и отправку изменений в ECR. Однако, если вы используете ECS для развертывания, вы можете добавить еще один этап, который возьмет созданный вами образ и обновит ваши серверы.

В любом случае нажмите «Создать», чтобы создать конвейер. Некоторые изменения необходимы, прежде чем он заработает, поэтому нажмите «Редактировать» в конвейере, затем «Редактировать этап» для этапа управления исходным кодом:

В нынешнем виде этап управления исходным кодом просто извлекает базовый образ из ECR. Это необходимо, но ему также нужен код приложения, чтобы делать что-то полезное, а также реагировать на изменения в коде приложения (а не только в базовом образе).

Нажмите «Добавить действие:»

Выберите CodeCommit (или другой элемент управления исходным кодом) в качестве типа действия и выберите свой репозиторий и ветку. Для «Выходных артефактов» вам нужно ввести SourceArtifact , чтобы обозначить, что это исходный код приложения.

Вы также можете отредактировать этап ECR, указав, что выходным артефактом является Base Image.

Это должно быть все, что нужно для запуска CodeBuild, и как только вы обновите свой конвейер, он должен снова запуститься, надеюсь, без ошибок.

Если вы столкнулись с ошибками, вероятно, ваша спецификация сборки для CodeBuild работает неправильно. Вы можете просмотреть журналы сборки в консоли CodeBuild или обратиться к Справочнику по спецификациям сборки AWS для получения дополнительной информации о том, как все это работает.