CD-Konfiguration über GitLab

Ich dachte eines Tages über die Automatisierung der Bereitstellung meines Projekts nach. gitlab.com bietet dafür alle notwendigen Werkzeuge an, und ich entschied mich natürlich, diese zu nutzen, nachdem ich mich eingearbeitet und ein kleines Bereitstellungsskript geschrieben hatte. In diesem Artikel teile ich meine Erfahrungen mit der Gemeinschaft.

TL;DR

  1. VPS einrichten: root deaktivieren, Passwortanmeldung ausschalten, dockerd installieren, ufw konfigurieren
  2. Zertifikate für den Server und den Client generieren docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Die Verwaltung von dockerd über einen TCP-Socket aktivieren: die Option -H fd:// aus der Docker-Konfiguration entfernen.
  3. Прописать пути до сертификатов в docker.json
  4. Die Variablen in GitLab in den CI/CD-Einstellungen mit dem Inhalt der Zertifikate ausfüllen. Ein Skript .gitlab-ci.yml für die Bereitstellung schreiben.

Alle Beispiele werde ich auf der Debian-Distribution zeigen.

Erstkonfiguration des VPS

Angenommen, Sie haben eine Instanz zum Beispiel auf DO, das Erste, was zu tun ist, ist, Ihren Server vor der aggressiven Außenwelt zu schützen. Ich werde nichts beweisen oder behaupten, sondern einfach das Protokoll /var/log/messages meines virtuellen Servers zeigen:

ScreenshotCD-Konfiguration über GitLab

Zuerst installieren wir die Firewall ufw:

apt-get update && apt-get install ufw

Wir aktivieren die Standardrichtlinie: alle eingehenden Verbindungen blockieren, alle ausgehenden Verbindungen erlauben:

ufw default deny incoming
ufw default allow outgoing

Wichtig: Vergessen Sie nicht, die Verbindung über SSH zu erlauben:

ufw allow OpenSSH

Die allgemeine Syntax ist wie folgt: Verbindung über einen Port erlauben: ufw allow 12345, wobei 12345 die Portnummer oder der Name des Dienstes ist. Verbieten: ufw deny 12345

Wir aktivieren die Firewall:

ufw enable

Wir beenden die Sitzung und melden uns erneut über SSH an.

Fügen Sie einen Benutzer hinzu, weisen Sie ihm ein Passwort zu und fügen Sie ihn zur Gruppe sudo hinzu.

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

Als Nächstes müssen wir die Passwortanmeldung deaktivieren. Kopieren Sie dazu Ihren SSH-Schlüssel auf den Server:

ssh-copy-id root@10.101.10.28

Die IP des Servers sollte Ihre eigene sein. Versuchen Sie nun, sich mit dem zuvor erstellten Benutzer anzumelden; das Passwort ist nicht mehr erforderlich. Anschließend ändern wir in der Konfigurationsdatei Folgendes:

sudo nano /etc/ssh/sshd_config

Deaktivieren Sie die Passwortanmeldung:

PasswordAuthentication no

Den SSH-Dienst sshd neu starten:

sudo systemctl reload sshd

Jetzt, wenn Sie oder jemand anderer versucht, sich über den Benutzer root anzumelden, wird es nicht funktionieren.

Als Nächstes installieren wir dockerd, über diesen Prozess werde ich nichts weiter sagen, da sich alles bereits geändert haben könnte. Gehen Sie zum Link zur offiziellen Website und folgen Sie den Installationsschritten für Docker auf Ihrer virtuellen Maschine: https://docs.docker.com/install/linux/docker-ce/debian/

Zertifikatgenerierung

Um den Docker-Dämon remote zu verwalten, ist eine verschlüsselte TLS-Verbindung erforderlich. Dazu müssen Sie ein Zertifikat und einen Schlüssel haben, die Sie generieren und auf Ihre remote Maschine übertragen müssen. Folgen Sie den Schritten, die in der Anleitung auf der offiziellen Docker-Website angegeben sind: https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Alle generierten *.pem-Dateien für den Server, namentlich ca.pem, server.pem, key.pem, müssen in das Verzeichnis /etc/docker auf dem Server gelegt werden.

Konfiguration des dockerd

Im Startskript des Docker-Dämon entfernen wir die Option -H df://; diese Option gibt an, auf welchem Host der Docker-Dämon verwaltet werden kann.

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

Als Nächstes müssen wir eine Konfigurationsdatei erstellen, falls sie noch nicht existiert, und die Optionen eintragen:

/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
}

Erlauben Sie Verbindungen über Port 2376:

sudo ufw allow 2376

Starten wir dockerd mit den neuen Einstellungen neu:

sudo systemctl daemon-reload && sudo systemctl restart docker

Wir überprüfen:

sudo systemctl status docker

Wenn alles „grün“ ist, können wir annehmen, dass wir Docker erfolgreich auf dem Server konfiguriert haben.

Einrichten von Continuous Delivery auf GitLab

Damit der GitLab-Worker Befehle auf dem Remote-Docker-Host ausführen kann, müssen wir uns entscheiden, wie und wo wir die Zertifikate und den Schlüssel für die verschlüsselte Verbindung zu dockerd speichern. Ich habe dieses Problem einfach gelöst, indem ich Variablen in den GitLab-Einstellungen definiert habe:

Spoiler-ÜberschriftCD-Konfiguration über GitLab

Geben Sie einfach den Inhalt der Zertifikate und des Schlüssels über cat aus: cat ca.pem. Kopieren und fügen Sie in den Wert der Variablen ein.

Lassen Sie uns ein Skript für die Bereitstellung über GitLab schreiben. Verwenden wird das Docker-in-Docker (dind) Image.

.gitlab-ci.yml

image:
  name: docker/compose:1.23.2
  # ändern wir den entrypoint, damit es in dind funktioniert
  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 # Bereitstellungsskript hier

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 war, den Inhalt der Zertifikate aus den GitLab CI/CD-Variablen in normaler Form „herauszuziehen“. Ich konnte nicht verstehen, warum die Verbindung zum Remote-Host nicht funktionierte. Auf dem Host habe ich das Protokoll mit sudo journalctl -u docker angesehen, dort trat ein Fehler beim Handshake auf. Ich beschloss zu prüfen, was überhaupt in den Variablen gespeichert ist, und konnte dies so anzeigen: cat -A $DOCKER_CERT_PATH/key.pem. Ich habe den Fehler behoben, indem ich das Entfernen des Wagenrücklaufs tr -d 'r' hinzugefügt habe.

Im Skript können nach Belieben Post-Release-Tasks hinzugefügt werden. Sie können die Arbeitsversion in meinem Repository einsehen. https://gitlab.com/isqad/gitlab-ci-cd

Quelle: habr.com

60GB SSD 8Gb DDR4