Статьи

Непрерывное развертывание: внедрение

Эта статья является частью серии « Непрерывная интеграция, доставка и развертывание ».

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

Подводя итог, наши цели:

  • развернуть на каждом коммите или так часто, как это необходимо
  • быть быстрым
  • быть автоматизированным
  • иметь возможность откатить
  • иметь нулевое время простоя

Настройка сцены

Давайте настроим технологическую часть истории.

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

Хотя Docker можно развернуть в любой операционной системе, я предпочитаю использовать CoreOS . Это дистрибутив Linux, который предоставляет функции, необходимые для работы стеков современной архитектуры. Преимущество CoreOS перед другими заключается в том, что он очень легкий. У него всего несколько инструментов, и они как раз те, которые нам нужны для непрерывного развертывания. Мы будем использовать Vagrant для создания виртуальной машины с CoreOS.

Два особенно полезных инструмента, предустановленных в CoreOS, — это etcd (хранилище ключей-ключей для общей конфигурации и обнаружение служб) и systemd (набор демонов, библиотек и утилит управления системой).

Мы будем использовать nginx в качестве обратного прокси-сервера. Его шаблоны будут поддерживаться confd, который предназначен для управления файлами конфигурации приложения с использованием шаблонов и данных из etcd.

Наконец, в качестве примера приложения мы будем развертывать (много раз) BDD Assistant . Он может использоваться как вспомогательный инструмент для разработки и тестирования BDD. Причиной для этого является то, что нам понадобится полноценное приложение, которое можно использовать для демонстрации стратегии развертывания, которую мы собираемся изучить.

Я ищу ранних пользователей приложения. Если вы заинтересованы, пожалуйста, свяжитесь со мной, и я предоставлю всю необходимую вам помощь.

CoreOS

coreos-Товарный знак-гориз цвета Если у вас еще нет запущенного экземпляра CoreOS, репозиторий непрерывного развертывания содержит Vagrantfile, который можно использовать для его запуска. Пожалуйста, клонируйте этот репозиторий или загрузите и распакуйте ZIP-файл. Чтобы запустить ОС, пожалуйста, установите Vagrant и выполните следующую команду из каталога с клонированным (или распакованным) хранилищем.

1
vagrant up

После создания и запуска виртуальной машины мы можем войти в CoreOS, используя:

1
vagrant ssh

Отныне вы должны быть внутри CoreOS.

докер

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

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

1
2
# Run container technologyconversationsbdd and expose port 9000
docker run --name bdd_assistant -d -p 9000:9000 vfarcic/technologyconversationsbdd

Это может занять некоторое время, пока все образы Docker будут загружены в первый раз. С этого момента запуск и остановка сервиса происходит очень быстро. Чтобы увидеть результат, откройте http: // localhost: 9000 / в вашем браузере.

Это было просто. Одной командой мы загрузили полностью работающее приложение с интерфейсом AngularJS Play! веб-сервер, REST API и т. д. Сам контейнер самодостаточен и неизменен. Новый релиз будет совершенно новым контейнером. Ничего не нужно настраивать (кроме приложения, на котором запущен порт), и нечего обновлять, когда выпускается новая версия. Это просто работает.

etcd

Давайте перейдем к etcd.

1
etcd &

Отныне мы можем использовать его для хранения и извлечения необходимой информации. В качестве примера мы можем сохранить порт, на котором работает BDD Assistant. Таким образом, любое приложение, которое должно быть интегрировано с ним, может извлечь порт и, например, использовать его для вызова API приложения.

1
2
3
4
# Set value for a give key
etcdctl set /bdd-assistant/port 9000
# Retrive stored value
etcdctl get /bdd-assistant/port

Это был очень простой (и быстрый) способ сохранить любой ключ / значение, которое нам может понадобиться. Это пригодится очень скоро.

Nginx

2000px-nginx_logo-SVG На данный момент наше приложение работает на порту 9000. Вместо открытия localhost: 9000 (или любого другого порта, на котором он работает) было бы лучше, если бы оно просто работало на localhost. Для этого мы можем использовать обратный прокси-сервер nginx.

На этот раз мы не будем напрямую звонить в Docker, а запустим его как сервис через systemd.

1
2
3
4
5
6
7
8
# Create directories for configuration files
sudo mkdir -p /etc/nginx/{sites-enabled,certs-enabled}
# Create directories for logs
sudo mkdir -p /var/log/nginx
# Copy nginx service
sudo cp /vagrant/nginx.service /etc/systemd/system/nginx.service
# Enable nginx service
sudo systemctl enable /etc/systemd/system/nginx.service

Файл nginx.service сообщает systemd, что делать, когда мы хотим запустить, остановить или перезапустить какой-либо сервис. В нашем случае сервис создается с использованием контейнера Docker nginx.

Давайте запустим сервис nginx (первый раз может потребоваться некоторое время, чтобы получить образ Docker).

1
2
3
4
# Start nginx service
sudo systemctl start nginx.service
# Check whether nginx is running as Docker container
docker ps

Как видите, nginx работает как контейнер Docker. Давай остановим это.

1
2
3
4
# Stop nginx service
sudo systemctl stop nginx.service
# Check whether nginx is running as Docker container
docker ps

Теперь он исчез из процессов Docker. Это так просто. Мы можем запустить и остановить любой контейнер Docker в кратчайшие сроки (при условии, что изображения уже были загружены).

Нам понадобится nginx и запустить его до конца статьи, поэтому давайте запустим его снова.

1
sudo systemctl start nginx.service

confd

Нам нужно что-то сказать нашему nginx, на какой порт перенаправлять, когда запрашивается BDD Assistant. Мы будем использовать confd для этого. Давайте настроим это.

1
2
3
4
5
6
# Download confd
wget -O confd https://github.com/kelseyhightower/confd/releases/download/v0.6.3/confd-0.6.3-linux-amd64
# Put it to the bin directory so that it is easily accessible
sudo cp confd /opt/bin/.
# Give it execution permissions
sudo chmod +x /opt/bin/confd

Следующим шагом является настройка confd для изменения маршрутов nginx и их перезагрузки при каждом развертывании нашего приложения.

1
2
3
4
5
6
# Create configuration and templates directories
sudo mkdir -p /etc/confd/{conf.d,templates}
# Copy configuration
sudo cp /vagrant/bdd_assistant.toml /etc/confd/conf.d/.
# Copy template
sudo cp /vagrant/bdd_assistant.conf.tmpl /etc/confd/templates/.

И bdd_assistant.toml, и bdd_assistant.conf.toml находятся в репозитории , который вы уже скачали.

Посмотрим, как это работает.

1
2
3
sudo confd -onetime -backend etcd -node 127.0.0.1:4001
cat /etc/nginx/sites-enabled/bdd_assistant.conf
wget localhost; cat index.html

Мы только что обновили шаблон nginx, чтобы использовать порт, ранее установленный в etcd. Теперь вы можете открыть http: // localhost: 8000 / в вашем браузере (Vagrant выставлен по умолчанию для 80 как 8000). Даже если приложение работает на порту 9000, мы настроили nginx для перенаправления запросов с порта 80 по умолчанию на порт 9000.

Остановимся и удалим контейнер BDD Assistant. Мы создадим его снова, используя все инструменты, которые мы уже видели.

1
2
3
docker stop bdd_assistant
docker rm bdd_assistant
docker ps

BDD Assistant Deployer

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

Мы будем практиковать Blue Green Deployment . Это означает, что у нас будет один релиз и работает (синий). Когда новый выпуск (зеленый) развернут, он будет работать параллельно. После запуска nginx перенаправит все запросы к нему вместо старого. Каждый последующий релиз будет следовать одному и тому же процессу. Развертывание поверх синего, перенаправление запросов с зеленого на синий, развертывание поверх зеленого, перенаправление запросов с синего на зеленый и т. Д. Откат будет легко выполнить. Нам просто нужно изменить обратный прокси. Там будет время обнуления, так как новый выпуск будет запущен, прежде чем мы начнем перенаправлять запросы. Все будет полностью автоматизировано и очень быстро. Имея все это в наличии, мы сможем развертывать так часто, как мы хотим (предпочтительно при каждом коммите в хранилище).

1
2
3
4
5
6
7
8
sudo cp /vagrant/bdd_assistant.service /etc/systemd/system/bdd_assistant_blue@9001.service
sudo cp /vagrant/bdd_assistant.service /etc/systemd/system/bdd_assistant_green@9002.service
sudo systemctl enable /etc/systemd/system/bdd_assistant_blue@9001.service
sudo systemctl enable /etc/systemd/system/bdd_assistant_green@9002.service
# sudo systemctl daemon-reload
etcdctl set /bdd-assistant/instance none
sudo chmod 744 /vagrant/deploy_bdd_assistant.sh
sudo cp /vagrant/deploy_bdd_assistant.sh /opt/bin/.

