Рубрики
Uncategorized

Глубокое погружение на AWS CodeBuild

Настройка автоматического развертывания для вашего Docker + ECS. Помечено с AWS, DevOps, CodeBuild, Docker.

В последние 2 поста мы построили приложение Rails в Docker и развернули его в Amazon ECS. В этом посте мы будем использовать AWS CodeBuild для автоматизации изображения докеров и развертываний в ECS.

Этот пост не нужен, чтобы настроить функциональный конвейер Ci/CD для нашего приложения Rails. Это кодовая печь гораздо короче и поднимает вас и бежит быстрее. Но если вы хотите иметь более глубокое понимание CodeBuild, прочитайте вдоль

Мы будем использовать Рельсы Для этого поста блога. Если вы используете другие веб-каркасы (I.E Sinatra, Django, Flask, и т. Д.), этот пост блога может служить ссылкой на автоматизацию ваших развертываний в ECS.

  • Создание рельсов + веб-приложения Sidekiq в Docker
  • Развертывание рельсов в Amazon ECS
    • Концепции
    • Нажмите на изображение в ECR
    • Создайте базу данных RDS, определение задачи и балансировку нагрузки
    • Создайте кластер ECS и подключите его все вместе
    • Настроить Sidekiq.
  • Автоматизация развертываний с AWS CodeDey
    • Глубокое погружение на AWS CodeBuild — мы здесь

CodeBuild это полностью управляемая сборка в облаке. Это устраняет необходимость в Создание серверов , которые находятся на 24/7, но используются всего несколько минут каждое развертывание.

Развертывание без кодовогобильда

Прежде чем мы понимаем, какой кодовыйБулд может сделать для настройки ECS, мы должны пройти через то, как это похоже на типичное развертывание без него. Шаги здесь просто обзор. Для получения подробного обсуждения о том, как каждый шаг сделан, щелкните по ссылке и перейдите в раздел Указанный:

  • Нажмите свой код в GitHub/Bitbucket
  • (5) Создайте изображение докера через локальную машину — Это также может быть сделано на выделенном сервере сборки.

    • (5.1) Docker Build. -T My-Rails-App — Чтобы создать изображение докера с кодом и зависимостями вашего приложения
    • (5.2) Docker Tag My-Rails-App: последние : v1.0.1 — Обведите свой образ докера с правильным URI. Обратите внимание, что мы увеличивали версию изображения на 0.0.1 (от 1,0 до 1,0,1).
    • (5.3) $ (AWS ECR Get-Login - Inno-Iclee-Email - Megion AP-Southeast-1) — Вход в AWS ECR
    • (5.4) Docker push : v1.0.1 — Нажмите изображение докера в ECR
  • (16) Создайте определение задачи — Измените версию Docker Image от 1,0,0 до 1.0.1 и создайте новую ревизию.

    • Измените версию изображения в определении контейнера
  • (17) Обновите службу, чтобы развернуть последнюю версию определения задач

Развертывание с CodeBuild.

После интеграции CodeBuild наше развертывание теперь уменьшено до 3 шагов:

  • Нажмите свой код в GitHub/Bitbucket
  • Перейдите в CodeBuild, выберите приложение и нажмите «Пуск».
  • (17) Обновите службу, чтобы развернуть последнюю версию определения задач

Преимущества

Если сокращение шагов (от 7 до 3) заставило вас рассмотреть возможность автоматизации ваших развертываний, проверьте эти другие преимущества для определения кодовогобильда:

  • Это уменьшает ручную работу DEV должен сделать для развертывания своих приложений. Таким образом, Devs может сосредоточиться на том, что они делают лучше всего — разрабатывают особенности Отказ
  • Поскольку Devs просто должен нажать свой код и нажать кнопку, мы устраняем риск того, что разработчик допустит ошибку в развертывании.
  • Он также устраняет необходимость в сервере сборки, отсюда, сохраняя на расходы на сервер AWS (не говоря уже о времени, необходимом для поддержания сервера сборки).
  • CodeBuild требует, чтобы каждый разработан AWS IAM пользователь В вашей учетной записи AWS. Это хорошо для подотчетности, поскольку вы знаете в журналах, которые развернули то, что, как и, когда.
  • Это указывает на автоматизированный подход CI/CI/CD, где все, что вам нужно сделать, это толкать ваш код, и он будет развернут в производстве после серии тестов.

Серверы сборки обычно принимают код приложения как вход Отказ Мы настроили Создайте среду сервера иметь необходимые runtimes для создания нашего приложенного кода. Время выполнения может быть Python, Ruby, Docker и т. Д. Мы указываем Серия команд сборки Чтобы создать наш прикладной код и создать пакет, который мы можем развернуть. Для развертываний докеров это докер изображения.

Поскольку CodeBuild — это просто автоматизированная служба сборки, он все еще должен выполнять шаги выше. Однако с CodeBuild вы не управляете серверами, которые делают сборку Отказ Он запускается внутри контейнера Docker с помощью времени выполнения/с, необходимым для создания вашего приложения. Вам просто нужно место для ввода всех этих конфигураций.

Основная концепция в CodeBuild — это проект сборки. Это отвечает четырем вопросам, необходимым для эксплуатации сервера сборки:

Где исходный код?

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

Вы можете иметь свой код в хостах исходного кода: GitHub, Bitbucket или CodeCommit. Вы также можете иметь свой код в S3 (но всерьез, трудно поддерживать кодовую базу, если она только в S3). Вам также будет предложено дать необходимые разрешения. Способ сделать это немного отличается от хоста исходного кода.

Какую среду сборки мы будем использовать?

CodeBuild использует контейнер Docker для создания вашего приложения. Среда сборки определяет какое время выполнения, ОС и инструменты будет в контейнере. Они будут доступны во время вашего процесса сборки.

Конечная цель нашей сборки состоит в том, чтобы изготовить документ Docker из нашего кода приложения. Следовательно, среда сборки, которую мы выберем, должны иметь предварительно установленное Docker.

Какая команда сборки мы будем работать?

Это серия команд, которые вы обычно выполняете во время процесса сборки. Эти команды обычно хранятся в buildspec.yml Отказ

Где мы будем вводить артефакт?

Поскольку мы вытащим изображение Docker в команде сборки, мы ничего не выберете для этой опции.

  • Это предполагает, что у вас есть учетная запись GitHub, и у вас есть настройка хранилища Git. Если нет, вы можете подписаться на учетную запись GitHub здесь и создать репозиторий GitHub здесь Отказ
  • Вы можете следить с приложением, которое мы строили за последние 3 сообщения, загрузив Исходный код Или вы можете применить его к вашему приложению приложения, которое вы развернули в ECS. Поскольку этот пост не имеет никакой конкретной конфигурации Rails/Ruby, которая должна сопровождаться, вы можете следовать через любое приложение, которое вы построили, которые уже созданы сверху докера и развернуты с помощью ECS.
  • Сценарии Ruby мы включаем позже, хорошо документированные и хорошо объясненные. Вам не нужен какой-либо опыт Ruby, чтобы запустить их. Окружающая среда CodeBuild, которую мы будем выбрать уже установленные Ruby 2.5, поэтому сценарии Ruby должны работать просто хорошо.

(3.1) На вкладке «Услуги» ищите CodeBuild и нажмите на нее. На правой части страницы нажмите «Создать проект Build». Убедитесь, что вы находитесь в том же регионе, что и ваш кластер ECS Отказ

(3.2) Поскольку мы выдвинули наше приложение в репозиторий GitHUB, выберите «GitHub» для поставщика источника. Вам будет предложено предоставить GitHub доступ к AWS CodeBuild. Сделайте это, нажав кнопку «Подключиться к GitHub».

(3.3) Войдите в свой аккаунт GitHub

