Поиск по сайту:

Как настроить конвейер непрерывного развертывания с помощью GitLab CI/CD в Ubuntu


Введение

GitLab — это платформа для совместной работы с открытым исходным кодом, которая предоставляет мощные функции, помимо размещения репозитория кода. Вы можете отслеживать проблемы, размещать пакеты и реестры, поддерживать вики-сайты, настраивать конвейеры непрерывной интеграции (CI) и непрерывного развертывания (CD) и многое другое.

В этом руководстве вы создадите конвейер непрерывного развертывания с помощью GitLab. Вы настроите конвейер для создания образа Docker, отправите его в реестр контейнеров GitLab и развернете на своем сервере с помощью SSH. Конвейер будет запускаться для каждого коммита, отправленного в репозиторий.

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

Закончив работу с этим руководством, вы можете посетить http://your_server_IP в браузере, чтобы просмотреть результаты автоматического развертывания.

Развертывайте свои интерфейсные приложения из GitHub с помощью платформы приложений DigitalOcean. Позвольте DigitalOcean сосредоточиться на масштабировании вашего приложения.

Предварительные условия

Если вы используете Ubuntu версии 16.04 или ниже, мы рекомендуем вам обновиться до более последней версии, поскольку Ubuntu больше не поддерживает эти версии. Этот сборник руководств поможет вам обновить версию Ubuntu.

Чтобы выполнить это руководство, вам понадобится:

  • Сервер под управлением Ubuntu вместе с пользователем без полномочий root с привилегиями sudo и активным брандмауэром. Для получения инструкций по их настройке выберите свой дистрибутив из этого списка и следуйте нашему Руководству по первоначальной настройке сервера. Вам понадобится как минимум 1 ГБ ОЗУ и 1 процессор.
  • Docker установлен на сервере, следуя этому руководству «Как установить и использовать Docker в Ubuntu» 22.04/20.04/18.04.
  • Учетная запись пользователя в экземпляре GitLab с включенным реестром контейнеров. Бесплатный план официального экземпляра GitLab соответствует требованиям. Вы также можете разместить свой собственный экземпляр GitLab, следуя руководству «Как установить и настроить GitLab в Ubuntu» 20.04/18.04.

Настройка конвейера непрерывной разработки на Gitlab

  1. Создать репозиторий Gitlab
  2. Регистрация Gitlab Runner
  3. Создайте пользователя развертывания
  4. Настройка SSH-ключа
  5. Хранение SSH-ключа в Gitlab
  6. Настройте конвейер Gitlab CI/CD
  7. Проверка развертывания
  8. Как откатить развертывание

Шаг 1 — Создание репозитория GitLab

Начнем с создания проекта GitLab и добавления в него HTML-файла. Позже вы скопируете HTML-файл в образ Nginx Docker, который, в свою очередь, развернете на сервере.

Войдите в свой экземпляр GitLab и нажмите Новый проект.

  1. На экране Создать новый проект выберите Создать пустой проект.
  2. Дайте ему правильное имя проекта.
  3. При необходимости добавьте цель развертывания проекта.
  4. Обязательно установите для параметра Уровень видимости значение Частный или Общедоступный в зависимости от ваших требований.
  5. Наконец нажмите Создать проект.

Вы будете перенаправлены на страницу обзора проекта.

Давайте создадим HTML-файл. На странице обзора вашего проекта нажмите + > Новый файл.

Задайте для Имя файла значение index.html и добавьте следующий HTML-код в тело файла:

<html>
    <body>
        <h1>My Personal Website</h1>
    </body>
</html>

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

Этот HTML-код создаст пустую страницу с одним заголовком, отображающим Мой личный веб-сайт при открытии в браузере.

Dockerfiles — это рецепты, используемые Docker для создания образов Docker. Давайте создадим Dockerfile, чтобы скопировать HTML-файл в изображение Nginx.

Вернитесь на страницу обзора проекта, нажмите кнопку + и выберите параметр Новый файл.

Задайте для Имя файла значение Dockerfile и добавьте следующие инструкции в тело файла:

FROM nginx:1.18
COPY index.html /usr/share/nginx/html

Инструкция FROM указывает образ для наследования — в данном случае образ nginx:1.18. 1.18 — это тег изображения, представляющий версию Nginx. Тег nginx:latest ссылается на последнюю версию Nginx, но это может привести к поломке вашего приложения в будущем, поэтому рекомендуется использовать фиксированные версии.

Инструкция COPY копирует файл index.html в /usr/share/nginx/html в образе Docker. Это каталог, в котором Nginx хранит статический HTML-контент.

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

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

Шаг 2 — Регистрация бегуна GitLab

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

В вашем конвейере развертывания вы хотите войти на свой сервер с помощью SSH. Для этого вы сохраните закрытый ключ SSH в переменной GitLab CI/CD (шаг 5). Закрытый ключ SSH — очень конфиденциальная часть данных, поскольку это входной билет на ваш сервер. Обычно закрытый ключ никогда не покидает систему, в которой он был сгенерирован. В обычном случае вы должны создать ключ SSH на своем хост-компьютере, затем авторизовать его на сервере (то есть скопировать открытый ключ на сервер), чтобы войти в систему вручную и выполнить процедуру развертывания.

Здесь ситуация немного меняется: вы хотите предоставить автономному органу (GitLab CI/CD) доступ к вашему серверу для автоматизации процедуры развертывания. Поэтому закрытый ключ должен покинуть систему, в которой он был сгенерирован, и передать его в доверительное управление GitLab и другим заинтересованным сторонам. Вы никогда не захотите, чтобы ваш закрытый ключ попал в среду, которую вы не контролируете и не доверяете ей.

Помимо GitLab, программа запуска GitLab — это еще одна система, в которую будет входить ваш закрытый ключ. Для каждого конвейера GitLab использует бегунов для выполнения тяжелой работы, то есть выполнения заданий, указанных вами в конфигурации CI/CD. Это означает, что задание по развертыванию в конечном итоге будет выполнено на бегуне GitLab, поэтому закрытый ключ будет скопирован на бегун, чтобы он мог войти на сервер с помощью SSH.

Если вы используете неизвестные средства запуска GitLab (например, общие средства запуска) для выполнения задания развертывания, вы не будете знать о том, что системы вступают в контакт с закрытым ключом. Несмотря на то, что средства запуска GitLab очищают все данные после выполнения задания, вы можете избежать отправки закрытого ключа в неизвестные системы, зарегистрировав свой собственный сервер в качестве средства запуска GitLab. Затем закрытый ключ будет скопирован на сервер, контролируемый вами.

Начните с входа на ваш сервер:

ssh sammy@your_server_IP

Чтобы установить сервис gitlab-runner, вам нужно добавить официальный репозиторий GitLab. Загрузите и проверьте сценарий установки:

curl -L "https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.deb.sh" | sudo bash

При успешном выполнении возвращается следующее сообщение:

The repository is setup! You can now install packages.

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

sudo apt-get install gitlab-runner

Когда вы выполните предыдущую команду, результат будет таким:

[sudo] password for sammy:   % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  5945  100  5945    0     0   8742      0 --:--:-- --:--:-- --:--:--  8729

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

systemctl status gitlab-runner

В выводе у вас будет active (running):

● gitlab-runner.service - GitLab Runner
   Loaded: loaded (/etc/systemd/system/gitlab-runner.service; enabled; vendor preset: enabled)
   Active: active (running) since Mon 2020-06-01 09:01:49 UTC; 4s ago
 Main PID: 16653 (gitlab-runner)
    Tasks: 6 (limit: 1152)
   CGroup: /system.slice/gitlab-runner.service
           └─16653 /usr/lib/gitlab-runner/gitlab-runner run --working-directory /home/gitlab-runner --config /etc/gitla

Чтобы зарегистрировать бегуна, вам необходимо получить токен проекта и URL-адрес GitLab:

  1. В проекте GitLab перейдите в раздел Настройки > CI/CD > Runners > Развернуть.
  2. В разделе Исполнители проекта нажмите Новый исполнитель проекта и следуйте форме, чтобы создать нового исполнителя для вашего проекта.
  3. После установки бегуна вы найдете токен регистрации и URL-адрес GitLab. Скопируйте оба в текстовый редактор; они понадобятся вам для следующей команды. Они будут называться https://your_gitlab.com и project_token.

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

sudo gitlab-runner register -n --url https://your_gitlab.com --registration-token project_token --executor docker --description "Deployment Runner" --docker-image "docker:stable" --tag-list deployment --docker-privileged

Опции команды можно интерпретировать следующим образом:

  • -n выполняет команду register в неинтерактивном режиме (мы указываем все параметры как параметры команды).
  • --url — это URL-адрес GitLab, который вы скопировали со страницы бегунов в GitLab.
  • --registration-token — это токен, который вы скопировали со страницы бегунов в GitLab.
  • --executor — тип исполнителя. docker выполняет каждое задание CI/CD в контейнере Docker (см. документацию GitLab по исполнителям).
  • --description — это описание бегуна, которое будет отображаться в GitLab.
  • --docker-image — это образ Docker по умолчанию, используемый в заданиях CI/CD, если не указано явно.
  • --tag-list — это список тегов, назначенных бегуну. Теги можно использовать в конфигурации конвейера для выбора конкретных исполнителей для задания CI/CD. Тег deployment позволит вам обратиться к этому конкретному исполнителю для выполнения задания по развертыванию.
  • --docker-privileged выполняет контейнер Docker, созданный для каждого задания CI/CD, в привилегированном режиме. Привилегированный контейнер имеет доступ ко всем устройствам на хост-компьютере и имеет почти такой же доступ к хосту, как и процессы, работающие вне контейнеров (см. документацию Docker о привилегиях во время выполнения и возможностях Linux). Причина запуска в привилегированном режиме заключается в том, что вы можете использовать Docker-in-Docker (dind) для создания образа Docker в вашем конвейере CI/CD. Хорошей практикой является предоставление контейнеру минимальных требований, которые ему необходимы. Для использования Docker-in-Docker вам необходимо работать в привилегированном режиме. Имейте в виду, что вы зарегистрировали бегун только для этого конкретного проекта, где вы контролируете команды, выполняемые в привилегированном контейнере.

После выполнения команды gitlab-runner Register вы получите следующий результат:

Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!

Проверьте процесс регистрации, перейдя в Настройки > CI/CD > Runners в GitLab, где отобразится зарегистрированный участник.

На следующем шаге вы создадите пользователя развертывания.

Шаг 3 — Создание пользователя развертывания

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

На вашем сервере создайте нового пользователя:

sudo adduser deployer

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

Добавьте пользователя в группу Docker:

sudo usermod -aG docker deployer

Это позволяет deployer выполнить команду docker, необходимую для выполнения развертывания.

Внимание! Добавление пользователя в группу Docker предоставляет привилегии, эквивалентные привилегиям пользователя root. Дополнительные сведения о том, как это влияет на безопасность вашей системы, см. в разделе Поверхность атаки Docker Daemon.

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

Шаг 4 — Настройка SSH-ключа

Вы собираетесь создать ключ SSH для пользователя развертывания. GitLab CI/CD позже будет использовать ключ для входа на сервер и выполнения процедуры развертывания.

Начнем с переключения на только что созданного пользователя deployer, для которого вы сгенерируете ключ SSH:

su deployer

Вам будет предложено ввести пароль развертывателя для завершения переключения пользователя.

Затем сгенерируйте 4096-битный SSH-ключ. Важно правильно ответить на вопросы команды ssh-keygen:

  1. Первый вопрос: ответьте на него с помощью ENTER, который сохранит ключ в расположении по умолчанию (остальная часть этого руководства предполагает, что ключ хранится в расположении по умолчанию).
  2. Второй вопрос: настраивает пароль для защиты закрытого ключа SSH (ключа, используемого для аутентификации). Если вы укажете парольную фразу, вам придется вводить ее каждый раз, когда используется закрытый ключ. В общем, парольная фраза добавляет еще один уровень безопасности к ключам SSH, что является хорошей практикой. Кто-то, владеющий закрытым ключом, также потребует парольную фразу для использования ключа. Для целей данного руководства важно, чтобы у вас была пустая парольная фраза, поскольку конвейер CI/CD будет выполняться в неинтерактивном режиме и, следовательно, не позволяет вводить парольную фразу.

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

ssh-keygen -b 4096

Чтобы авторизовать ключ SSH для пользователя deployer, вам необходимо добавить открытый ключ в файл authorized_keys:

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

~ — это сокращение от дома пользователя в Linux. Программа cat распечатает содержимое файла; здесь вы используете оператор >> для перенаправления вывода cat и добавления его в файл authorized_keys.

На этом этапе вы создали пару ключей SSH для конвейера CI/CD для входа в систему и развертывания приложения. Далее вы сохраните закрытый ключ в GitLab, чтобы сделать его доступным во время процесса конвейера.

Шаг 5. Сохранение закрытого ключа в переменной GitLab CI/CD

Вы собираетесь сохранить закрытый ключ SSH в переменной файла GitLab CI/CD, чтобы конвейер мог использовать ключ для входа на сервер.

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

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

Начните с показа закрытого ключа SSH:

cat ~/.ssh/id_rsa

Скопируйте вывод в буфер обмена. Обязательно добавьте разрыв строки после -----END RSA PRIVATE KEY ----- :

-----BEGIN RSA PRIVATE KEY-----
...
-----END RSA PRIVATE KEY-----

Теперь перейдите в Настройки > CI/CD > Переменные в своем проекте GitLab и нажмите Добавить переменную. Заполните форму следующим образом:

  • Ключ: ID_RSA
  • Значение: вставьте закрытый ключ SSH из буфера обмена (включая разрыв строки в конце).
  • Тип: Файл.
  • Область действия среды: Все (по умолчанию)
  • Защита переменной: Проверено
  • Переменная маски: Не отмечена

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

Файл, содержащий закрытый ключ, будет создан на бегуне для каждого задания CI/CD, а его путь будет сохранен в переменной среды $ID_RSA.

Создайте еще одну переменную с IP-адресом вашего сервера. Нажмите Добавить переменную и заполните форму следующим образом:

  • Ключ: SERVER_IP
  • Значение: IP_вашего_сервера
  • Тип: Переменная.
  • Область действия среды: Все (по умолчанию).
  • Защита переменной: Проверено
  • Переменная маски: Выбрано

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

  • Ключ: SERVER_USER
  • Значение: развертыватель
  • Тип: Переменная.
  • Область действия среды: Все (по умолчанию).
  • Защита переменной: Проверено
  • Переменная маски: Выбрано

Теперь вы сохранили закрытый ключ в переменной GitLab CI/CD, что делает ключ доступным во время выполнения конвейера. На следующем этапе вы переходите к настройке конвейера CI/CD.

Шаг 6. Настройка файла .gitlab-ci.yml

Вы собираетесь настроить конвейер GitLab CI/CD. Конвейер создаст образ Docker и отправит его в реестр контейнеров. GitLab предоставляет реестр контейнеров для каждого проекта. Вы можете изучить реестр контейнеров, перейдя в раздел Пакеты и реестры > Реестр контейнеров в своем проекте GitLab (подробнее читайте в документации по реестру контейнеров GitLab). Последний шаг вашего конвейера – чтобы войти на свой сервер, извлеките последний образ Docker, удалите старый контейнер и запустите новый контейнер.

Теперь вы создадите файл .gitlab-ci.yml, содержащий конфигурацию конвейера. В GitLab перейдите на страницу Обзор проекта, нажмите кнопку + и выберите Новый файл. Затем установите для Имя файла значение .gitlab-ci.yml.

(В качестве альтернативы вы можете клонировать репозиторий и внести все следующие изменения в .gitlab-ci.yml на своем локальном компьютере, а затем зафиксировать и отправить его в удаленный репозиторий.)

Для начала добавьте следующее:

stages:
  - publish
  - deploy

Каждое задание назначается _stage_. Задания, назначенные на один и тот же этап, выполняются параллельно (если доступно достаточное количество исполнителей). Этапы будут выполняться в том порядке, в котором они были указаны. Здесь этап publish будет первым, а этап deploy — вторым. Последующие этапы начинаются только тогда, когда предыдущий этап завершился успешно (то есть все задания выполнены). Сценические имена можно выбирать произвольно.

Если вы хотите объединить эту конфигурацию компакт-диска с существующим конвейером CI, который тестирует и собирает приложение, вы можете добавить этапы publish и deploy после существующих этапов. так что развертывание происходит только в том случае, если тесты пройдены.

После этого добавьте это в свой файл .gitlab-ci.yml:

. . .
variables:
  TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
  TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA

Раздел переменных определяет переменные среды, которые будут доступны в контексте раздела script задания. Эти переменные будут доступны как обычные переменные среды Linux; то есть вы можете ссылаться на них в сценарии, добавляя в качестве префикса знак доллара, например $TAG_LATEST. GitLab создает несколько предопределенных переменных для каждого задания, которые предоставляют контекстно-зависимую информацию, такую как имя ветки или хеш фиксации, над которой работает задание (подробнее о предопределенной переменной читайте здесь). Здесь вы составляете две переменные среды из предопределенных переменных. Они представляют:

  • CI_REGISTRY_IMAGE: представляет URL-адрес реестра контейнеров, привязанного к конкретному проекту. Этот URL-адрес зависит от экземпляра GitLab. Например, URL-адреса реестра для проектов gitlab.com соответствуют шаблону: registry.gitlab.com/your_user/your_project. Но поскольку GitLab предоставит эту переменную, вам не нужно знать точный URL-адрес.
  • CI_COMMIT_REF_NAME: имя ветки или тега, для которого создается проект.
  • CI_COMMIT_SHORT_SHA: первые восемь символов версии фиксации, для которой создан проект.

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

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

С другой стороны, TAG_COMMIT использует первые восемь символов развертываемого SHA коммита в качестве тега изображения, тем самым создавая уникальный образ Docker для каждого коммита. Вы сможете проследить историю образов Docker вплоть до детализации коммитов Git. Это распространенный метод при непрерывном развертывании, поскольку он позволяет быстро развернуть более старую версию кода в случае дефектного развертывания.

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

$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME указывает базовое имя образа Docker. Согласно документации GitLab, имя образа Docker должно соответствовать следующей схеме:

image name scheme
<registry URL>/<namespace>/<project>/<image>

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

repository name levels
registry.example.com/group/project:some-tag registry.example.com/group/project/image:latest registry.example.com/group/project/my/image:rc1

Для вашей переменной TAG_COMMIT вы использовали второй вариант, где image будет заменен именем ветки.

Затем добавьте следующее в файл .gitlab-ci.yml:

. . .
publish:
  image: docker:latest
  stage: publish
  services:
    - docker:dind
  script:
    - docker build -t $TAG_COMMIT -t $TAG_LATEST .
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker push $TAG_COMMIT
    - docker push $TAG_LATEST

Раздел publish — это первое задание в вашей конфигурации CI/CD. Давайте разберем это:

  • image — это образ Docker, который будет использоваться для этого задания. Бегун GitLab создаст контейнер Docker для каждого задания и выполнит скрипт внутри этого контейнера. Изображение docker:latest гарантирует, что команда docker будет доступна.
  • stage назначает задание этапу publish.
  • services определяет Docker-in-Docker — сервис dind. Именно по этой причине вы зарегистрировали программу запуска GitLab в привилегированном режиме.

Раздел script задания publish определяет команды оболочки, которые необходимо выполнить для этого задания. При выполнении этих команд рабочий каталог будет установлен в корень репозитория.

  • docker build ...: создает образ Docker на основе Dockerfile и помечает его последним тегом фиксации, определенным в разделе переменных.
  • docker login ...: регистрирует Docker в реестре контейнеров проекта. В качестве токена аутентификации вы используете предопределенную переменную $CI_JOB_TOKEN. GitLab сгенерирует токен и будет действовать в течение всего срока действия задания.
  • docker push...: отправляет оба тега изображения в реестр контейнеров.

После этого добавьте задание deploy в ваш .gitlab-ci.yml:

. . .
deploy:
  image: alpine:latest
  stage: deploy
  tags:
    - deployment
  script:
    - chmod og= $ID_RSA
    - apk update && apk add openssh-client
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY"
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker container rm -f my-app || true"
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name my-app $TAG_COMMIT"

Alpine — это легкий дистрибутив Linux, и здесь достаточно образа Docker. Вы назначаете задание этапу deploy. Тег развертывания гарантирует, что задание будет выполнено на бегунах с тегом deployment, например на бегуне, который вы настроили на шаге 2.

Раздел script задания deploy начинается с двух конфигурационных команд:

  • chmod og= $ID_RSA: отзывает все разрешения для группы и других из закрытого ключа, так что его может использовать только владелец. Это обязательное требование, иначе SSH откажется работать с закрытым ключом.
  • apk update && apk add openssh-client: обновляет менеджер пакетов Alpine (apk) и устанавливает openssh-client, который предоставляет команду ssh.

Далее следуют четыре последовательные команды ssh. Шаблон для каждого:

ssh connect pattern for all deployment commands
ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "command"

В каждом операторе ssh вы выполняете команду на удаленном сервере. Для этого вы проходите аутентификацию с помощью своего закрытого ключа.

Возможные варианты:

  • -i означает файл идентификации, а $ID_RSA — это переменная GitLab, содержащая путь к файлу закрытого ключа.
  • -o StrictHostKeyChecking=no позволяет обойти вопрос о том, доверяете ли вы удаленному хосту. На этот вопрос невозможно ответить в неинтерактивном контексте, таком как конвейер.
  • $SERVER_USER и $SERVER_IP — это переменные GitLab, которые вы создали на шаге 5. Они определяют удаленный хост и пользователя для входа в систему для SSH-соединения.
  • команда будет выполнена на удаленном хосте.

В конечном итоге развертывание происходит путем выполнения этих четырех команд на вашем сервере:

  1. вход в Docker ...: регистрирует Docker в реестре контейнеров.
  2. docker pull ...: извлекает последний образ из реестра контейнеров.
  3. dockerContainer rm ...: удаляет существующий контейнер, если он существует. || true гарантирует, что код выхода всегда будет успешным, даже если не было запущенного контейнера с именем my-app. Это гарантирует выполнение процедуры удаления, если существует без нарушения конвейера, когда контейнер не существует (например, при первом развертывании).
  4. docker run ...: запускает новый контейнер, используя последний образ из реестра. Контейнер будет называться my-app. Порт 80 на хосте будет привязан к порту 80 контейнера (порядок: -p хост:контейнер). -d запускает контейнер в автономном режиме, иначе конвейер зависнет в ожидании завершения команды.

Примечание. Может показаться странным использовать SSH для запуска этих команд на вашем сервере, учитывая, что GitLab Runner, выполняющий команды, является тем же самым сервером. Тем не менее, это необходимо, поскольку бегун выполняет команды в контейнере Docker, поэтому вы будете выполнять развертывание внутри контейнера, а не на сервере, если будете выполнять команды без использования SSH. Можно возразить, что вместо использования Docker в качестве исполнителя-исполнителя вы можете использовать исполнитель оболочки для запуска команд на самом хосте. Но это создаст ограничение для вашего конвейера, а именно то, что исполнитель должен быть тем же сервером, на котором вы хотите выполнить развертывание. Это неустойчивое и расширяемое решение, поскольку однажды вам может потребоваться перенести приложение на другой сервер или использовать другой сервер-исполнитель. В любом случае имеет смысл использовать SSH для выполнения команд развертывания, будь то по техническим причинам или по причинам, связанным с миграцией.

Давайте продолжим, добавив это в задание по развертыванию в вашем .gitlab-ci.yml:

. . .
deploy:
. . .
  environment:
    name: production
    url: http://your_server_IP
  only:
    - master

Среды GitLab позволяют вам контролировать развертывания внутри GitLab. Вы можете изучить среды в своем проекте GitLab, перейдя в Операции > Среды. Если конвейер еще не завершен, доступной среды не будет, поскольку развертывание еще не проводилось.

Когда задание конвейера определяет раздел environment, GitLab будет создавать развертывание для данной среды (здесь production) каждый раз, когда задание успешно завершается. Это позволяет вам отслеживать все развертывания, созданные GitLab CI/CD. Для каждого развертывания вы можете увидеть связанный коммит и ветку, для которой он был создан.

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

