rsync ist ein beliebtes Dienstprogramm zur Dateisynchronisierung, das einen effizienten Algorithmus verwendet, um den Bandbreitenverbrauch zu minimieren. Eine der häufigsten Rollen von rsync ist die Bereitstellung eines Website-Builds auf einem Remote-Produktionsserver. So kombinieren Sie die Vielseitigkeit von rsync mit der Automatisierung, die von GitLab CI-Pipelines bereitgestellt wird.
Pipeline-Executoren
GitLab CI unterstützt mehrere Arten von Pipeline-Ausführern. Diese definieren die Umgebung, in der Ihr Job ausgeführt wird. Die shell
Executor ist der Standard und führt Bare-Metal auf dem Host-Rechner aus. Damit können Ihre Pipelines jeden auf dem Host verfügbaren Befehl ohne weitere Konfiguration verwenden. Da die meisten gängigen Linux-Distributionen mit installiertem rsync ausgeliefert werden, ist dieser Ansatz leicht zu handhaben.
Leider ist die shell
Executor bietet keine starke Isolation und kann die Umgebung Ihres Hosts im Laufe der Zeit verschmutzen. Eine bessere Alternative ist der docker
Executor, der für jeden CI-Job einen neuen Docker-Container hochfährt. Alle Jobs werden in einer sauberen Umgebung ausgeführt, die den Host nicht beeinträchtigen kann.
Der Nachteil hierbei ist, dass Docker-Basisimages im Allgemeinen rsync
nicht enthalten oder ssh
. Sogar offizielle OS-Images wie ubuntu:latest
als minimale Builds ohne diese Befehle versenden. Dies führt zu einem etwas komplizierteren Pipeline-Skript, um die Abhängigkeiten und rsync
hinzuzufügen Ihre Dateien.
So fügen Sie Ihrer Pipeline rsync hinzu. Stellen Sie sicher, dass Sie einen Docker-basierten GitLab Runner zur Verfügung haben, bevor Sie fortfahren. Wir gehen außerdem davon aus, dass Sie ein einsatzbereites GitLab-Projekt haben.
Vorbereitung
Sie benötigen ein verfügbares SSH-Schlüsselpaar, wenn Sie rsync verwenden, um eine Verbindung zu einem entfernten SSH-Host herzustellen. Sie können öffentliche und private Schlüssel generieren, indem Sie ssh-keygen -t rsa
ausführen . Kopieren Sie den öffentlichen Schlüssel auf den Server, mit dem Sie sich verbinden werden.
Kopieren Sie als Nächstes den generierten privaten Schlüssel in Ihre Zwischenablage:
cat ~/.ssh/id_rsa | xclip -selection c
Gehen Sie zu Ihrem GitLab-Projekt und klicken Sie unten im linken Navigationsmenü auf „Einstellungen“. Klicken Sie im Untermenü auf den Punkt „CI/CD“. Scrollen Sie auf der daraufhin angezeigten Seite nach unten zum Abschnitt „Variablen“.
Klicken Sie auf die blaue Schaltfläche „Variable hinzufügen“. Geben Sie Ihrer neuen Variable im Feld „Schlüssel“ einen Namen. Wir verwenden SSH_PRIVATE_KEY
. Fügen Sie Ihren privaten Schlüssel in das Feld „Wert“ ein, einschließlich des vorangestellten ----BEGIN
und nachgestelltem -----END
Zeilen.
Wenn Sie den Schlüssel als CI-Variable hinzufügen, können Sie ihn später in Ihrer Pipeline referenzieren. Es wird dem SSH-Agenten in den Containern hinzugefügt, die Ihre Pipeline erstellt.
Hinzufügen Ihrer Pipeline-Datei
GitLab CI führt Jobs basierend auf dem Inhalt einer .gitlab-ci.yml
aus Datei in Ihrem Repository. GitLab findet diese Datei automatisch und führt die Pipeline aus, die sie definiert, wenn Sie Änderungen an Ihre Branches pushen.
deploy: stage: deploy image: alpine:latest script: - rsync -atv --delete --progress ./ [email protected]:/var/www/html
Diese .gitlab-ci.yml
enthält einen Job, der rsync
verwendet um den Inhalt des Arbeitsverzeichnisses nach /var/www/html
zu synchronisieren auf example.com
Server. Es verwendet den alpine:latest
Docker-Image als Build-Umgebung. Die Pipeline schlägt derzeit fehl, weil rsync
ist nicht im Alpine-Image enthalten.
Installation von SSH und rsync
Alpine ist eine gute Basis für diesen Job, da es sich um ein leichtgewichtiges Image mit wenigen Abhängigkeiten handelt. Dadurch wird die Netzwerknutzung reduziert, während GitLab das Image zu Beginn des Jobs abruft, wodurch Ihre Pipeline beschleunigt wird. Damit rsync funktioniert, fügen Sie dem Image SSH und rsync hinzu, starten Sie dann den SSH-Agenten und registrieren Sie den zuvor generierten privaten Schlüssel.
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 ./ [email protected]:/var/www/html
OpenSSH und rsync werden mit Alpines apk
installiert Paket-Manager. Der SSH-Authentifizierungsagent wird gestartet und Ihr privater Schlüssel wird über ssh-add
hinzugefügt . GitLab fügt automatisch den SSH_PRIVATE_KEY
ein Umgebungsvariable mit dem Wert, den Sie in den Einstellungen Ihres Projekts definiert haben. Wenn Sie auf dem GitLab-Variablenbildschirm einen anderen Schlüssel verwendet haben, stellen Sie sicher, dass Sie Ihre Pipeline entsprechend anpassen.
Hostverifizierung verwalten
SSH fordert Sie interaktiv zur Bestätigung auf, wenn Sie sich zum ersten Mal mit einem neuen Remote-Host verbinden. Dies ist nicht mit der CI-Umgebung kompatibel, in der Sie diese Eingabeaufforderungen nicht sehen oder darauf reagieren können.
Um dies zu beheben, stehen zwei Optionen zur Verfügung:Deaktivieren Sie strenge Hostschlüsselprüfungen oder registrieren Sie Ihren Server im Voraus als „bekannten“ Host.
Fügen Sie für die erste Option die folgende Zeile zum before_script
Ihrer Pipeline hinzu :
- echo "Host *ntStrictHostKeyChecking no" >> ~/.ssh/config
Dies funktioniert zwar, ist aber ein potenzielles Sicherheitsrisiko. Sie werden nicht gewarnt, wenn ein Angreifer die Kontrolle über die Domain oder IP Ihres Servers erlangt. Mit der Überprüfung des Hostschlüssels können Sie überprüfen, ob die Identität der Fernbedienung Ihren Erwartungen entspricht.
Sie können die Remote als bekannten Host nicht interaktiv hinzufügen, indem Sie auf Ihrem eigenen Computer außerhalb Ihrer Pipeline eine Verbindung zu ihr herstellen. Überprüfen Sie Ihre ~/.ssh/known_hosts
Datei und suchen Sie die Zeile mit der IP oder dem Hostnamen der Fernbedienung. Kopieren Sie diese Zeile und verwenden Sie das Verfahren von früher, um eine neue GitLab-CI-Variable hinzuzufügen. Nennen Sie diese Variable SSH_HOST_KEY
.
Aktualisieren Sie jetzt Ihr before_script
Abschnitt mit der folgenden Zeile:
- echo "$SSH_HOST_KEY" > ~/.ssh/known_hosts
Jetzt können Sie sich mit dem Server verbinden, ohne Bestätigungsaufforderungen zu erhalten. Pushen Sie Ihren Code in Ihr GitLab-Repository und beobachten Sie, wie Ihre Pipeline abgeschlossen wird.
Weitere Verbesserungen
Diese Pipeline ist ein einfaches Beispiel für die ersten Schritte mit SSH und rsync in einer Docker-Umgebung. Es gibt Möglichkeiten, das System weiter zu verbessern, indem die Vorbereitungsschritte in eine dedizierte Build-Phase verpackt werden, die ein Docker-Image erstellt, das Sie zwischen Pipelines wiederverwenden können.
Die .gitlab-ci.yml
würde auch von einer stärkeren Verwendung von Variablen profitieren. Abstrahieren des Hostnamens des Remote-Servers (example.com
), Verzeichnis (/var/www/html
) und Benutzer (user
) in GitLab CI-Variablen würde dazu beitragen, die Datei sauber zu halten, verhindern, dass gelegentliche Repository-Browser Umgebungsdetails sehen, und Sie könnten die Konfigurationswerte ändern, ohne Ihre Pipeline-Datei zu bearbeiten.
Zusammenfassung
Die Verwendung von rsync in GitLab CI-Pipelines erfordert ein wenig manuelles Setup, um eine Build-Umgebung mit den benötigten Abhängigkeiten zu bilden. Sie müssen manuell einen privaten SSH-Schlüssel einfügen und den Remote-Server als bekannten Host registrieren.
Obwohl Community-Docker-Images verfügbar sind, die SSH und rsync auf beliebte Basis-Images rollen, geben Ihnen diese letztendlich weniger Kontrolle über Ihren Build. Sie erweitern die Lieferkette Ihrer Pipeline um ein Image, dem Sie nicht unbedingt vertrauen können. Beginnen Sie mit einem Basis-Image des Betriebssystems und fügen Sie hinzu, was Sie brauchen, damit Sie Vertrauen in Ihre Builds haben.