Якось замислився я про автоматизацію розгортання свого проекту. gitlab.com люб'язно надає для цього всі інструменти, і я, звичайно, вирішив скористатися, розібравшись і написавши невеликий сценарій деплою. У статті я ділюся своїм досвідом із спільнотою.
Прописати в змінні gitlab у налаштуваннях CI/CD із вмістом сертифікатів. Написати скрипт .gitlab-ci.yml для деплою.
Всі приклади я показуватиму на дистрибутиві Debian.
Початкове налаштування VPS
Ось ви купили інстанс наприклад на DOперше, що необхідно зробити, це захистити ваш сервер від агресивного зовнішнього світу. Я не буду нічого доводити і стверджувати, просто покажу лог /var/log/messages свого віртуального сервера:
Скріншот
По-перше встановимо фаєрвол ufw:
apt-get update && apt-get install ufw
Включимо політику за замовчуванням: блокуємо всі вхідні з'єднання, дозволяємо всі вихідні з'єднання:
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/
Генерація сертифікатів
Щоб керувати демоном докера, віддалено потрібне шифроване 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://, ця опція відповідає, на якому хості можна управляти демоном докера.
# At /lib/systemd/system/docker.service
[Service]
Type=notify
ExecStart=/usr/bin/dockerd
Далі слід створити файл налаштувань, якщо його ще немає та прописати опції:
Якщо все зелене, то вважаємо, що на сервері ми успішно налаштували docker.
Налаштування continuous deleivery на gitlab
Для того, щоб воркер гіталабу зміг виконувати команди на віддаленому хості докера необхідно визначитися, як і де зберігати сертифікати та ключ для шифрованого з'єднання з dockerd. Я вирішив цю проблему просто прописавши в змінні в налаштуваннях gitlbab:
Заголовок спойлера
Просто виводьте вміст сертифікатів та ключа через cat: cat ca.pem. Копіюєте і вставляєте значення змінних.
Пропишемо сценарій для деплою через гітлаб. Використовуватиме docker-in-docker (dind) образ.
#!/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