Раздел only определяет имена ветвей и тегов, для которых будет выполняться задание. По умолчанию GitLab запускает конвейер при каждом отправке в репозиторий и выполняет все задания (при условии, что файл .gitlab-ci.yml существует). Раздел only — это один из вариантов ограничения выполнения задания определенными ветвями/тегами. Здесь вы хотите выполнить задание развертывания только для ветки master. Чтобы определить более сложные правила относительно того, должно ли задание выполняться или нет, взгляните на синтаксис правил.

Примечание. В октябре 2020 года GitHub изменил соглашение об именовании ветки по умолчанию с master на main. Другие провайдеры, такие как GitLab и сообщество разработчиков в целом, начинают следовать этому подходу. Термин master используется в этом руководстве для обозначения ветки по умолчанию, для которой у вас может быть другое имя.

Полный файл .gitlab-ci.yml будет выглядеть следующим образом:

stages:
  - publish
  - deploy

variables:
  TAG_LATEST: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:latest
  TAG_COMMIT: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_NAME:$CI_COMMIT_SHORT_SHA

publish:
  image: docker:latest
  stage: publish
  services:
    - docker:dind
  script:
    - docker build -t $TAG_COMMIT -t $TAG_LATEST .
    - docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY
    - docker push $TAG_COMMIT
    - docker push $TAG_LATEST

deploy:
  image: alpine:latest
  stage: deploy
  tags:
    - deployment
  script:
    - chmod og= $ID_RSA
    - apk update && apk add openssh-client
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker login -u gitlab-ci-token -p $CI_JOB_TOKEN $CI_REGISTRY"
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker pull $TAG_COMMIT"
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker container rm -f my-app || true"
    - ssh -i $ID_RSA -o StrictHostKeyChecking=no $SERVER_USER@$SERVER_IP "docker run -d -p 80:80 --name my-app $TAG_COMMIT"
  environment:
    name: production
    url: http://your_server_IP
  only:
    - master

Наконец, нажмите Зафиксировать изменения внизу страницы GitLab, чтобы создать файл .gitlab-ci.yml. В качестве альтернативы, когда вы клонировали репозиторий Git локально, зафиксируйте и отправьте файл на удаленный компьютер.

Вы создали конфигурацию GitLab CI/CD для создания образа Docker и его развертывания на своем сервере. На следующем этапе вы проверяете развертывание.

Шаг 7 — Проверка развертывания

Теперь вы проверите развертывание в различных местах GitLab, а также на своем сервере и в браузере.

Когда файл .gitlab-ci.yml отправляется в репозиторий, GitLab автоматически обнаруживает его и запускает конвейер CI/CD. Когда вы создали файл .gitlab-ci.yml, GitLab запустил первый конвейер.

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

Давайте рассмотрим трубопровод. Нажмите кнопку Пройдено в столбце Статус, чтобы открыть страницу обзора конвейера. Вы получите обзор общей информации, такой как:

  • Продолжительность выполнения всего конвейера.
  • Для какого коммита и ветки был выполнен конвейер.
  • Связанные запросы на слияние. Если для ответственной ветки существует открытый мерж-реквест, он появится здесь.
  • Все задания, выполняемые в этом конвейере, а также их статус.

Затем нажмите кнопку Опубликовать, чтобы открыть страницу результатов задания развертывания.

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

Откройте Создать > Вакансии. У вас будет обзор всех развертываний вакансий. Пока было только одно развертывание. Для каждого развертывания в самом правом углу есть кнопка запустить еще раз. Повторное развертывание повторит задание по развертыванию этого конкретного конвейера.

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

Примечание. Ваш реестр контейнеров GitLab может иметь политику истечения срока действия. Политика истечения срока действия регулярно удаляет старые образы и теги из реестра контейнеров. Как следствие, развертывание, срок действия которого превышает срок действия политики, не удастся повторно развернуть, поскольку образ Docker для этого коммита будет удален из реестра. Вы можете управлять политикой истечения срока действия в разделе Настройки > CI/CD > Политика истечения срока действия тега реестра контейнеров. Интервал истечения срока действия обычно устанавливается на что-то большее, например 90 дней. Но когда вы сталкиваетесь со случаем попытки развернуть образ, который был удален из реестра из-за политики истечения срока действия, вы можете решить проблему, перезапустив задание публикации этого конкретного конвейера как ну, который заново создаст и отправит образ для данного коммита в реестр.

