Configurazione CD tramite gitlab

Un giorno mi sono chiesto come automizzare il deployment del mio progetto. gitlab.com offre tutti gli strumenti necessari per farlo, quindi ho deciso di approfittarne, approfondendo e scrivendo un piccolo script di deployment. In questo articolo condivido la mia esperienza con la comunità.

TL;DR

  1. Configurare VPS: disabilitare root, accesso con password, installare dockerd, configurare ufw
  2. Generare certificati per il server e il client docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Abilitare la gestione di dockerd tramite socket tcp: rimuovere l'opzione -H fd:// dal file di configurazione di Docker.
  3. Прописать пути до сертификатов в docker.json
  4. Definire nelle variabili gitlab nelle impostazioni CI/CD il contenuto dei certificati. Scrivere lo script .gitlab-ci.yml per il deployment.

Mostrerò tutti gli esempi su una distribuzione Debian.

Impostazione iniziale di VPS

Avete acquistato un'istanza ad esempio su DO, la prima cosa da fare è proteggere il vostro server dal mondo esterno aggressivo. Non proverò nulla e non affermerò, mostrerò semplicemente il log /var/log/messages del mio server virtuale:

ScreenshotConfigurazione CD tramite gitlab

Prima di tutto, installiamo il firewall ufw:

apt-get update && apt-get install ufw

Attiveremo la politica predefinita: blocchiamo tutte le connessioni in ingresso, consentiamo tutte le connessioni in uscita:

ufw default deny incoming
ufw default allow outgoing

Importante: non dimentichiamo di consentire la connessione via ssh:

ufw allow OpenSSH

La sintassi generale è: Consentire la connessione su una porta: ufw allow 12345, dove 12345 è il numero di porta o il nome del servizio. Negare: ufw deny 12345

Attiviamo il firewall:

ufw enable

Disconnettersi dalla sessione e riconnettersi via ssh.

Aggiungi un utente, assegna una password e aggiungilo al gruppo sudo.

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

Il passo successivo è disattivare l'accesso con password. Copia la tua chiave ssh sul server:

ssh-copy-id root@10.101.10.28

l'ip del server deve essere il tuo. Prova ora a collegarti con l'utente creato in precedenza, non è più necessario inserire la password. Poi, nelle impostazioni di configurazione, cambiamo quanto segue:

sudo nano /etc/ssh/sshd_config

disabilitiamo l'accesso con password:

PasswordAuthentication no

Riavviamo il demone sshd:

sudo systemctl reload sshd

Ora, se tu o qualcun altro provate ad accedere come utente root, non avrete successo.

Successivamente, installiamo dockerd; non descriverò ulteriormente il processo, poiché potrebbe essere già cambiato. Visitate il link al sito ufficiale e seguite le fasi di installazione di Docker sulla vostra macchina virtuale: https://docs.docker.com/install/linux/docker-ce/debian/

Generazione dei certificati

Per gestire il demone Docker da remoto è necessario un collegamento TLS crittografato. A tal fine, è necessario avere un certificato e una chiave che devono essere generati e trasferiti sulla vostra macchina remota. Seguite i passaggi indicati nelle istruzioni sul sito ufficiale di Docker: https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Tutti i file *.pem generati per il server, ovvero ca.pem, server.pem, key.pem, devono essere collocati nella directory /etc/docker sul server.

Configurazione di dockerd

Nello script di avvio del demone Docker, rimuoviamo l'opzione -H df://, questa opzione determina da quale host si può gestire il demone Docker.

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

Dopodiché, occorre creare un file di configurazione, se non è già presente, e specificare le opzioni:

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

Consentiamo le connessioni sulla porta 2376:

sudo ufw allow 2376

Riavviamo dockerd con le nuove impostazioni:

sudo systemctl daemon-reload && sudo systemctl restart docker

Controlliamo:

sudo systemctl status docker

Se tutto è «verde», consideriamo che abbiamo configurato con successo docker sul server.

Configurazione della continuous delivery su GitLab

Affinché il worker di GitLab possa eseguire comandi su un host remoto di Docker, è necessario decidere come e dove memorizzare i certificati e la chiave per la connessione crittografata con dockerd. Ho risolto il problema semplicemente definendo delle variabili nelle impostazioni di GitLab:

Titolo del riquadro collapsibleConfigurazione CD tramite gitlab

Basta visualizzare il contenuto dei certificati e della chiave tramite cat: cat ca.pem. Copiate e incollate i valori nelle variabili.

Scriviamo uno script per il deploy tramite GitLab. Useremo l'immagine docker-in-docker (dind).

.gitlab-ci.yml

image:
  name: docker/compose:1.23.2
  # riscriviamo l'entrypoint per farlo funzionare in 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 # script di deploy qui

Contenuto dello script di deploy con commenti:

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

Il problema principale era "estrarre" dalle variabili gitlab CI/CD il contenuto dei certificati in modo corretto. Non riuscivo a capire perché la connessione con l'host remoto non funzionasse. Ho controllato il registro sull'host usando sudo journalctl -u docker, e lì ho trovato un errore durante il handshake. Ho deciso di dare un'occhiata a cosa fosse effettivamente memorizzato nelle variabili; per farlo, è possibile usare cat -A $DOCKER_CERT_PATH/key.pem. Ho risolto l'errore aggiungendo la rimozione del carattere di ritorno con tr -d 'r'.

Successivamente, nel tuo script puoi aggiungere task post-release a tua discrezione. Puoi consultare la versione funzionante nel mio repository. https://gitlab.com/isqad/gitlab-ci-cd

Fonte: habr.com

Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster