• База знаний
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Статья также доступна на украинском (перейти к просмотру).

Как использовать Rsync из SSH для автоматизации, безопасной синхронизации и деплоя сайтов в GitLab CI/CD

В нашей первой статье по основам использования утилиты Rsync для синхронизации данных были рассмотрены ее возможности и приведены базовые приемы работы с ней в пределах локальной среды. Здесь мы сконцентрируемся на ее применении совместно с безопасным протоколом SSH для синхронизации данных, размещенных на удаленных хостах и организации deploy-процесса для веб-проекта средствами GitLab CI/CD. В то же время, будут рассмотрены некоторые из доступных средств автоматизации и оптимизации работы. Rsync в условиях, максимально приближённых к рабочим.

Безопасная работа через SSH-ключи

Повысить уровень безопасности при использовании Rsync для синхронизации данных можно путем выбора SSH в качестве удаленной оболочки с выбором способа авторизации на основе SSH-ключей вместо пароля. Такой подход обеспечивает передачу файлов в зашифрованном виде и позволяет избежать многих типов атак.

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

  1. Создание пары SSH-ключей – «открытый» и «закрытый»;

  2. передача открытого ключа на удаленный хост;

  3. Смена статуса удаленного хоста.

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

Создание SSH-ключей

Сгенерируем пару RSA-ключей на нашей локальной машине:

$ ssh-keygen -t rsa

$ ssh-keygen -t rsa

Выход команды:

Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:nlLlDq2BFUcCzkG7hkCgXV2w94OqKEZBrEWcGsSLda0 root@dedicated
The key's randomart image is:
+---[RSA 3072]----+
|==o..+=++.o  |
|o*=..oo+ +   |
|==+. .= o .  |
|+o .E. = *   |
|  . . + S =  |
| .   . + * . |
|. o + .  |
|.. . . .     |
|... .        |
+----[SHA256]-----+

Передача открытого ключа

Копируем одним из распространенных способов сгенерированный открытый ключ на удаленный хост, с которым в дальнейшем планируется работа:

$ ssh-copy-id -i ~/.ssh/id_rsa.pub alexandr75001@176.9.1*.***

$ ssh-copy-id -i ~/.ssh/id_rsa.pub alexandr75001@176.9.1*.***

Даем согласие на соединение с хостом (да).

$ ssh-copy-id -i ~/.ssh/id_rsa.pub alexandr75001@176.9.1*.***

Вводим пароль для аккаунта alexandr75001 удаленного хоста.

Пароль для аккаунта alexandr75001

Выход: 

Number of key(s) added: 1
Now try logging into the machine, with:   "ssh 'alexandr75001@176.9.1*.***'"
and check to make sure that only the key(s) you wanted were added. 

«Открытый» ключ добавлен на удаленный хост.

Изменение статуса удаленного хоста

В OpenSSH в специальном файле ~/.ssh/known_hosts сохраняется список открытых ключей хостов, к которым владелец аккаунта имеет беспрепятственный доступ. Все эти хосты для локальной системы имеют статус «Доверенный».

Перед использованием Rsync по SSH необходимо предварительно обеспечить наличие в указанном списке хостов, с которыми мы будем работать. Это можно сделать двумя путями:

  • Установить хотя бы одно соединение с нужным хостом;

  • Воспользоваться утилитой ssh-keyscan. 

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

Are you sure you want to continue connecting (yes/no/[fignerprint])?     

После этого хост получает статус «Доверенный».

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

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

$ ssh-keyscan -t rsa176.9.1*.***>> ~/.ssh/known_hosts

$ ssh-keyscan -t rsa176.9.1*.***>> ~/.ssh/known_hosts

Выход команды:

# 176.9.1*.***:22 SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.13

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

cat ~/.ssh/known_hosts

cat ~/.ssh/known_hosts

Выход:

|1|zQe0U6FB1pwPRoHr6qzXV16RbiY=|jEp3X+pYFrEzvKqRq3FsuFnyb3E= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGizGee
Zx6WURNKattRhjSbf0srbHyBDIqaRVPsNkGvxHil1pRG0agV7/qpS8c0et9GGNN/VNZF8TXivF1ntV/4= 176.9.1*.*** ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEB55myQPm0kDpLG9xjONQdG0Z9lNb8BINlHWp1woy9td/QoVy9ADtYlD1x+OTyvPp7mDefVzc72IKJrAs
DnqumE9Dv8Ret/fOxG6DPTgKP2EujAO28hZ5
+ZVHFBzyOvrYFQepkBWqsqaC3d+g4ysYRfJJw6yf0dTkRQbDbzSaDXX8LD+YuYL1QmYKv+h4A5zIUNuCaLJcmTh/MaACC6R874HYtKPGFmMeo3AX04XTp7sA+iN1A4Ow
TMBx6ypSaCpDjCLZcHcOrUh/8ABULsb+rFG6gmdht
+CM2vVHdsWmpv9dYWsn5CRSmaMp2uXqm1jGKLr1BO+q2eEJQV57****

Можно убедиться, что запись для определенного IP присутствует в файле. Следует отметить, что первая запись относится также к той же машине – она была сформирована сразу после установления соединения при копировании нами файла открытого ключа.

Подробный обзор работы с файлом ssh_config читайте в статье “Настройка ssh_config” а об использовании known_hosts Вы можете узнать из статьи “Файл known_hosts

Rsync в GitLab CI/CD для деплоя сайтов

В случае наличия готового к использованию GitLab-проекта можно организовать его развертывание на хосте средствами GitLab CI/CDс применением возможностей программы Rsync и протокола SSH. Необходимым условием при этом будет применение GitLab Runner на основе Docker. Это позволит обеспечить выполнение каждой из задач в «незагрязненной» изолированной среде.  

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

Можно выделить несколько этапов для выполнения нашей задачи по деплою сайта:

  • Подготовительный этап;

  • формирование конвейерного сценария;

  • Управление Host-верификацией.  

Подготовительный этап

Цель подготовительного этапа состоит в получении пара SSH-ключей и их регистрации на удаленном сервере и на платформе GitLab собственного проекта. Выполним необходимые действия для реализации указанной цели.

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

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

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

$ sudo apt install xclip

$ sudo apt install xclip

Подтверждаем свое согласие (Y).

Setting up xclip (0.13-2)

Выход: Setting up xclip (0.13-2). Так что программа установлена.

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

 $ cat ~/.ssh/id_rsa | xclip -selection c

Второй путь проще. Для этого достаточно вывести все символы ключа на экран, как показано ниже, и скопировать их. При этом следует иметь в виду, что копировать нужно как первую (– – – – – BEGIN ...), да и последнюю (– – – – – END ...) строчки, иначе в дальнейшем возникнут ошибки.

$ cat ~/.ssh/id_rsa

$ cat ~/.ssh/id_rsa

Настройки собственного GitLab-проекта, нажав Настройки в левой части окна. Далее следует выбрать пункт CI/CDи найти в правой части окна раздел Variables (см. скриншот).

После того, как ключ скопирован в буфер, перейдите к настройкам собственного GitLab-проекта, нажав Настройки в левой части окна. Далее следует выбрать пункт CI/CDи найти в правой части окна раздел Variables (см. скриншот).

Variables

Для создания новой переменной следует нажать кнопку Add variable снизу, после чего появится окно для внесения нужных значений (см. скриншот ниже)

Нажать кнопку Add variable

В поле Key введем произвольное имя новой переменной (SSH_PRIVATE_KEY). У поле Value вставим из буфера обмена скопированный нами закрытый ключ. Целесообразно сделать переменную скрытой, включив опцию Mask variable из области Флаги в нижней части окна. Это сделает его невидимым в журналах задач. 

После того как поля значений будут заполнены, следует нажать кнопку Add variable, инициирующий процесс создания переменной

Формирование конвейерного сценария

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

Приведем основные записи файла .gitlab-in.yml, касающиеся нашего проекта:   

jobs:
 deploy:
    stage: deploy
    image: alpine:latest // Docker-шаблон для создания среды сборки
    before_script:
      - apk update && apk add openssh-client rsync // включение в шаблон  rsync и ssh
      - eval $(ssh-agent -s) // Запуск агента аутентификации SSH   
      - echo "$SSH_PRIVATE_KEY" | ssh-add - // Регистрация закрытого ключа
    script:
       - rsync -atq --progress ./ alexandr75001@176.9.1*.***:/var/www/html

// Запуск rsync для синхронизации данных рабочего каталога и удаленного сервера

Управление Host-верификацией

При первом подключении к удаленному хосту SSH в интерактивном режиме запрос на подтверждение аутентификации пользователя. Однако такой режим несовместим с CI/CD-средой. Для этого выходом из ситуации может служить регистрация удаленного сервера в качестве «known» или доверенного узла.

Выше мы рассматривали способы, как этого добиться, то есть получить соответствующую запись в файле ~/.ssh/known_hosts локальной системы Остается только скопировать запись в буфер обмена и вставить его в настройках GitLab CI/CD собственного проекта, создав новую переменную, которая может называться, например, SSH_HOST_KEY. После этого следует вставить в файл сценария в раздел before_script одну единственную строчку:

- echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts

Теперь все. Больше никаких «лишних» запросов в подтверждение авторизации не будет, а значит, можно будет спокойно работать над проектом.

Синхронизация локального и удаленного устройств по SSH

У нас есть последний архивный файл резервной копии проекта в популярном формате tar.gz. Задача состоит в его синхронизации с удаленным сервером и удалением из каталога – источника. И в этом нам поможет утилита Rsync. 

Сначала убедимся, что файл архивной копии с именем newbackup.tar.gz присутствует в локальном каталоге бекапов на нашей машине:

$ ls mybackups

$ ls mybackups

Выход: файлы newbackup.tar.gz . Итак, файл на месте.

Теперь загрузим наш tar-файл на удаленный сервер с помощью следующей команды:

$ rsync --progress --remove-source-files -vhre ssh /root/mybackups/newbackup.tar.gzalexandr75001@176.9.1*.***:резервные копии/

Здесь опция --progress обеспечивает отображение процесса синхронизации; --remove-source-files –обеспечивает удаление исходного файла из источника; ssh –вызывает службу SSH для использования в качестве удаленной оболочки; резервные копии – каталог назначения на сервере, который будет автоматически создан в случае его отсутствия.

Результат выполнения команды приведен ниже.

sending incremental file list

Выход:

sending incremental file list
created directory backups
newbackup.tar.gz
        484 100%0.00kB/s    0:00:00 (xfr#1, to-chk=0/1)
sent 578 bytes  received 72 bytes  8.97 bytes/sec
total size is 484  speedup is 0.74

Можно убедиться, что каталог с именем резервные копии был создан на сервере и файл newbackup.tar.gz скопированный в него.

Проверим, был ли удален файл из каталога – источники:

$ ls -a mybackups/ 

$ ls -a mybackups/

Выход: . .. files . Файл отсутствует, а значит, был удалён сразу после окончания процесса копирования на сервер, как и должно быть.

Также можно синхронизировать удаленное устройство с локальным, поменяв местами в команде синхронизации каталоги источника данных и назначения

Оптимизация скорости: --bwlimit, --partial, --checksum

Ограничение для утилиты пропускной способности канала

Нередки случаи ситуации, когда необходимо ограничить пропускную способность канала для Rsync,например,если мы используем всеобщее интернет-подключение или пропускная способность канала имеет ограниченные возможности и нам необходимо его использовать во время работы утилиты. В таком случае на помощь придет параметр --bwlimit.Он позволяет указать максимальную скорость передачи данных через сокет, выраженную в единицах в секунду. С целью обеспечения обратной совместимости ограничение скорости будет автоматически округляться до ближайшего килобайта, и поэтому скорость не может быть меньше значения в 1024 Б/с.

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

$ rsync --progress --remove-source-files --bwlimit=30 -vhre ssh /root/mybackups/newbackup.tar.gz alexandr75001@176.9.1*.***:backups/

$ rsync --progress --remove-source-files --bwlimit=30 -vhre ssh /root/mybackups/newbackup.tar.gz alexandr75001@176.9.1*.***:backups/

Выход:

sending incremental file list
newbackup.tar.gz
        484 100%0.00kB/s    0:00:00 (xfr#1, to-chk=0/1)
sent 94 bytes  received 48 bytes  4.24 bytes/sec
total size is 484  speedup is 3.41 

Можно убедиться, что скорость передачи значительно снизилась по сравнению с использованием команды без указанной опции (4.24 против 8.97 bytes/sec).

Сохранение частично передаваемых файлов

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

Сравнение файлов на основе контрольных сумм

Для определения утилитой Rsync необходимости передачи файла стандартный подход предполагает учет времени внесения изменений в файл, а также его размер. И если одноименный файл из каталога назначения имеет одинаковые с источником значения указанных параметров, копирование не произойдет. В большинстве случаев это срабатывает верно, но не у всех. Для этого здесь может помочь применение метода сравнения контрольных сумм файлов источника и назначения. Метод включается с помощью опции --checksum, указанной в команде. Это несколько затормозит процесс копирования, поскольку будет считываться содержимое обоих файлов, но все равно такой подход может оказаться полезным в некоторых случаях.

Автоматизация деплоя на собственном VPS

Если вы планируете построить полноценный CI/CD-процесс из GitLab, обратите внимание на VPS-хостинг FREEhost.UA. У нас доступны готовые шаблоны с предварительно установленным GitLab, которые позволяют развернуть среду разработки и автоматический деплой за несколько минут.

VPS работают на быстрых NVMe-дисках с полным root-доступом и возможностью гибко настроить ресурсы под ваш проект.

Ознакомьтесь с тарифами здесь:https://freehost.com.ua/ukr/vps-hosting/

Подписывайтесь на наш телеграмм-канал https://t.me/freehostua, чтобы быть в курсе новых полезных материалов

Смотрите наш канал Youtube на https://www.youtube.com/freehostua.

Мы в чем ошиблись, или что-то пропустили?

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

Дата: 17.11.2025
Автор: Александр Ровник
Голосование

Авторам статьи важно Ваше мнение. Будем рады его обсудить с Вами:

comments powered by Disqus
navigate
go
exit
Спасибо, что выбираете FREEhost.UA