Затем нажмите кнопку Просмотреть развертывание, после чего в браузере откроется http://your_server_IP, и вы увидите Мой личный веб-сайт. заголовок.

Наконец, мы хотим проверить развернутый контейнер на вашем сервере. Подойдите к своему терминалу и обязательно войдите в систему еще раз, если вы уже отключились (это работает для обоих пользователей, sammy и deployer):

ssh sammy@your_server_IP

Теперь перечислим запущенные контейнеры:

docker container ls

В нем будет указан контейнер my-app:

CONTAINER ID        IMAGE                                                          COMMAND                  CREATED             STATUS              PORTS                NAMES
5b64df4b37f8        registry.your_gitlab.com/your_gitlab_user/your_project/master:your_commit_sha   "nginx -g 'daemon of…"   4 hours ago         Up 4 hours          0.0.0.0:80->80/tcp   my-app

Теперь вы проверили развертывание. На следующем шаге вы выполните процесс отката развертывания.

Шаг 8 — Откат развертывания

Далее вы обновите веб-страницу, на которой будет создано новое развертывание, а затем повторно развернуто предыдущее с использованием сред GitLab. Здесь рассматривается вариант использования отката развертывания в случае неправильного развертывания.

Начните с небольшого изменения в файле index.html:

  1. В GitLab перейдите к Обзору проекта и откройте файл index.html.
  2. Нажмите кнопку Изменить, чтобы открыть онлайн-редактор.
  3. Измените содержимое файла на следующее:
<html>
<body>
<h1>My Enhanced Personal Website</h1>
</body>
</html>

Сохраните изменения, нажав Применить изменения внизу страницы.

Для развертывания изменений будет создан новый конвейер. В GitLab перейдите в раздел CI/CD > Pipelines. Когда конвейер завершится, вы можете открыть http://your_server_IP в браузере для обновленной веб-страницы, которая теперь отображает Мой расширенный персональный веб-сайт. Мой личный веб-сайт.

Когда вы перейдете к Build > Jobs, вы увидите вновь созданное развертывание. Теперь нажмите кнопку запустить еще раз исходного, более старого развертывания:

Подтвердите всплывающее окно, нажав кнопку Откат.

Задание развертывания этого старого конвейера будет перезапущено, и вы будете перенаправлены на страницу обзора задания. Дождитесь завершения задания, затем откройте http://your_server_IP в браузере, где вы увидите начальный заголовок Мой личный веб-сайт. появляюсь снова.

Давайте подведем итоги того, чего вы достигли в ходе этого урока.

Заключение

В этом руководстве вы настроили конвейер непрерывного развертывания с помощью GitLab CI/CD. Вы создали небольшой веб-проект, состоящий из файла HTML и файла Dockerfile. Затем вы настроили конфигурацию конвейера .gitlab-ci.yml следующим образом:

  1. Создайте образ Docker.
  2. Отправьте образ Docker в реестр контейнеров.
  3. Войдите на сервер, извлеките последний образ, остановите текущий контейнер и запустите новый.

GitLab теперь будет развертывать веб-страницу на вашем сервере при каждой отправке в репозиторий.

Кроме того, вы проверили развертывание в GitLab и на своем сервере. Вы также создали второе развертывание и откатились к первому развертыванию с использованием сред GitLab, что демонстрирует, как вы справляетесь с дефектными развертываниями.

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

В качестве следующего шага вы можете сделать свой сервис доступным по доменному имени и защитить соединение с помощью HTTPS, для чего хорошим продолжением является «Как использовать Traefik в качестве обратного прокси-сервера для контейнеров Docker в Ubuntu 20.04/18.04».

Автор выбрал Фонд свободного и открытого исходного кода для получения пожертвования в рамках программы Write for DOnations.

Статьи по данной тематике: