CD-Setup über Gitlab

Ich habe einmal darüber nachgedacht, die Bereitstellung meines Projekts zu automatisieren. gitlab.com stellt freundlicherweise alle Tools dafür zur Verfügung, und natürlich habe ich mich dafür entschieden, es zu nutzen, indem ich es herausgefunden und ein kleines Bereitstellungsskript geschrieben habe. In diesem Artikel teile ich meine Erfahrungen mit der Community.

TL; DR

  1. VPS einrichten: Root deaktivieren, Passwort anmelden, Dockerd installieren, ufw konfigurieren
  2. Generieren Sie Zertifikate für Server und Client docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Dockerd-Steuerung über TCP-Socket aktivieren: Entfernen Sie die Option -H fd:// aus der Docker-Konfiguration.
  3. Legen Sie Pfade zu Zertifikaten in docker.json fest
  4. Registrieren Sie sich in den Gitlab-Variablen in den CI/CD-Einstellungen mit den Inhalten der Zertifikate. Schreiben Sie ein .gitlab-ci.yml-Skript für die Bereitstellung.

Ich werde alle Beispiele zur Debian-Distribution zeigen.

Ersteinrichtung des VPS

Hier haben Sie zum Beispiel eine Instanz gekauft DO, ist das erste, was Sie tun müssen, Ihren Server vor der aggressiven Außenwelt zu schützen. Ich werde nichts beweisen oder behaupten, ich zeige lediglich das /var/log/messages-Protokoll meines virtuellen Servers:

ScreenshotCD-Setup über Gitlab

Installieren Sie zunächst die UFW-Firewall:

apt-get update && apt-get install ufw

Aktivieren Sie die Standardrichtlinie: Alle eingehenden Verbindungen blockieren, alle ausgehenden Verbindungen zulassen:

ufw default deny incoming
ufw default allow outgoing

Wichtig: Vergessen Sie nicht, die Verbindung über SSH zuzulassen:

ufw allow OpenSSH

Die allgemeine Syntax lautet: Verbindung auf Port zulassen: ufwallow 12345, wobei 12345 die Portnummer oder der Dienstname ist. Verweigern: ufw verweigern 12345

Firewall einschalten:

ufw enable

Wir verlassen die Sitzung und melden uns erneut per ssh an.

Fügen Sie einen Benutzer hinzu, weisen Sie ihm ein Passwort zu und fügen Sie ihn der Sudo-Gruppe hinzu.

apt-get install sudo
adduser scoty
usermod -aG sudo scoty

Als nächstes sollten Sie laut Plan die Passwort-Anmeldung deaktivieren. Kopieren Sie dazu Ihren SSH-Schlüssel auf den Server:

ssh-copy-id [email protected]

Die IP des Servers muss Ihnen gehören. Versuchen Sie nun, sich unter dem zuvor erstellten Benutzer anzumelden. Sie müssen kein Passwort mehr eingeben. Als nächstes ändern Sie in den Konfigurationseinstellungen Folgendes:

sudo nano /etc/ssh/sshd_config

Passwort-Login deaktivieren:

PasswordAuthentication no

Starten Sie den SSHD-Daemon neu:

sudo systemctl reload sshd

Wenn Sie oder eine andere Person nun versuchen, sich als Root anzumelden, schlägt dies fehl.

Als nächstes installieren wir Docker. Ich werde den Vorgang hier nicht beschreiben, da bereits alles geändert werden kann. Folgen Sie dem Link zur offiziellen Website und führen Sie die Schritte zur Installation von Docker auf Ihrer virtuellen Maschine durch: https://docs.docker.com/install/linux/docker-ce/debian/

Zertifikatserstellung

Zur Fernsteuerung des Docker-Daemons ist eine verschlüsselte TLS-Verbindung erforderlich. Dazu benötigen Sie ein Zertifikat und einen Schlüssel, die Sie generieren und auf Ihren Remote-Rechner übertragen müssen. Befolgen Sie die Schritte in den Anweisungen auf der offiziellen Docker-Website: https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Alle generierten *.pem-Dateien für den Server, nämlich ca.pem, server.pem, key.pem, sollten im Verzeichnis /etc/docker auf dem Server abgelegt werden.

Docker-Setup

Entfernen Sie im Docker-Daemon-Startskript die Option -H df://. Diese Option gibt an, auf welchem ​​Host der Docker-Daemon gesteuert werden kann.

# At /lib/systemd/system/docker.service
[Service]
Type=notify
ExecStart=/usr/bin/dockerd

Erstellen Sie als Nächstes eine Einstellungsdatei, falls diese noch nicht vorhanden ist, und legen Sie die Optionen fest:

/etc/docker/docker.json

{
  "hosts": [
    "unix:///var/run/docker.sock",
    "tcp://0.0.0.0:2376"
  ],
  "labels": [
    "is-our-remote-engine=true"
  ],
  "tls": true,
  "tlscacert": "/etc/docker/ca.pem",
  "tlscert": "/etc/docker/server.pem",
  "tlskey": "/etc/docker/key.pem",
  "tlsverify": true
}

Verbindungen auf Port 2376 zulassen:

sudo ufw allow 2376

Starten Sie Docker mit neuen Einstellungen neu:

sudo systemctl daemon-reload && sudo systemctl restart docker

Lass uns das Prüfen:

sudo systemctl status docker

Wenn alles grün ist, gehen wir davon aus, dass wir Docker erfolgreich auf dem Server konfiguriert haben.

Continuous Delivery auf Gitlab einrichten

Damit der Gitalab-Worker Befehle auf einem Remote-Docker-Host ausführen kann, müssen Sie entscheiden, wie und wo Zertifikate und ein Schlüssel für eine verschlüsselte Verbindung zu Docker gespeichert werden. Ich habe dieses Problem gelöst, indem ich einfach in die Variablen in den Gitlbab-Einstellungen geschrieben habe:

SpoilertitelCD-Setup über Gitlab

Geben Sie einfach den Inhalt der Zertifikate und des Schlüssels über cat aus: cat ca.pem. Kopieren und in Variablenwerte einfügen.

Schreiben wir ein Skript für die Bereitstellung über Gitlab. Es wird das Docker-in-Docker-Image (dind) verwendet.

.gitlab-ci.yml

image:
  name: docker/compose:1.23.2
  # перепишем entrypoint , чтобы работало в dind
  entrypoint: ["/bin/sh", "-c"]

variables:
  DOCKER_HOST: tcp://docker:2375/
  DOCKER_DRIVER: overlay2

services:
  - docker:dind

stages:
  - deploy

deploy:
  stage: deploy
  script:
    - bin/deploy.sh # скрипт деплоя тут

Der Inhalt des Bereitstellungsskripts mit Kommentaren:

bin/deploy.sh

#!/usr/bin/env sh
# Падаем сразу, если возникли какие-то ошибки
set -e
# Выводим, то , что делаем
set -v

# 
DOCKER_COMPOSE_FILE=docker-compose.yml
# Куда деплоим
DEPLOY_HOST=185.241.52.28
# Путь для сертификатов клиента, то есть в нашем случае - gitlab-воркера
DOCKER_CERT_PATH=/root/.docker

# проверим, что в контейнере все имеется
docker info
docker-compose version

# создаем путь (сейчас работаем в клиенте - воркере gitlab'а)
mkdir $DOCKER_CERT_PATH
# изымаем содержимое переменных, при этом удаляем лишние символы добавленные при сохранении переменных.
echo "$CA_PEM" | tr -d 'r' > $DOCKER_CERT_PATH/ca.pem
echo "$CERT_PEM" | tr -d 'r' > $DOCKER_CERT_PATH/cert.pem
echo "$KEY_PEM" | tr -d 'r' > $DOCKER_CERT_PATH/key.pem
# на всякий случай даем только читать
chmod 400 $DOCKER_CERT_PATH/ca.pem
chmod 400 $DOCKER_CERT_PATH/cert.pem
chmod 400 $DOCKER_CERT_PATH/key.pem

# далее начинаем уже работать с удаленным docker-демоном. Собственно, сам деплой
export DOCKER_TLS_VERIFY=1
export DOCKER_HOST=tcp://$DEPLOY_HOST:2376

# проверим, что коннектится все успешно
docker-compose 
  -f $DOCKER_COMPOSE_FILE 
  ps

# логинимся в docker-регистри, тут можете указать свой "местный" регистри
docker login -u $DOCKER_USER -p $DOCKER_PASSWORD

docker-compose 
  -f $DOCKER_COMPOSE_FILE 
  pull app
# поднимаем приложение
docker-compose 
  -f $DOCKER_COMPOSE_FILE 
  up -d app

Das Hauptproblem bestand darin, den Inhalt der Zertifikate in normaler Form aus den Gitlab-CI/CD-Variablen „herauszuziehen“. Ich konnte nicht herausfinden, warum die Verbindung zum Remote-Host nicht funktionierte. Ich habe mir das Docker-Protokoll „sudo journalctl -u“ auf dem Host angesehen und festgestellt, dass beim Handshake ein Fehler aufgetreten ist. Ich habe beschlossen, mir anzusehen, was im Allgemeinen in Variablen gespeichert ist. Hier können Sie cat -A $DOCKER_CERT_PATH/key.pem sehen. Der Fehler wurde behoben, indem das Caret-Zeichen tr -d 'r' entfernt wurde.

Darüber hinaus können Sie dem Skript nach eigenem Ermessen Aufgaben nach der Veröffentlichung hinzufügen. Sie können sich die Arbeitsversion in meinem Repository ansehen https://gitlab.com/isqad/gitlab-ci-cd

Source: habr.com

Kommentar hinzufügen