Настройка на CD чрез gitlab

Замислих се веднъж как да автоматизирам разгръщането на проекта си. gitlab.com любезно предоставя всички инструменти за това и, разбира се, реших да се възползвам, разбирайки и пишейки малък сценарий за деплой. В статията споделям опита си с общността.

TL;DR

  1. Настройване на VPS: деактивиране на root, вход с парола, инсталиране на dockerd, настройка на ufw.
  2. Генериране на сертификати за сървъра и клиента. docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Включване на управлението на dockerd чрез tcp сокет: премахнете опцията -H fd:// от конфигурацията на Docker.
  3. Прописать пути до сертификатов в docker.json
  4. Въведете в променливите на gitlab в настройките CI/CD съдържанието на сертификатите. Напишете скрипт .gitlab-ci.yml за деплой.

Всички примери ще покажа на дистрибуция Debian.

Начална настройка на VPS.

Вие купихте инстанция например на DO, първото нещо, което трябва да направите, е да защитите сървъра си от агресивния външен свят. Няма да доказвам или твърдя нищо, просто ще покажа лога /var/log/messages на виртуалния си сървър:

СкриншотНастройка на CD чрез gitlab

Първо ще инсталираме защитната стена ufw:

apt-get update && apt-get install ufw

Включваме политиката по подразбиране: блокираме всички входящи връзки, разрешаваме всички изходящи връзки:

ufw default deny incoming
ufw default allow outgoing

Важно: не забравяйте да разрешите SSH връзката:

ufw allow OpenSSH

Общият синтаксис е: Разрешаване на връзка по порт: ufw allow 12345, където 12345 е номерът на порта или името на услугата. Забрана: ufw deny 12345

Включваме защитната стена:

ufw enable

Излизате от сесията и отново се логвате по SSH.

Добавете потребител, назначете му парола и го добавете в групата sudo.

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

Следващата стъпка е да деактивирате входа с парола. За целта копирайте вашия SSH ключ на сървъра:

ssh-copy-id root@10.101.10.28

IP адресът на сървъра трябва да е вашият. Опитайте сега да се логнете с потребителя, създаден по-рано, паролата вече не трябва да се въвежда. След това в настройките на конфигурацията променяме следното:

sudo nano /etc/ssh/sshd_config

деактивираме входа с парола:

PasswordAuthentication no

Перезапускаме демона sshd:

sudo systemctl reload sshd

Сега, ако вие или някой друг опита да влезе с потребителя root, нищо няма да се получи.

Следващата стъпка е да инсталираме dockerd, не ще описвам процеса, тъй като всичко може да е променено, посетете официалния сайт и следвайте стъпките за инсталиране на Docker на вашата виртуалка: https://docs.docker.com/install/linux/docker-ce/debian/

Генерация на сертификати

За да управлявате Docker демона отдалечено, е необходимо криптирано TLS свързване. За това е нужно да имате сертификат и ключ, които трябва да генерирате и прехвърлите на отдалечената машина. Следвайте стъпките, зададени в инструкциите на официалния сайт на Docker: https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Всички генерирани *.pem файлове за сървъра, а именно ca.pem, server.pem, key.pem трябва да бъдат поставени в директорията /etc/docker на сървъра.

Конфигурация на dockerd

В сценария за стартиране на Docker демона премахваме опцията -H df://, тази опция указва от кой хост може да се управлява Docker демона.

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

След това трябва да създадете файл с настройки, ако не съществува, и да запишете опциите:

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

Разрешаваме свързвания на порт 2376:

sudo ufw allow 2376

Перезапускаме dockerd с новите настройки:

sudo systemctl daemon-reload && sudo systemctl restart docker

Проверете:

sudo systemctl status docker

Ако всичко е „зелено“, считаме, че успешно сме конфигурирали docker на сървъра.

Настройка на непрекъснато доставяне (continuous delivery) на GitLab

За да може работният процес на GitLab да изпълнява команди на отдалечен Docker хост, необходимо е да се определим как и къде да се съхраняват сертификатите и ключа за криптирано свързване с dockerd. Реших този проблем, просто ги записа в променливите в настройките на GitLab:

Заглавие на спойлераНастройка на CD чрез gitlab

Просто изведете съдържанието на сертификатите и ключа чрез cat: cat ca.pem. Копирайте и поставете в стойността на променливите.

Ще напишем сценарий за разполагане чрез GitLab. Ще се използва Docker-in-Docker (dind) образ.

.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 # сценарий за разполагане тук

Съдържание на сценария за разполагане с коментари:

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

Основната проблема беше да „извлека“ от променливите на GitLab CI/CD съдържанието на сертификатите в нормален вид. Не можех да разбера защо не работеше свързването с отдалечения хост. На хоста видях логовете с sudo journalctl -u docker, там имаше грешка при ръкостискането. Реших да проверя какво всъщност се пази в променливите, за това може да се види така: cat -A $DOCKER_CERT_PATH/key.pem. Справих се с грешката, като добавих премахване на символа за каретка: tr -d ‘r’.

В сценария можете да добавите пост-релизни задачи по собствено желание. Можете да се запознаете с работната версия в моето хранилище https://gitlab.com/isqad/gitlab-ci-cd

Източник: habr.com

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster