Как использовать Rsync и SSH в Dockerized GitLab CI Pipeline
rsync — популярная утилита синхронизации файлов, использующая эффективный алгоритм для минимизации потребления полосы пропускания. Одной из общих ролей rsync является развертывание сборки веб-сайта на удаленном рабочем сервере. Вот как можно сочетать универсальность rsync с автоматизацией, обеспечиваемой конвейерами GitLab CI.
Исполнители конвейера
GitLab CI поддерживает несколько типов исполнителей конвейера. Они определяют среду, в которой будет выполняться ваше задание. Исполнитель shell
используется по умолчанию и работает на чистом железе на хост-компьютере. Это позволяет вашим конвейерам использовать любую команду, доступную на хосте, без дополнительной настройки. Поскольку большинство популярных дистрибутивов Linux поставляются с установленным rsync, с этим подходом легко справиться.
К сожалению, исполнитель shell
не обеспечивает надежной изоляции и со временем может загрязнить среду вашего хоста. Лучшей альтернативой является исполнитель docker
, который запускает новый контейнер Docker для каждого задания CI. Все задания выполняются в чистой среде, которая не может повлиять на хост.
Недостатком здесь является то, что базовые образы Docker обычно не включают rsync
или ssh
. Даже официальные образы ОС, такие как ubuntu:latest
, поставляются в виде минимальных сборок без этих команд. Это делает сценарий конвейера немного более сложным для добавления зависимостей и rsync
ваших файлов.
Вот как добавить rsync в ваш конвейер. Прежде чем продолжить, убедитесь, что у вас есть GitLab Runner на основе Docker. Мы также предполагаем, что у вас есть готовый к использованию проект GitLab.
Готовиться
Вам понадобится пара ключей SSH, если вы будете использовать rsync для подключения к удаленному хосту SSH. Вы можете сгенерировать открытый и закрытый ключи, запустив ssh-keygen -t rsa
. Скопируйте открытый ключ на сервер, к которому вы будете подключаться.
Затем скопируйте сгенерированный закрытый ключ в буфер обмена:
cat ~/.ssh/id_rsa | xclip -selection c
Перейдите в свой проект GitLab и нажмите «Настройки» в нижней части левого навигационного меню. Щелкните пункт «CI/CD» в подменю. Прокрутите страницу вниз до раздела «Переменные».
Нажмите синюю кнопку «Добавить переменную». Дайте вашей новой переменной имя в поле «Ключ». Мы используем SSH_PRIVATE_KEY
. Вставьте свой закрытый ключ в поле «Значение», включая начальную строку ----BEGIN
и завершающую строку -----END
.
Добавление ключа в качестве переменной CI позволит вам позже ссылаться на него в конвейере. Он будет добавлен к агенту SSH в контейнерах, которые создает ваш конвейер.
Добавление вашего файла конвейера
GitLab CI запускает задания на основе содержимого файла .gitlab-ci.yml
в вашем репозитории. GitLab автоматически найдет этот файл и запустит конвейер, который он определяет, когда вы отправляете изменения в свои ветки.
deploy: stage: deploy image: alpine:latest script: - rsync -atv --delete --progress ./ user@example.com:/var/www/html
Этот .gitlab-ci.yml
содержит задание, которое использует rsync
для синхронизации содержимого рабочего каталога с /var/www/html
в сервер example.com
. Он использует образ Docker alpine:latest
в качестве среды сборки. Конвейер в настоящее время не работает, так как rsync
не включен в образ Alpine.
Установка SSH и rsync
Alpine — хорошая основа для работы, потому что это легковесный образ с небольшим количеством зависимостей. Это снижает использование сети, в то время как GitLab извлекает образ в начале задания, ускоряя конвейер. Чтобы заставить rsync работать, добавьте в образ SSH и rsync, а затем запустите агент SSH и зарегистрируйте сгенерированный ранее закрытый ключ.
deploy: stage: deploy image: alpine:latest before_script: - apk update && apk add openssh-client rsync - eval $(ssh-agent -s) - echo "$SSH_PRIVATE_KEY" | ssh-add - script: - rsync -atv --delete --progress ./ user@example.com:/var/www/html
OpenSSH и rsync устанавливаются с помощью менеджера пакетов Alpine apk
. Агент аутентификации SSH запускается, и ваш закрытый ключ добавляется с помощью ssh-add
. GitLab автоматически вставляет переменную среды SSH_PRIVATE_KEY
со значением, которое вы определили в настройках вашего проекта. Если вы использовали другой ключ на экране переменных GitLab, убедитесь, что вы соответствующим образом настроили конвейер.
Управление проверкой хоста
SSH интерактивно запрашивает подтверждение при первом подключении к новому удаленному хосту. Это несовместимо со средой CI, где вы не сможете видеть эти запросы или отвечать на них.
Для решения этой проблемы доступны два варианта: отключить строгие проверки ключей хоста или заранее зарегистрировать свой сервер как «известный» хост.
Для первого варианта добавьте следующую строку в before_script
конвейера:
- echo "Host *ntStrictHostKeyChecking no" >> ~/.ssh/config
Хотя это работает, это потенциальный риск для безопасности. У вас не будет предупреждения, если злоумышленник получит контроль над доменом или IP-адресом вашего сервера. Использование проверки ключа хоста позволяет вам убедиться, что личность удаленного устройства соответствует вашим ожиданиям.
Вы можете добавить удаленный узел в качестве известного узла неинтерактивно, подключившись к нему на своем собственном компьютере за пределами конвейера. Проверьте файл ~/.ssh/known_hosts
и найдите строку, содержащую IP-адрес или имя хоста удаленного устройства. Скопируйте эту строку и используйте описанную ранее процедуру, чтобы добавить новую переменную GitLab CI. Назовите эту переменную SSH_HOST_KEY
.
Теперь обновите раздел before_script
следующей строкой:
- echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts
Теперь вы сможете подключиться к серверу, не получая никаких запросов на подтверждение. Отправьте свой код в репозиторий GitLab и наблюдайте за завершением конвейера.
Дальнейшие улучшения
Этот конвейер — простой пример того, как начать работу с SSH и rsync в среде Dockerized. Существуют возможности для дальнейшего улучшения системы путем переноса этапов подготовки на выделенный этап сборки, на котором создается образ Docker, который можно повторно использовать между конвейерами.
.gitlab-ci.yml
также выиграет от большего использования переменных. Абстрагирование имени хоста удаленного сервера (example.com
), каталога (/var/www/html
) и пользователя (user
) в GitLab CI переменные помогли бы сохранить файл в чистоте, не позволили бы случайным браузерам репозиториев видеть сведения об окружающей среде и позволили бы вам изменить значения конфигурации без редактирования файла конвейера.
Краткое содержание
Использование rsync в конвейерах GitLab CI требует небольшой ручной настройки, чтобы сформировать среду сборки с нужными вам зависимостями. Вы должны вручную ввести закрытый ключ SSH и зарегистрировать удаленный сервер как известный хост.
Несмотря на то, что доступны образы Docker от сообщества, в которых используются SSH и rsync поверх популярных базовых образов, в конечном итоге они дают вам меньший контроль над вашей сборкой. Вы расширяете цепочку поставок своего конвейера с изображением, которому вы не всегда можете доверять. Начиная с базового образа ОС и добавляя то, что вам нужно, вы можете быть уверены в своих сборках.