(3.4) Авторизуйте AWS CodeBuild, чтобы получить доступ к вашим репозиториям GitHub, утверждая запрос: «Авторизует AWS-CODESUITE»

(3.5) После этого вы будете направлены обратно в проект по сборке. Добавьте URL-адрес репозитория.

(3.6) Прокрутите вниз до раздела среды.

  • Выберите «Ubuntu» в качестве операционной системы
  • Выберите «Standard» как ваше время выполнения
  • Выберите «AWS/CodeBuild/Standard: 1,0» как изображение. Не выбирайте стандарт: 2.0 Как у этого все еще есть проблемы с Ruby на написании этого поста Отказ
  • Выберите «Всегда используйте новейшее изображение для этой версии выполнения»
  • Обязательно отметьте привилегированную щелчок. Если вы этого не отметите это, мы не сможем построить свой образ докера.
  • Выберите «Новую роль сервиса». Роль, которая будет создана, определит, что ресурсы AWS вы можете получить доступ во время процесса сборки.

(3.7) Вы должны увидеть эту страницу после создания проекта сборки:

Теперь, когда у нас есть проект нашего сборки, мы должны настроить сценарии, чтобы сделать следующее:

  • Обратите внимание, что мы реализовали семантическую версию с нашими изображениями докера. Наша первая версия изображения составляет 1.0.0, следующий — 1.0.1, и так далее. Из-за этого мы должны определить новейшую версию изображения (скажем, это 1.0.0). Мы увеличим 1 к этому, поэтому наша следующая версия изображения станет 1.0.1.
  • Поскольку версия изображения изменилась (от 1.0,0 до 1.0.1), мы должны обновить наше определение задачи. Мы создадим ревизию определения задач с новой версией Docker Image. Если вы не знакомы с определениями задач, я рекомендую прочитать мое предыдущее сообщение в блоге на Концепции ECS Отказ

Для этой задачи я разработал 2 рубиновых фрагмента. Если ваше приложение не в Ruby, все в порядке. Мы все еще можем использовать этот скрипт, поскольку среда CodeBuild мы используем, имеет RUBY Runtime.

(4.1) Создайте папку сценариев в корневом каталоге Rails, используя команду MKDIR сценарии Отказ

(4.2) Создайте файл load_latest_image_version_number.rb В папке скриптов. Скопируйте и вставьте скрипт снизу.

Этот файл ищет новейшую версию изображения, получая все изображения Docker, нажав на то же имя хранилища, зацикливающую каждый, чтобы получить последний тег. Обязательно поменяйте Repository_name Переменная, если ваш репозиторий ECR назван по-разному.

# frozen_string_literal: true

require "aws-sdk-ecr"

# (1) Fetch all Docker images pushed to ECR ever (that's why there's a loop)
# so we can pull the old old ones as well

major_version = "v1"
repository_name = "sample-docker-rails-app"

client = Aws::ECR::Client.new

image_fetcher = client.list_images(repository_name: repository_name)
images = image_fetcher.image_ids
counter = 1

until image_fetcher.next_token.nil?
  counter += 1

  image_fetcher = client.list_images(repository_name: repository_name,
                                     next_token: image_fetcher.next_token)
  images += image_fetcher.image_ids
end

# (2) We only want to look at images with tag "v1.0.x", so filter the others out.

image_tags = images.map(&:image_tag)

relevant_images = image_tags.compact.select do |t|
  c = t.split(".")

  c[-2] == "0" && c[-3] == major_version
end

# (3) Get the max, add 1 and that's the version we use!
latest_series_zero_image = relevant_images.map { |t| t.split(".")[-1].to_i }.max

# (4) Output the version to standard out!
puts "#{major_version}.0.#{latest_series_zero_image + 1}"

(4.3) Создайте файл update_task_definition.rb. В папке скриптов. Скопируйте и вставьте скрипт снизу. Код объясняется в комментариях каждого блока. В этом скрипте вы заметите широкое использование переменных среды. Откуда приходят эти переменные env? Мы определим его в более позднем разделе. На данный момент рассмотрите все из них должным образом.

Этот фрагмент разделен на 4 части. Эти 4 части, вместе, выполните следующие действия:

  • Он читает переменные среды вашей настройки CodeBuild. В части 2, которые предложены ECS_ будет размещен в определении задания.
  • У нас есть 2 определения задач для обновления: Web and Sidekiq. Эти две определения задач на 20% отличаются друг от друга. Мы определяем переменную под названием base_task_definition В части 1 для 80% сходства между этими двумя определениями задач. В каждом определении задачи мы также устанавливаем каждое определение задачи.
  • Для разницы в 20% мы вручную устанавливаем их в части 3. Какова разница в 20%?
    • Команда для запуска веб-сервиса — puma -c config/puma.rb Отказ Для Sidekiq у нас есть sidekiq -c config/sidekiq.yml Отказ
    • Sidekiq и WEB настроены для размещения своих журналов в разных группах журнала в CloudWatch.
    • Имя определения задачи Sidekiq и Web отличаются.
  • Затем мы нажимаем 2 определения задач в AWS, поэтому у нас будет новая ревизия, которую мы можем развернуть.
# frozen_string_literal: true

require "aws-sdk-ecs"

# (PART 1) Define the ECS client, deep_copy method and the base task definition

client = Aws::ECS::Client.new

def deep_copy(o)
  Marshal.load(Marshal.dump(o))
end

base_td = {
            container_definitions: [
              {
                log_configuration: {
                  log_driver: "awslogs",
                  options: {
                    "awslogs-stream-prefix" => "ecs",
                    "awslogs-region" => "ap-southeast-1"
                  }
                },
                port_mappings: [
                  {
                    host_port: 0,
                    protocol: "tcp",
                    container_port: 8080
                  }
                ],
                name: "web"
              }
            ],
            placement_constraints: [],
            memory: "1024",
            cpu: "512",
            volumes: []
          }

# (PART 2) All env variables prepended "ECS_" will be included in the task definition

env_vars = []

relevant_envs = ENV.select { |k, _| k[0..3] == "ECS_" }

relevant_envs.each do |key, value|
  # skip this variable from being included
  next if key == "ECS_CONTAINER_METADATA_URI"

  proper_key = key.gsub("ECS_", "").to_sym
  env_vars << {
    name: proper_key,
    value: value
  }
end

# (PART 3) Define how the web task definition and the Sidekiq task definition differs

log = {
  web: ENV["CLOUDWATCH_WEB_LOG_GROUP"],
  sidekiq: ENV["CLOUDWATCH_SIDEKIQ_LOG_GROUP"],
}

base_td[:container_definitions][0][:image] = "#{ENV['REPO_URL']}:#{ENV['LATEST_VERSION']}"
base_td[:container_definitions][0][:environment] = env_vars

web_td = deep_copy(base_td)
web_td[:container_definitions][0][:command] = ["puma", "-C", "config/docker_puma.rb", "-p", "8080"]
web_td[:container_definitions][0][:log_configuration][:options]["awslogs-group"] = log[:web]
web_td[:container_definitions][0][:name] = "web"
web_td[:requires_compatibilities] = ["EC2"]
web_td[:family] = ENV["TASK_DEFINITION_WEB"]
web_td[:network_mode] = nil

sidekiq_td = deep_copy(base_td)
sidekiq_td[:container_definitions][0][:command] = ["sidekiq", "-C", "config/sidekiq.yml"]
sidekiq_td[:container_definitions][0][:log_configuration][:options]["awslogs-group"] = log[:sidekiq]
sidekiq_td[:container_definitions][0][:name] = "web"
sidekiq_td[:requires_compatibilities] = ["EC2"]
sidekiq_td[:family] = ENV["TASK_DEFINITION_SIDEKIQ"]
sidekiq_td[:network_mode] = nil

# (PART 4) Create a new revision of the web and Sidekiq task definitions

client.register_task_definition(web_td)
client.register_task_definition(sidekiq_td)

(4.4) У нас также есть buildspec.yml Отказ Этот файл необходим для выполнения кодовогобильда для выполнения и необходимости быть внутри корневого каталога вашего приложения. Рассмотрим BuildSpec.yml в качестве набора инструкций, которые вы даете CodeBuild о том, как создать свой образ.

Типичный buildspec.yml Документы имеют 2 основных компонента: (i) версии, а (ii) фазы. Версия всегда 0,2. Порция фаз определяет жизненный цикл типичного процесса сборки. Для нашей настройки мы решили определить жизненный цикл таким образом:

  • Предварительно построение
    • Войдите в AWS ECR
    • Установить AWS-SDK-ECR и AWS-SDK-ECS Отказ Эти рубиггемы будут использоваться скриптом в 4.2 и 4.3.
    • Получите последнюю версию нашего изображения, выполнив скрипт, который мы описали в 4.2
    • Создать Общие/PIDs и Общие/розеты Папка для Puma, чтобы иметь место для хранения его PID.
  • Строить
    • Сделать докер построить и пометить изображение правильно
  • Пост-сборка
    • Нажмите на изображение на Amazon ECR
    • Обновите определение задачи, запустив скрипт, который мы описали в 4.3
version: 0.2 

phases: 
  install:
    runtime-versions:
        docker: 18
    commands:
      - nohup /usr/local/bin/dockerd --host=unix:///var/run/docker.sock --host=tcp://127.0.0.1:2375 --storage-driver=overlay2&
      - timeout 15 sh -c "until docker info; do echo .; sleep 1; done"
  pre_build:
    commands:
    - echo Logging in to Amazon ECR....
    - aws --version
    - $(aws ecr get-login --no-include-email --region $CI_REGION)

    - echo "including rubygems.org as repo"
    - gem sources --add https://rubygems.org/

    - echo "installing aws-sdk-ecr"
    - gem install 'aws-sdk-ecr'

    - echo "installing aws-sdk-ecs"
    - gem install 'aws-sdk-ecs'

    - echo "load the latest ECR image revision number"
    - LATEST_VERSION=$(ruby scripts/load_latest_image_version_number.rb)
    - echo the version now is $LATEST_VERSION

    - echo "Creating folders for pid files"
    - mkdir shared
    - mkdir shared/pids
    - mkdir shared/sockets
  build: 
    commands: 
    - echo Build started on `date`
    - echo Building the Docker image...
    - docker build -t mydockerrepo .

    - docker tag mydockerrepo:latest $REPO_URL:$LATEST_VERSION
  post_build: 
    commands: 
    - echo Build completed on `date` 
    - echo pushing to repo
    - docker push $REPO_URL:$LATEST_VERSION
    - ruby scripts/update_task_definition.rb

(4.4) Отредактируйте домашнюю страницу через VI приложение/просмотры/Home/index.html.erb и добавьте фрагмент в нижней части файла. Это докажет, что наше развертывание через CodeBuild было успешно.

Updated via CodeBuild!

(4.5) Просмотрите изменения, которые вы сделали. Если вы удовлетворены им, совершайте и подтолкнитесь к GitHub.

git add .
git commit -m "Add initial scripts, and change to the HTML part"
git push origin master

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

(5.1) Перейдите на CodeBuild на вкладке «Услуги». Перейдите к строим проектам и ищите проект построения, который мы только что создали. Для меня это названо ruby-docker-приложение. Нажмите «Редактировать» выпадайте и выберите «Окружающую среду».

(5.2) Нажмите «Дополнительную конфигурацию», чтобы открыть раздел переменных среды.

