Статьи

Интеграция Elastic Beanstalk, Docker и CircleCI для автоматического развертывания

Мы запускаем некоторые из наших сервисов в контейнерах Docker под Elastic Beanstalk (EB) и используем CircleCI для нашего цикла CI. EB, Docker и CircleCI прекрасно интегрируются для автоматического развертывания.

Довольно легко настроить все сервисы для совместной работы. В этом посте я кратко излагаю шаги для этого.

О приложениях и версиях EB

Elastic Beanstalk имеет концепции приложений, сред и версий приложений. Автоматические шаги, которые я описываю здесь, вплоть до создания новой версии приложения в EB. Фактическое развертывание выполняется вручную с использованием интерфейса управления Elastic Beanstalk. Я тоже это описываю.

Сделать этот последний шаг автоматически легко, и я добавлю пост об этом в будущем.

Я не собираюсь описывать цикл CI (тестирование, автоматизация и т. Д.). Это совершенно другая, очень важная тема, но она выходит за рамки этого поста. Подключение GitHub к circleci также выходит за рамки этого поста.

Архитектура

Мне нужно интегрировать четыре разных сервиса:

  • circleci — сервис непрерывной интеграции (и развертывания).
  • Докер-хаб — это то место, куда загружаются изображения Docker.
  • AWS — Elastic Beanstalk (EB) , сервис Amazon, который хорошо интегрируется с Docker.
  • AWS S3 . Сервис хранения Amazon.

Основной поток

Все начинается с push в GitHub (который я не включил в список выше). Как только мы что-то добавляем в GitHub, запускается circleci и запускается на основе circle.ymlфайла. CI создаст образ Docker и загрузит его в Docker-hub. Мы используем частный репозиторий. Следующим шагом CI загрузит специальный файл json на S3. Этот файл сообщит EB, откуда взять изображение, изображение и другие параметры. В качестве последнего шага, для доставки, он создаст новую версию приложения в EB.

Диаграмма процесса

CI Docker EB Развертывание Архитектура высокого уровня

Описание и схема выше относятся к части развертывания от CI (GitHub) до AWS (EB). Это не описывает последнюю часть для развертывания новой версии приложения в EB. Я опишу это позже в этом посте.

права доступа

В посте описывается, как работать с частным репозиторием в Docker Hub. Чтобы работать с закрытым репозиторием, необходимо установить несколько разрешений.

  • Circleci должен уметь:

    1. Загрузить изображение в Docker-Hub
    2. Загрузить файл JSON в корзину в S3
    3. Вызовите команду AWS в Elastic Benastalk (создайте новую версию приложения)
  • AWS EB должен уметь:

    1. Извлечь (получить / список) данные из корзины S3
    2. Вытащите изображение из Docker-Hub

Я пропускаю часть создания пользователя в GitHub, Circleci, Docker-Hub и AWS.

Аутентификация Docker

Прежде чем мы настроим аутентификацию, нам нужно войти в Docker и создать файл dockercfg.

файл dockercfg

Docker имеет специальный файл конфигурации, обычно называемый .dockercfg. Нам нужно создать этот файл для пользователя, у которого есть права загружать изображения в docker-hub и загружать изображения.
Чтобы создать его, вам нужно выполнить следующую команду:
docker login
Эта команда создаст файл в ~ / .docker / .dockercfg. Если вы хотите создать этот файл для другого электронного письма (пользователя), используйте -eопцию. Проверьте: docker login doc
Внимание!
Формат файла отличается для Docker версий 1.6 и 1.7. В настоящее время нам нужно использовать формат 1.6. В противном случае AWS не сможет подключиться к хранилищу.

«Старая» версия, Docker 1.6


{
  "https://index.docker.io/v1/": {
    "auth": "AUTH_KEY",
    "email": "DOCKER_EMAIL"
  }
}

Более новая (Docker 1.7) версия файла конфигурации

Вероятно, это будет файл, созданный на вашем компьютере.


{
  "auths": {
    "https://index.docker.io/v1/": {
      "auth": "AUTH_KEY",
      "email": "DOCKER_EMAIL"
    }
  }
}

Правильный формат основан на версии Docker, которую использует EB.
Нам нужно добавить его в доступную корзину S3. Это объясняется позже в посте.

Загрузка из Circleci в Docker Hub

Настройка пользователя в Docker Hub

  1. В Docker Hub создайте команду (для вашей организации).
  2. В хранилище нажмите «Соавторы» и добавьте эту команду с правами на запись.
  3. Под организацией, нажмите на команды. Добавьте пользователя «развертывателя» в команду. Это пользователь, у которого есть файл, описанный ранее.

Я создал специального пользователя с определенным адресом электронной почты специально для этого.
Пользователь в этой команде (разрешение на запись) должен иметь файл dockercfg.

Настройка файла circle.yml с разрешениями Docker-Hub

Документация объясняет набор разрешений , как это:
docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS
Но мы сделали это по- другому. В части развертывания мы манипулировали файлом dockercfg.
Вот часть файла out circle.yml:


commands:
  - |
    cat > ~/.dockercfg << EOF
    {
      "https://index.docker.io/v1/": {
        "auth": "$DOCKER_AUTH",
        "email": "$DOCKER_EMAIL"
      }
    }
    EOF

Circleci использует переменные среды. Таким образом, мы должны установить их также. Нам нужно установить ключ аутентификации докера и адрес электронной почты. Позже мы установим больше.

Установка переменных окружения в окружности

Под настройкой проекта в Circelci щелкните Переменные среды .

Настройки -> Переменные среды

Добавьте две переменные окружения: DOCKER_AUTH и DOCKER_EMAIL
Значения должны быть такими же, как в файле, который был создан ранее.

Загрузить файл JSON в корзину в S3

Часть цикла развертывания заключается в загрузке файла дескриптора JSON на S3. Поэтому Circleci должен иметь разрешения для этой операции. Мы будем использовать политики разрешений IAM AWS. Я решил иметь одну корзину S3 для всех развертываний всех проектов. Это сделает мою жизнь намного проще, потому что я смогу использовать того же пользователя, разрешения и политики. Каждый проект / развертываемая часть будет находиться в отдельном каталоге.

Ниже приведены шаги по настройке среды AWS.

  1. Создайте корзину развертывания
  2. Создайте пользователя в AWS (или решите использовать существующего)
  3. Держите учетные данные пользователя, предоставленные AWS (загруженные), под рукой
  4. Создать политику в AWS, которая позволяет:

    1. получить доступ к ведру
    2. создать версию приложения в EB
  5. Добавьте эту политику для пользователя (которая установлена ​​в circleci)
  6. Установите переменные среды в Circleci с учетными данными, предоставленными AWS

Создание политики

В AWS перейдите в IAM и нажмите Политики на левой навигационной панели. Нажмите Создать политику .
Вы можете использовать диспетчер политик или создать следующую политику:


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1443479777000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:PutObject"
            ],
            "Resource": [
                "arn:aws:s3:::MY_DEPLOY_BUCKET/*"
            ]
        },
        {
            "Sid": "Stmt1443479924000",
            "Effect": "Allow",
            "Action": [
                "elasticbeanstalk:CreateApplicationVersion"
            ],
            "Resource": [
                "arn:aws:elasticbeanstalk:THE_EB_REGION:MY_ACCOUNT:applicationversion/*"
            ]
        }
    ]
}

Как упоминалось выше, эта политика позволяет получить доступ к конкретному сегменту (MY_DEPLOY_BUCKET), подкаталогу. И это позволяет инициировать создание новой версии приложения в EB. Эта политика будет использоваться пользователем, который зарегистрирован в circleci.

Разрешения AWS в Circleci

Circleci имеет специальные настройки для интеграции с AWS. На левой навигационной панели щелкните Разрешения AWS .
Положите ключ доступа и секрет в правильные поля. У вас должны быть эти ключи из файла учетных данных, созданного AWS.

Извлечь (получить / список) данные из корзины S3

Теперь нам нужно предоставить доступ к экземплярам EB, чтобы получить некоторые данные из S3. Экземпляр EB должен получить файл dockercfg (описанный ранее). В EB вы можете установить профиль экземпляра . Этот профиль даст разрешения экземпляру. Но сначала нам нужно создать политику. Так же, как мы делали ранее.

Создать политику в AWS


{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1443508794000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::MY_DEPLOY_BUCKET",
                "arn:aws:s3:::MY_DEPLOY_BUCKET/*"
            ]
        }
    ]
}

Эта политика предоставляет доступ на чтение к корзине развертывания и подкаталогам. Экземпляр EB должен иметь доступ к корневому каталогу корзины, потому что здесь я положу файл dockercfg. Требуется доступ к подкаталогу, потому что именно в этом месте Circleci загружает файлы дескриптора JSON.

Установите эту политику для экземпляра EB

На приборной панели EB:

  1. Перейдите в Панель управления приложениями (выберите приложение, которое вы устанавливаете)
  2. Выберите среду, которую вы хотите автоматически развернуть ➜
  3. Нажмите Конфигурация в левой панели навигации ➜
  4. Нажмите кнопку настройки экземпляров ➜
  5. Вы увидите профиль экземпляра. Вам нужно установить роль. Убедитесь, что у этой роли есть политика, созданная на предыдущем шаге.
  6. Применить изменения

Вытащите изображение из Docker-Hub

Чтобы экземпляр EB мог загружать образ из Dockerhub, нам нужно дать ему разрешения.
Для этого EB использует dockercfg. Загрузите dockercfg (описанный выше) в корзину, на которую у EB есть разрешение (в моем примере: MY_DEPLOY_BUCKET ). Поместите его в корневой каталог корзины . Позже вы установите переменные окружения в окружности с этим именем файла.

Настройка скриптов CircleCI

После настройки всех разрешений и сред мы готовы установить сценарии circleci. Circleci использует файл circle.yml для настройки шагов по созданию проекта.

В этом разделе я объясню, как настроить этот файл для непрерывного развертывания с использованием Docker и EB.
Другие элементы в этом файле находятся вне области видимости. Я добавил примеры скриптов в GitHub .

файл circle.yml

Ниже приведены соответствующие части в файле circle.yml.


machine:
  services:
# This is a Docker deployment
    - docker
  environment:
# Setting the tag for Docker-hub
    TAG: $CIRCLE_BRANCH-$CIRCLE_SHA1
# MY_IMAGE_NAME is hard coded in this file. The project’s environment variables do not pass at this stage.
    DOCKER_IMAGE: MY_ORGANIZATION/MY_IMAGE_NAME:$CIRCLE_BRANCH-$CIRCLE_SHA1

deployment:
# An example for on environment
  staging:
# The ‘automatic-.*’ is hook so we can automatically deploy from different branches.
# Usually we deploy automatically after a pull-request is merged to master.
    branch: [master, /automatic-.*/]
# This is our way for setting docker cfg credentials. We set project’s environment variables with the values.
    commands:
      - |
          cat > ~/.dockercfg << EOF
          {
              "https://index.docker.io/v1/": {
                  "auth": "$DOCKER_AUTH",
                  "email": "$DOCKER_EMAIL"
              }
          }
          EOF
# Sample for RoR project. Not relevant specifically to Docker.
      - bundle package --all
# Our Dockerfile.app is located under directory: docker-images
      - docker build -t $DOCKER_IMAGE -f docker-images/Dockerfile.app .
      - docker push $DOCKER_IMAGE
# Calling script for uploading JSON descriptor file
      - sh ./create_docker_run_file.sh $TAG
# Calling script for setting new application version in AWS EB
      - sh ./upload_image_to_elastcbeanstalk.sh $TAG 

Файл дескриптора шаблона

AWS EB использует JSON-файл для получения информации о Docker-концентраторе. Нужно знать, где находится изображение (организация, изображение, тег). Также необходимо знать, откуда взять файл dockercfg. Поместите этот файл в корневой каталог проекта.


{
  "AWSEBDockerrunVersion": "1",
  "Authentication": {
    "Bucket": "<DEPLOYMENT_BUCKET>",
    "Key": "<AUTHENTICATION_KEY>"
  },
  "Image": {
    "Name": “MY_ORGANIZATION/<IMAGE_NAME>:<TAG>",
    "Update": "true"
  },
  "Ports": [
    {
      "ContainerPort": "<EXPOSED_PORTS>"
    }
  ]
}

Первый скрипт, который мы запустим, заменит теги и создаст новый файл. Список переменных среды описан ниже.

Скрипт, который управляет файлом шаблона дескриптора

Поместите этот файл в корневой каталог проекта.


#! /bin/bash
DOCKER_TAG=$1

# Prefix of file name is the tag.
DOCKERRUN_FILE=$DOCKER_TAG-Dockerrun.aws.json

# Replacing tags in the file and creating a file.
sed -e "s/<TAG>/$DOCKER_TAG/" -e "s/<DEPLOYMENT_BUCKET>/$DEPLOYMENT_BUCKET/" -e "s/<IMAGE_NAME>/$IMAGE_NAME/" -e "s/<EXPOSED_PORTS>/$EXPOSED_PORTS/" -e "s/<AUTHENTICATION_KEY>/$AUTHENTICATION_KEY/" < Dockerrun.aws.json.template > $DOCKERRUN_FILE

S3_PATH="s3://$DEPLOYMENT_BUCKET/$BUCKET_DIRECTORY/$DOCKERRUN_FILE"
# Uploading json file to $S3_PATH
aws s3 cp $DOCKERRUN_FILE $S3_PATH 

Скрипт, который добавляет новую версию приложения в EB

Последний автоматизированный шаг — запуск AWS EB с новой версией приложения. Использование метки и другого изображения для каждого коммита (в мастере) помогает отслеживать, какая версия в какой среде. Даже если мы используем единую среду («реальное» непрерывное развертывание), ее легче отслеживать, а также выполнять откат.
Поместите этот файл в корневой каталог проекта.


#! /bin/bash

DOCKER_TAG=$1
DOCKERRUN_FILE=$DOCKER_TAG-Dockerrun.aws.json
EB_BUCKET=$DEPLOYMENT_BUCKET/$BUCKET_DIRECTORY

# Run aws command to create a new EB application with label
aws elasticbeanstalk create-application-version --region=$REGION --application-name $AWS_APPLICATION_NAME 
    --version-label $DOCKER_TAG --source-bundle S3Bucket=$DEPLOYMENT_BUCKET,S3Key=$BUCKET_DIRECTORY/$DOCKERRUN_FILE

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

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

AUTHENTICATION_KEY — имя файла dockercfg, который находится в корзине S3.
AWS_APPLICATION_NAME — имя приложения в EB
BUCKET_DIRECTORY — Каталог , в котором мы загрузите JSON дескрипторы файлов
DEPLOYMENT_BUCKET — S3 имя Ковша
DOCKER_AUTH — Ключ аутентификации для подключения к dockerhub (созданный с помощью докера логин)
DOCKER_EMAIL — электронная почта из ключевого Auth
EXPOSED_PORTS — Докер порты
IMAGE_NAME — у каждого образа Docker есть имя. Тогда это: Организация: Image-Name
REGION — регион AWS приложения EB

Некоторые переменные среды в файлах сценариев / конфигурации предоставляются circleci (например, CIRCLE_SHA1 и CIRCLE_BRANCH)

Развертывание в AWS EB

Как только версия приложения загружена в EB, мы можем решить развернуть ее в среде EB.
Следуй этим шагам:

  1. В EB на панели инструментов приложения щелкните Версии приложений на левой навигационной панели.
  2. Вы увидите таблицу со всеми помеченными версиями. Проверьте версию, которую вы хотите развернуть (SHA1 может помочь узнать фиксацию и содержание развертывания)
  3. Нажмите развернуть
  4. Выберите среду
  5. Вы сделали

Версии приложений AWS EB

Резюме

После настройки одного проекта легко повторно использовать сценарии и разрешения для других проектов.
Эта процедура на компакт-диске делает развертывание и отслеживание версий легкой задачей.
Следующий шаг, который заключается в развертывании новой версии в среде EB, очень прост. И я добавлю другой пост для этого.