Мы запускаем некоторые из наших сервисов в контейнерах 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 должен уметь:
- Загрузить изображение в Docker-Hub
- Загрузить файл JSON в корзину в S3
- Вызовите команду AWS в Elastic Benastalk (создайте новую версию приложения)
- AWS EB должен уметь:
- Извлечь (получить / список) данные из корзины S3
- Вытащите изображение из 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
- В Docker Hub создайте команду (для вашей организации).
- В хранилище нажмите «Соавторы» и добавьте эту команду с правами на запись.
- Под организацией, нажмите на команды. Добавьте пользователя «развертывателя» в команду. Это пользователь, у которого есть файл, описанный ранее.
Я создал специального пользователя с определенным адресом электронной почты специально для этого.
Пользователь в этой команде (разрешение на запись) должен иметь файл 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.
- Создайте корзину развертывания
- Создайте пользователя в AWS (или решите использовать существующего)
- Держите учетные данные пользователя, предоставленные AWS (загруженные), под рукой
- Создать политику в AWS, которая позволяет:
- получить доступ к ведру
- создать версию приложения в EB
- Добавьте эту политику для пользователя (которая установлена в circleci)
- Установите переменные среды в 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:
- Перейдите в Панель управления приложениями (выберите приложение, которое вы устанавливаете)
- Выберите среду, которую вы хотите автоматически развернуть ➜
- Нажмите Конфигурация в левой панели навигации ➜
- Нажмите кнопку настройки экземпляров ➜
- Вы увидите профиль экземпляра. Вам нужно установить роль. Убедитесь, что у этой роли есть политика, созданная на предыдущем шаге. ➜
- Применить изменения
Вытащите изображение из 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.
Следуй этим шагам:
- В EB на панели инструментов приложения щелкните Версии приложений на левой навигационной панели.
- Вы увидите таблицу со всеми помеченными версиями. Проверьте версию, которую вы хотите развернуть (SHA1 может помочь узнать фиксацию и содержание развертывания)
- Нажмите развернуть
- Выберите среду
- Вы сделали
Версии приложений AWS EB
Резюме
После настройки одного проекта легко повторно использовать сценарии и разрешения для других проектов.
Эта процедура на компакт-диске делает развертывание и отслеживание версий легкой задачей.
Следующий шаг, который заключается в развертывании новой версии в среде EB, очень прост. И я добавлю другой пост для этого.