Как настроить конвейер непрерывного развертывания с помощью 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
- Создать репозиторий Gitlab
- Регистрация Gitlab Runner
- Создайте пользователя развертывания
- Настройка SSH-ключа
- Хранение SSH-ключа в Gitlab
- Настройте конвейер Gitlab CI/CD
- Проверка развертывания
- Как откатить развертывание
Шаг 1 — Создание репозитория GitLab
Начнем с создания проекта GitLab и добавления в него HTML-файла. Позже вы скопируете HTML-файл в образ Nginx Docker, который, в свою очередь, развернете на сервере.
Войдите в свой экземпляр GitLab и нажмите Новый проект.
- На экране Создать новый проект выберите Создать пустой проект.
- Дайте ему правильное имя проекта.
- При необходимости добавьте цель развертывания проекта.
- Обязательно установите для параметра Уровень видимости значение Частный или Общедоступный в зависимости от ваших требований.
- Наконец нажмите Создать проект.
Вы будете перенаправлены на страницу обзора проекта.
Давайте создадим 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:
- В проекте GitLab перейдите в раздел Настройки > CI/CD > Runners > Развернуть.
- В разделе Исполнители проекта нажмите Новый исполнитель проекта и следуйте форме, чтобы создать нового исполнителя для вашего проекта.
- После установки бегуна вы найдете токен регистрации и 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
:
- Первый вопрос: ответьте на него с помощью
ENTER
, который сохранит ключ в расположении по умолчанию (остальная часть этого руководства предполагает, что ключ хранится в расположении по умолчанию). - Второй вопрос: настраивает пароль для защиты закрытого ключа 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 levelsregistry.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 commandsssh -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-соединения.команда
будет выполнена на удаленном хосте.
В конечном итоге развертывание происходит путем выполнения этих четырех команд на вашем сервере:
вход в Docker ...
: регистрирует Docker в реестре контейнеров.docker pull ...
: извлекает последний образ из реестра контейнеров.dockerContainer rm ...
: удаляет существующий контейнер, если он существует.|| true
гарантирует, что код выхода всегда будет успешным, даже если не было запущенного контейнера с именемmy-app
. Это гарантирует выполнение процедуры удаления, если существует без нарушения конвейера, когда контейнер не существует (например, при первом развертывании).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
:
- В GitLab перейдите к Обзору проекта и откройте файл
index.html
. - Нажмите кнопку Изменить, чтобы открыть онлайн-редактор.
- Измените содержимое файла на следующее:
<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
следующим образом:
- Создайте образ Docker.
- Отправьте образ Docker в реестр контейнеров.
- Войдите на сервер, извлеките последний образ, остановите текущий контейнер и запустите новый.
GitLab теперь будет развертывать веб-страницу на вашем сервере при каждой отправке в репозиторий.
Кроме того, вы проверили развертывание в GitLab и на своем сервере. Вы также создали второе развертывание и откатились к первому развертыванию с использованием сред GitLab, что демонстрирует, как вы справляетесь с дефектными развертываниями.
На этом этапе вы автоматизировали всю цепочку развертывания. Теперь вы можете чаще делиться изменениями кода со всем миром и/или с клиентами. В результате циклы разработки, вероятно, станут короче, поскольку на сбор отзывов и публикацию изменений кода уходит меньше времени.
В качестве следующего шага вы можете сделать свой сервис доступным по доменному имени и защитить соединение с помощью HTTPS, для чего хорошим продолжением является «Как использовать Traefik в качестве обратного прокси-сервера для контейнеров Docker в Ubuntu 20.04/18.04».
Автор выбрал Фонд свободного и открытого исходного кода для получения пожертвования в рамках программы Write for DOnations.