TechBlogSD - Все для WordPress и WEB разработки
WEB и WordPress инструкции, новости, обзоры тем и плагинов

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker

950

Введение

DigitalOcean – это платформа, которая дает разработчикам место для размещения своих приложений. Они предлагают как скромный виртуальный частный сервер (VPS), который они называют «каплями», так и более продвинутые продукты, такие как балансировщики нагрузки и управляемые базы данных. Мы обсудим все вышеперечисленное в следующих разделах.

Чтобы следовать этому руководству, вам необходимо создать учетную запись DigitalOcean. Вам также потребуется создать учетную запись GitHub, если у вас ее еще нет. Поскольку я разработчик Node.js, в этом руководстве будет использоваться базовая служба Node.js (Docker), хотя ее можно легко адаптировать для работы с любой платформой, с которой вы более знакомы.

Создание инфраструктуры в DigitalOcean

К концу этой демонстрации вы создадите две по 5 долларов в месяц. капли, одна 10 $ / мес. балансировщик нагрузки и бесплатный реестр контейнеров. DigitalOcean взимает почасовую оплату за эти продукты, поэтому, как только вы все соберете и начнете работать, вы сможете сразу же разрушить инфраструктуру, заплатив всего несколько долларов.

Взгляните на инфраструктуру, которую мы собираемся построить:

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

Как только все будет сделано, у вас будет действие GitHub, которое автоматически развертывает основную ветвь вашего репозитория как в каплях, так и в каплях.api-1``api-2

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

График развертывания

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

Ниже представлен график предстоящих операций. Мы более подробно рассмотрим экземпляр, чем экземпляр, чтобы сэкономить место, хотя они будут проходить через один и тот же процесс:api-1``api-2

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

На приведенном выше рисунке ось X представляет время и перемещается слева направо. Когда процесс развертывания запускается впервые, работают два экземпляра службы, API 1 и API 2, которые запускают V1 кодовой базы. Пока это происходит, балансировщик нагрузки отправляет им обоим проверки работоспособности, чтобы убедиться, что они могут получать запросы.

В конце концов, произойдет развертывание, которое приведет к вызову конечной точки завершения работы. С этого момента проверки работоспособности не будут выполняться. Обратите внимание, что даже если проверка работоспособности завершается ошибкой, служба все еще может обрабатывать запросы и маршрутизировать трафик. Если две проверки завершились неудачно, этот экземпляр сервера удаляется из балансировщика нагрузки, заменяется V2 кодовой базы и возвращается к работе. После прохождения трех проверок работоспособности балансировщик нагрузки снова начинает маршрутизировать запросы к экземпляру. Как только это будет сделано, процесс развертывания продолжится до следующего экземпляра службы.

На высоком уровне есть два важных момента, которые следует извлечь из вышеизложенного:

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

Обладая этими знаниями, вы готовы перейти к нашему конкретному руководству по DigitalOcean.

Руководство по развертыванию: нулевое время простоя с помощью DigitalOcean

Создать токены

Токены позволяют приложениям взаимодействовать с API DigitalOcean от вашего имени. В этом примере они будут использоваться, чтобы сервер сборки GitHub мог отправлять образы Docker в реестр контейнеров, и чтобы ваши капли могли извлекать из реестра контейнеров.

Посетите страницу настроек API DigitalOcean и сгенерируйте два новых токена. Назовите первый «Действия GitHub», а второй «Извлечение реестра капель ». Оба могут быть настроены для чтения и записи в этом примере. Обратите внимание на эти токены API, поскольку они понадобятся вам позже.

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

Сгенерируйте SSH-ключ

При обмене данными с серверами по SSH гораздо безопаснее использовать ключ SSH, чем пароль. По этой причине вы теперь сгенерируете SSH-ключ (который длиннее и более случайный, чем пароль) для доступа к каплям.

Использование ключа SSH позволит вам вручную подключиться и выполнить некоторую начальную настройку, а также позволит GitHub передавать файлы в дроплеты.

Чтобы сгенерировать SSH-ключ, выполните следующую команду:

$ ssh-keygen -t rsa -f ~/.ssh/api-droplets # leave password blank

Эта команда создаст два ключевых файла. Первый находится в ~ / .ssh / api-droplets и является вашим закрытым ключом, которым вы не должны делиться с третьими лицами. Второй файл находится в ~ / .ssh / api-droplets.pub и является открытым ключом. С этим вы можете быть менее скупыми.

Создание капель (VPC)

Используя интерфейс DigitalOcean, создайте две капли.

