• База знань
  • /
  • Блог
  • /
  • 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*.***

Даємо згоду на з’єднання з хостом (yes).

$ 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 із відповідними параметрами. Це дозволить уникнути витрат часових ресурсів для зміни статусу хостів.

Скористаємося вказаною утилітою для додавання запису для визначеного IP:

$ 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 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGizGeeZx6WURNKattRhjSbf0srbHyBDIqaRVPsNkGvxHil1pRG0agV7/qpS8c0et9GGNN/VNZF8TXivF1ntV/4=
176.9.1*.*** ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDEB55myQPm0kDpLG9xjONQdG0Z9lNb8BINlHWp1woy9td/QoVy9ADtYlD1x+OTyvPp7mDefVzc72IKJrAsDnqumE9Dv8Ret/fOxG6DPTgKP2EujAO28hZ5+ZVHFBzyOvrYFQepkBWqsqaC3d+g4ysYRfJJw6yf0dTkRQbDbzSaDXX8LD+YuYL1QmYKv+h4A5zIUNuCaLJcmTh/MaACC6R874HYtKPGFmMeo3AX04XTp7sA+iN1A4OwTMBx6ypSaCpDjCLZcHcOrUh/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-проекту, натиснувши Settings у лівій частині вікна. Далі слід обрати пункт CI/CD та знайти у правій частині вікна розділ Variables (див. скриншот).

Variables

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

Натиснути кнопку Add variable

У полі Key введемо довільне ім’я нової змінної (SSH_PRIVATE_KEY). У поле Value вставимо з буферу обміну скопійований нами закритий ключ. Доцільно зробити змінну прихованою, включивши опцію Mask variable із області Flags у нижній частині вікна. Це зробить її невидимою у журналах завдань. 

Після того, як поля значень будуть заповнені, слід натиснути кнопку Add variable, що ініціює процес створення змінної.

Формування конвеєрного сценарію

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

Наведемо основні записи файлу .gitlab-ci.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

Вихід: files newbackup.tar.gz . Отже, файл на місці.

Тепер завантажимо наш tar-файл на віддалений сервер за допомогою наступної команди:

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

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

Результат виконання команди наведений нижче.

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
Можна переконатися, що каталог із ім’ям backups був створений на сервері та файл 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