Мы только что создали два сервиса BDD Assistant: синий и зеленый. Каждый из них будет работать на разных портах (9001 и 9002) и хранить соответствующую информацию в etcd. deploy_bdd_assistant.sh — это простой скрипт, который запускает сервис, обновляет шаблон nginx с помощью conf и, наконец, останавливает старый сервис. Служба BDD Assistant и deploy_bdd_assistant.sh доступны в уже загруженном репо.

Давайте попробуем это.

1
sudo deploy_bdd_assistant.sh

Новая версия будет развернута каждый раз, когда мы запускаем скрипт deploy_bdd_assistant.sh. Мы можем подтвердить это, проверив, какое значение хранится в etcd, посмотрев на процессы Docker и, наконец, запустив приложение в браузере.

1
2
docker ps
etcdctl get /bdd-assistant/port

Процесс Docker должен измениться с запуска синего развертывания на порте 9001 на запуск зеленого на порте 9002 и наоборот. Порт, сохраненный в etcd, должен измениться с 9001 на 9002 и наоборот. Какая бы версия не была развернута, http: // localhost: 8000 / всегда будет работать в вашем браузере, независимо от того, находится ли мы в процессе развертывания или уже завершили его.

Повторите выполнение сценария deploy_bdd_assistant.sh столько раз, сколько захотите. Следует всегда развертывать последнюю новую версию.

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

Непрерывная доставка и развертывание

Описанный выше процесс должен быть привязан к вашему CI / CD серверу ( Jenkins , Bamboo , GoCD и т. Д.). Одна из возможных процедур непрерывной доставки будет:

  1. Зафиксируйте код в VCS ( GIT , SVN и т. Д.)
  2. Запустите весь статический анализ
  3. Запустите все юнит-тесты
  4. Сборка Docker контейнера
  5. Развертывание в тестовой среде
    1. Запустите контейнер с новой версией
    2. Запускать автоматизированные функциональные, интеграционные (т.е. BDD ) и стресс-тесты
    3. Выполните ручные тесты
    4. Измените обратный прокси, чтобы он указывал на новый контейнер
  6. Развертывание в производственной среде
    1. Запустите контейнер с новой версией
    2. Запускать автоматизированные функциональные, интеграционные (т.е. BDD ) и стресс-тесты
    3. Измените обратный прокси, чтобы он указывал на новый контейнер

В идеале, не должно быть никаких ручных испытаний, и в этом случае пункт 5 не требуется. У нас будет непрерывное развертывание, которое будет автоматически развертывать каждый коммит, прошедший все тесты в рабочей среде. Если ручная проверка неизбежна, у нас есть Непрерывная доставка в тестовые среды, и программное обеспечение будет развернуто в производство одним нажатием кнопки на используемом нами сервере CI / CD.

Резюме

Независимо от того, выберем ли мы непрерывную доставку или развертывание, когда наш процесс полностью автоматизирован (от сборки до тестирования и до самого развертывания), мы можем потратить время на работу, приносящую больше пользы, позволяя сценариям выполнять свою работу за нас. Время выхода на рынок должно резко сократиться, поскольку мы сможем предоставлять пользователям функции, как только код будет добавлен в хранилище. Это очень мощная и ценная концепция.

В случае возникновения каких-либо проблем после выполнения упражнений, вы можете пропустить их и перейти непосредственно к запуску сценария deploy_bdd_assistant.sh. Просто удалите комментарии (#) из Vagrantfile.

Если виртуальная машина уже запущена и работает, уничтожьте ее.

1
vagrant destroy

Создайте новую виртуальную машину и запустите сценарий deploy_bdd_assistant.sh.

1
2
3
vagrant up
vagrant ssh
sudo deploy_bdd_assistant.sh

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

BDD Assistant и его развертывание с Docker могут быть еще лучше. Мы можем разделить приложение на более мелкие микросервисы. Например, он может иметь внешний интерфейс как отдельный контейнер. Back-end можно разделить на более мелкие сервисы (управление историями, ведение историй и т. Д.). Эти микросервисы могут быть развернуты на одной или разных машинах и организованы с помощью Fleet . Микросервисы станут темой следующей статьи.

Ссылка: Непрерывное развертывание: Внедрение от нашего партнера JCG Виктора Фарсика в блоге Technology Talks.