При этом вам будет предложено предоставить некоторые детали. Для распространения выберите Debian 10. Для плана выберите Базовый 5 долларов в месяц. Для варианта центра обработки данных выберите ближайший к вам центр обработки данных и убедитесь, что балансировщик нагрузки, который вы создадите позже, находится в том же центре обработки данных. Я выбрал для себя SFO2.

В разделе аутентификации нажмите кнопку New SSH Key. Присвойте ключу SSH имя, например Droplet SSH Key, и вставьте содержимое файла ~/.ssh/api-droplets.pub в поле ввода ключа SSH, затем нажмите Добавить ключ SSH. Установите количество создаваемых капель равным 2.

Назовите имена хостов api-1 и api-2. Наконец, пометьте обе капли новым тегом http-api. Этот тег позже будет использоваться подсистемой балансировки нагрузки для сопоставления запросов к каплям.

После того, как вы создали капли, вы должны увидеть их в интерфейсе следующим образом:

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

Указанный здесь IP-адрес является общедоступным IP-адресом вашей капли. Эти адреса однозначно идентифицируют ваши капли в Интернете. Используя эти IP-адреса, вы теперь будете подключаться по SSH к двум каплям со своей машины разработки.

Выполните следующую команду для своей первой капли:

Как только вы подключитесь, вам нужно будет сделать пару вещей.

Сначала установите Docker на VPS. Это будет использоваться для инкапсуляции и запуска вашего приложения. Вам также необходимо установить doctlдвоичный файл и пройти аутентификацию с его помощью, что позволит VPS взаимодействовать с DigitalOcean. Чтобы выполнить эту настройку, выполните следующую команду:

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

Создать балансировщик нагрузки

Теперь, когда вы создали свои капли, следующим шагом вы захотите создать балансировщик нагрузки с использованием пользовательского интерфейса DigitalOcean. Для этой демонстрации подойдет вариант Small $ 10 / мес. Как отмечалось ранее, убедитесь, что он находится в том же регионе, где вы создали две капли.

В поле «Добавить капли» введите тег и щелкните результат, чтобы динамически сопоставить ваши капли. Для этого проекта достаточно опции перенаправления HTTP с порта 80 на порт 80.http-api

Измените дополнительные параметры, чтобы настроить конечные точки проверки работоспособности. Обычно балансировщик нагрузки делает запрос к конечной точке /, но этому проекту требуется выделенная конечная точка только для проверок работоспособности.

Чтобы настроить эту выделенную конечную точку, измените «Path» на, установите «Unhealthy Threshold» на 2 и установите «Healthy Threshold» на 3. Теперь ваша конфигурация должна выглядеть так:/health

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

Назовите свой балансировщик нагрузки запоминающимся и запоминающимся. В моем случае я выбрал .sfo2-api

Как только вы сохраните балансировщик нагрузки, вы должны увидеть его в пользовательском интерфейсе. Мой балансировщик нагрузки выглядит примерно так (обратите внимание, что 0 из 2 согласованных капель исправны, потому что сервер на них не работает):

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

Как и в случае с каплями, IP-адрес – это уникальный IP-адрес, который идентифицирует ваш балансировщик нагрузки. В этот момент вы можете сделать запрос к балансировщику нагрузки со своей машины разработки, чтобы убедиться, что он работает. Выполните следующую команду в своем терминале:

Когда вы это сделаете, вы должны получить ответ об ошибке HTTP с сообщением в теле ответа «Нет доступного сервера для обработки этого запроса». Это ожидается; на данный момент в нашем процессе нет исправных серверов.503 Service Unavailable

Создать реестр контейнеров

Затем вы создадите реестр контейнеров с помощью пользовательского интерфейса DigitalOcean. Здесь хранятся образы Docker.

По умолчанию вы ограничены 500 МБ бесплатного хранилища, чего достаточно для этого эксперимента. Для более крупных проектов вы быстро перерастете это число. Действительно, первое развертывание этого проекта потребляет около 300 МБ хранилища, хотя при дополнительных развертываниях добавляется только пара мегабайт.

При создании реестра вам нужно будет дать ему уникальное имя. В этом примере я выбрал имя foo, но вам нужно будет выбрать что-то глобально уникальное для всех клиентов DigitalOcean.

Создать репозиторий GitHub

Чтобы продолжить настройку развертывания с нулевым временем простоя с DigitalOcean, мы будем использовать пользовательский интерфейс GitHub для создания нового репозитория.

Настройте локальный каталог так, чтобы он указывал на репозиторий. Обязательно используйте новое mainсоглашение о ветвлении вместо master. На экране нового репозитория GitHub есть все необходимые для этого команды.

Как только это будет сделано, добавьте в репозиторий следующие файлы:

.github/workflows/main-deploy.yml

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

В этом случае вам понадобится только один файл для описания процесса развертывания, когда код объединяется с основной ветвью. Используйте следующий файл в качестве шаблона, отметив, что вы захотите заменить <REGISTRY_NAME>его именем вашего реестра DigitalOcean, например, fooзначением, которое я использовал.

Этот файл содержит три задания. Первый – buildэто сборка контейнера докеров внутри виртуальной машины Ubuntu. Он также помечает контейнер и помещает его в реестр контейнеров.

И рабочие места также запустить в виртуальной машине Ubuntu, но они делают все их работу над SSH. В частности, они подключаются к вашим каплям, извлекают новый образ докера, сообщают службе о завершении работы и ждут, пока проверки работоспособности не завершатся. После этого старый контейнер удаляется, и запускается новый контейнер на основе нового образа.deploy-api-1``deploy-api-2

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

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

Пояснения к соответствующим файлам

Dockerfile

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

FROM node:14 EXPOSE 80 WORKDIR /srv/api ADD . /srv/api RUN npm install --production CMD ["node", "api.mjs"]

Этот образ основан на строке Node.js 14 LTS. Он указывает на то, что внутренняя служба прослушивает порт 80. Код приложения копируется в каталог / srv / api / внутри изображения. Затем он выполняет производственную установку перед окончательным запуском файла api.mjs .

.dockerginore

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

.git .gitignore node_modules npm-debug.log test

Самая важная строка здесь – это директория. Это важно, потому что эти файлы должны создаваться в процессе сборки образа, а не копироваться из вашей ОС.node_modules/

.gitignore

Этот файл в основном предназначен для предотвращения фиксации:node_modules/

node_modules npm-debug.log

api.mjs

Этот файл представляет собой очень простой API, который будет доступен за балансировщиком нагрузки и является точкой входа в службу:

Маршрут в основном показывает, что услуга может работать путем генерации случайного числа, чтобы действовать в качестве идентификатора. Это число будет оставаться неизменным на протяжении всего срока службы экземпляра.GET /

Это то, что использует балансировщик нагрузки, чтобы узнать, работает ли приложение и может ли оно получать запросы. Устанавливает переменную. Как только это произойдет, любые последующие запросы к нему будут возвращать код состояния «недоволен». Это механизм, который позволяет нам изящно объявить, что служба должна быть удалена из балансировщика нагрузки.GET /health``GET /shutdown``die``true``GET /health``503

package.json and package-lock.json

Эти два файла можно сгенерировать, выполнив следующие команды:

$ npm init -y $ npm install fastify@3

Это создает каталог и два файла пакета. Эти файлы пакетов позже будут использоваться в процессе сборки Docker для загрузки необходимых файлов пакетов из репозитория пакетов npmjs.com.node_modules/

Секреты проекта GitHub

Чтобы запустить развертывание, вам также нужно будет создать некоторые секреты проекта GitHub. Это переменные, которые могут использоваться файлами YAML GitHub Action.

Чтобы создать секреты своего проекта, перейдите на вкладку настроек для проекта GitHub и добавьте четыре записи.

Ваша первая запись будет DIGITALOCEAN_ACCESS_TOKEN. Это значение токена доступа GitHub Actions, созданного на предыдущем шаге.

Ваша вторая запись будет DO_API_KEY. Это будет содержимое файла закрытого ключа, который вы создали ранее. Будьте осторожны при вставке содержимого, так как вы хотите убедиться, что символы новой строки сохранены.~/.ssh/api-droplets

Наконец, вы добавите две записи DO_API1_HOST, и DO_API2_HOST. Оба они будут содержать IP-адреса двух созданных вами капель API. Теперь ваш экран секретов должен выглядеть так:

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

Все четыре этих секретных имени упоминаются в ранее созданном YAML-файле GitHub Action.

Запустите первое развертывание

Чтобы запустить первое развертывание, выполните следующие действия:

  1. Объедините изменения файла с основной ветвью GitHub, создав и объединив пул-реквест, или добавив его непосредственно в основную ветвь и нажав. Как только это будет сделано, процесс развертывания должен начаться.
  2. В репозитории GitHub проверьте вкладку Действия. Вы должны увидеть активное действие, связанное со слиянием кода с основной веткой. Щелкните его, чтобы просмотреть дополнительную информацию. На моем экране это выглядит так:

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

Поиск проблемы

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

Если есть проблема с кодом, который вы расшифровали, измените его и снова зафиксируйте в основной ветке. Это автоматически запустит другую сборку.

Если вам нужно изменить секрет GitHub, перейдите и измените его с помощью пользовательского интерфейса GitHub – просто знайте, что это не запустит другое развертывание. Вместо этого снова посетите вкладку «Действия», нажмите кнопку «Развернуть в рабочей среде» слева и используйте раскрывающийся список «Выполнить рабочий процесс» справа, чтобы снова запустить сборку из основной ветви.