(5.3) Мы разместим переменные среды здесь. У нас есть 2 вида переменных окружающей среды:

  • Переменные, которые мы добавляем в определение задачи — эти переменные должны быть предложены с помощью «ECS_». Это сигналы к скрипту в 4.3, что они будут включены в определение задачи. Следовательно, эти переменные будут доступны для нашего приложения.
    • ECS_POSTGRES_DB , ECS_POSTGRES_HOST , ECS_Postgres_Password , ECS_POSTGRES_USER — Информация о подключении базы данных PostgreSQL.
    • ECS_rails_env — установить на постановку.
    • ECS_RAILS_LOG_TO_STDOUT — Установить, чтобы включить журналы проглатывать CloudWatch
    • Ecs_rails_master_key — установить на главный ключ рельсов
    • ECS_REDIS_URL — Установите URL-адрес Redis
  • Переменные Мы будем использовать исключительно для процесса сборки — эти переменные необходимы для нас для создания изображения, Но мы больше не будем использовать их после Отказ

    • Repo_url.
    • Task_definition_web , Task_definition_sidekiq — Установить имя определения задачи Web и Sidekiq. Для меня это приложение Docker-Rails для Web, и Docker-Rails-App-Sidekiq для Sidekiq.
    • Cloudwatch_web_log_group , Cloudwatch_sidekiq_log_group.
    • CI_REGION — Установите на AP-Southeast-1 или регион, где развернут ваш кластер ECS.

(5.4) После того, как вы сохраните его, вернитесь к проекту сборки и нажмите «Начать сборку».

Вы должны увидеть форму ниже. Для секции источника установите исходную версию на «Master», а затем нажмите «Пуск».

(5.5) Вы должны этот экран. Если вы нажмете «хвостовые журналы», вы увидите много журналов из процесса сборки.

(5.6) Процесс сборки сломается, потому что мы не дали разрешения CodeBuild для доступа к ECR и ECS. В следующем разделе мы создадим необходимые разрешения.

(6.1) Создайте политику IAM. Установите опцию JSON и вставьте этот JSON ниже. Обязательно заменить Your_aws_account_number . с вашим номером счета. Эта политика позволяет создавать изменения определения задач (без полного доступа ECS).

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "ecs:RegisterTaskDefinition",
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "iam:PassRole",
            "Resource": "arn:aws:iam::<>:role/ecsTaskExecutionRole"
        }
    ]
}

(6.2) Просмотрите политику IAM. Как только вы удовлетворены этим, нажмите «Создать политику». Назовите политику «ECS-Policy-Policy-Code-Build».

(6.3) Получите название роли сервисного проекта.

На отдельной вкладке перейдите на страницу проекта Build, нажмите «Изменить выпадение», а затем нажмите «Окружающая среда». Вы должны увидеть роль сервисной службы, как показано ниже:

(6.4) Затем отправляйтесь в IAM роли. Поиск роль IAM, которую вы получили на шаге 6.3. Нажмите на роль.

(6.5) Нажмите Прикреплять политики

(6.6) Поиск и прикрепить Amazonec2containerregistryPowerUser Обеспечить доступ к власти доступа к ECR. Это позволяет нам получить новейшую версию изображения, а также нажать изображения в ECR.

Затем, поиск и прикрепите политику, которую мы создали на шаге 6.2. Если вы следят именно, это должно быть названо ECS-Policy-for-Code-Build Отказ

Ваш роль IAM теперь должен иметь 3 роли.

Теперь наш проект сборки правильно настроен для запуска сборки.

(6.7) Запустите сборку снова, следуя шаге 5.4. Как только это завершено, перейдите в веб-услуги в Интернете и Sidekiq. Вы должны увидеть, что есть новая редакция определения задач (и определение задачи, в настоящее время в этих услугах, теперь устарели).

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

(6.8) Подождите несколько минут. Если все прошло хорошо, вы сможете увидеть обновленную домашнюю страницу с текстом: «Обновлено через CodeBuild!»

Теперь мы можем развернуть нашу приложение ECS Rails через CodeBuild! Как и в случае любого инфраструктурного проекта, основная часть работы во время установки. Но после этого ваши развертывания должны быть намного проще!

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

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

Оригинал: «https://dev.to/raphael_jambalos/automate-docker-build-with-aws-codebuild-9om»