Задумался как-то раз я об автоматизации развертывания своего проекта. 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