В нашем примере вы можете видеть, что после buildуспешного завершения на втором шаге выполняется развертывание. Следующий шаг – развертывание – еще не произошел, потому что он ждет завершения. Если развертывание завершится неудачно, оно не будет развернуто. Это дает вам время исправить любые проблемы и развернуть исправление. Более того, если какой-либо из этих шагов потерпит неудачу, вы можете щелкнуть по ним, чтобы получить дополнительную информацию.api-1``api-2``api-1``api-2

Мониторинг работоспособности приложения

Графики DigitalOcean для балансировщика нагрузки отображают работоспособность приложения с течением времени, и, по моему опыту, опрашивает работоспособность приложения каждую минуту.

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

Вот что произошло в моем случае:

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

График времени простоя ясно показывает (зеленый) наличие простоя. Другой (коричневый) не был опрошен в нужный момент, чтобы вызвать скачок графика. График проверки работоспособности показывает, что это было незначительно.app-1``app-2``app-2

На этом buildшаге образы Docker отправляются в хранилище контейнеров. Каждый раз, когда это происходит, изображение помечается дважды; один раз содержащий latestтег, а другой – хеш-код фиксации git основной ветки, когда сборка произошла.

Вот как выглядит мой реестр контейнеров после выполнения двух сборок:

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

latestТег заменяется каждой сборки. Это тег, который используется для развертывания образов докеров в рабочей среде. Тег, использующий хеш фиксации, – это просто удобство, чтобы показать вам, что он работает. Более надежная система могла бы использовать это для отката развертываний до предыдущих коммитов.

Сделайте запрос с балансировкой нагрузки

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

Теперь вы готовы доказать, что приложение работает с резервированием. Вы можете сделать это, выполнив несколько раз следующую команду:

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

Если один из ваших серверов выйдет из строя, он будет удален из ротации. При настройке проверок работоспособности балансировщику нагрузки может потребоваться от 11 до 20 секунд, чтобы понять, что один из экземпляров не работает. В течение этого времени 50 процентов запросов, отправляемых на балансировщик нагрузки, завершаются ошибкой. Более агрессивные проверки работоспособности могут сократить это время, но сложно построить систему, которая на 100% устойчива к сбоям.

Конечно, передача IP-адресов не так уж и удобна, но вы можете настроить параметры DNS для домена, чтобы он указывал на IP-адрес. Опять же, еще одно руководство на другой день.

Производство

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

  • Не выставляйте конечную точку выключения на порту. Вместо этого слушайте только другой порт (локальный интерфейс). Обратите внимание, что в настоящее время любой может позвонить, чтобы отключить дроплет.:80``127.0.0.1``[http://<LOAD_BALANCER_IP>/shutdown](http://%3Cload_balancer_ip%3E/shutdown)
  • Переименуйте healthcheckконечную точку на то, что труднее угадать
  • Для реального приложения перенаправляйте HTTPS-запросы от балансировщика нагрузки к HTTP в API.
  • Используйте для дроплетов учетную запись без полномочий root

Наконец, имейте в виду, что службы API прослушивают (все интерфейсы), поэтому клиент может обойти балансировщик нагрузки, напрямую запросив IP-адрес капли. Помните, что каждая капля предоставляет два сетевых интерфейса, один открытый и один частный, и что службы Node.js должны прослушивать частный интерфейс, до которого может добраться балансировщик нагрузки.0.0.0.0

Заключение

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

LogRocket: полная видимость ваших веб-приложений

Развертывание с нулевым временем простоя с помощью DigitalOcean, GitHub и Docker - блог LogRocket

LogRocket – это решение для мониторинга внешних приложений, которое позволяет воспроизводить проблемы, как если бы они произошли в вашем собственном браузере. Вместо того, чтобы угадывать, почему происходят ошибки, или запрашивать у пользователей снимки экрана и дампы журнала, LogRocket позволяет воспроизвести сеанс, чтобы быстро понять, что пошло не так. Он отлично работает с любым приложением, независимо от фреймворка, и имеет плагины для регистрации дополнительного контекста из Redux, Vuex и @ ngrx / store.

Помимо регистрации действий и состояния Redux, LogRocket записывает журналы консоли, ошибки JavaScript, трассировки стека, сетевые запросы / ответы с заголовками и телами, метаданные браузера и пользовательские журналы. Он также использует DOM для записи HTML и CSS на странице, воссоздавая видео с идеальным пикселем даже для самых сложных одностраничных приложений.

Попробуй бесплатно.

Источник записи: https://blog.logrocket.com

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