Konfiguracja CD przez gitlab

Pewnego dnia pomyślałem o automatyzacji wdrażania mojego projektu. gitlab.com uprzejmie dostarcza do tego wszystkie narzędzia, więc postanowiłem skorzystać, zrozumieć i napisać mały skrypt do wdrożenia. W artykule dzielę się swoim doświadczeniem z społecznością.

TL;DR

  1. Skonfiguruj VPS: wyłącz root, logowanie hasłem, zainstaluj dockerd, skonfiguruj ufw
  2. Wygeneruj certyfikaty dla serwera i klienta docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Włącz zarządzanie dockerd przez gniazdo tcp: usuń opcję -H fd:// z konfiguracji dockera.
  3. Прописать пути до сертификатов в docker.json
  4. Zdefiniuj w zmiennych gitlab w ustawieniach CI/CD zawartość certyfikatów. Napisz skrypt .gitlab-ci.yml do wdrożenia.

Wszystkie przykłady będę pokazywał na dystrybucji Debian.

Początkowa konfiguracja VPS

Oto kupiłeś instancję na przykład na DO, pierwszą rzeczą, jaką musisz zrobić, to zabezpieczyć swój serwer przed agresywnym światem zewnętrznym. Nie będę niczego udowadniał ani twierdził, po prostu pokażę log /var/log/messages swojego wirtualnego serwera:

Zrzut ekranuKonfiguracja CD przez gitlab

Po pierwsze zainstalujemy zaporę ufw:

apt-get update && apt-get install ufw

Włączamy politykę domyślną: blokujemy wszystkie połączenia przychodzące, zezwalamy na wszystkie połączenia wychodzące:

ufw default deny incoming
ufw default allow outgoing

Ważne: nie zapomnij zezwolić na połączenie przez ssh:

ufw allow OpenSSH

Ogólny składnik jest taki: Zezwolić na połączenie przez port: ufw allow 12345, gdzie 12345 to numer portu lub nazwa usługi. Zablokować: ufw deny 12345

Włączamy zaporę:

ufw enable

Wychodzimy z sesji i logujemy się ponownie przez ssh.

Dodaj użytkownika, nadaj mu hasło i dodaj go do grupy sudo.

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

Następnie według planu należy wyłączyć logowanie hasłem. W tym celu skopiuj swój klucz ssh na serwer:

ssh-copy-id root@10.101.10.28

IP serwera powinno być Twoje. Spróbuj teraz zalogować się jako wcześniej utworzony użytkownik, hasło nie jest już potrzebne. Następnie w konfiguracji zmieniamy następujące:

sudo nano /etc/ssh/sshd_config

wyłączamy logowanie hasłem:

PasswordAuthentication no

Restartujemy demon sshd:

sudo systemctl reload sshd

Teraz, jeśli Ty lub ktoś inny spróbuje zalogować się jako użytkownik root, nie będzie możliwe.

Następnie instalujemy dockerd, tego procesu już nie opiszę, ponieważ wszystko mogło się już zmienić, idź do linku na oficjalnej stronie i przejdź przez kroki instalacji docker na swoją wirtualkę: https://docs.docker.com/install/linux/docker-ce/debian/

Generowanie certyfikatów

Aby zarządzać demonem Dockera zdalnie, potrzebne jest zaszyfrowane połączenie TLS. W tym celu niezbędne jest posiadanie certyfikatu i klucza, które należy wygenerować i przenieść na zdalną maszynę. Postępuj zgodnie z krokami opisanymi w instrukcji na oficjalnej stronie Dockera: https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Wszystkie wygenerowane pliki *.pem dla serwera, a dokładniej ca.pem, server.pem, key.pem, należy umieścić w katalogu /etc/docker na serwerze.

Konfiguracja dockerd

W skrypcie uruchomieniowym demona Dockera usuwamy opcję -H df://, ta opcja odpowiada za to, z jakiego hosta można zarządzać demonem Dockera.

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

Następnie należy utworzyć plik konfiguracyjny, jeśli jeszcze nie istnieje i wpisać opcje:

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

Zezwól na połączenia na porcie 2376:

sudo ufw allow 2376

Uruchomimy ponownie dockerd z nowymi ustawieniami:

sudo systemctl daemon-reload && sudo systemctl restart docker

Sprawdźmy:

sudo systemctl status docker

Jeśli wszystko jest „zielone”, uznajemy, że na serwerze pomyślnie skonfigurowaliśmy Dockera.

Konfiguracja continuous delivery w GitLab

Aby worker GitLaba mógł wykonywać polecenia na zdalnym hoście Dockera, należy określić, jak i gdzie przechowywać certyfikaty oraz klucz do szyfrowanego połączenia z dockerd. Rozwiązałem ten problem, wpisując to w zmienne w ustawieniach GitLaba:

Nagłówek spoileraKonfiguracja CD przez gitlab

Po prostu wyświetl zawartość certyfikatów i klucza za pomocą cat: cat ca.pem. Kopiuj i wklej do wartości zmiennych.

Utwórzmy skrypt do wdrożenia przez GitLab. Użyjemy obrazu docker-in-docker (dind).

.gitlab-ci.yml

image:
  name: docker/compose:1.23.2
  # przeredagujemy entrypoint, aby działał w 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 # skrypt wdrożeniowy tutaj

Zawartość skryptu wdrożeniowego z komentarzami:

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

Głównym problemem było „wyciągnięcie” z zmiennych GitLab CI/CD zawartości certyfikatów w normalnej postaci. Nie mogłem zrozumieć, dlaczego połączenie z zdalnym hostem nie działało. Na hoście sprawdziłem dziennik sudo journalctl -u docker, tam błąd przy uścisku dłoni. Postanowiłem zobaczyć, co w ogóle jest przechowywane w zmiennych, w tym celu można zobaczyć tak cat -A $DOCKER_CERT_PATH/key.pem. Błąd został naprawiony przez dodanie usunięcia znaku powrotu tr -d ‘r’.

Można dodać zadania po wydaniu do scenariusza według własnego uznania. Możesz zapoznać się z wersją roboczą w moim repozytorium. https://gitlab.com/isqad/gitlab-ci-cd

Źródło: habr.com

Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS 🔥 Kup solidny hosting stron z ochroną przed DDoS, serwery VPS VDS | ProHoster