Задумался как-то раз я об автоматизации развертывания своего проекта. gitlab.com любезно предоставляет для этого все инструменты, и я конечно решил воспользоваться, разобравшись и написав небольшой сценарий деплоя. В статье я делюсь своим опытом с сообществом.
TL;DR
- Настроить VPS: отключить root, вход по паролю, поставить dockerd, настроить ufw
- Сгенерировать сертификаты для сервера и клиента Включить управление dockerd через tcp сокет: убрать опцию -H fd:// из конфига докера.
- Прописать пути до сертификатов в docker.json
- Прописать в переменные gitlab в настройках CI/CD с содержимым сертификатов. Написать скрипт .gitlab-ci.yml для деплоя.
Все примеры я буду показывать на дистрибутиве Debian.
Первоначальная настройка VPS
Вот вы купили инстанс например на , первое, что необходимо предпринять, это защитить ваш сервер от агрессивного внешнего мира. Я не буду ничего доказывать и утверждать, просто покажу лог /var/log/messages своего виртуального сервера:
Скриншот
Во-первых установим файервол 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.28ip сервера должен быть указан ваш. Попробуйте теперь залогиниться под созданным ранее пользователем, пароль вводить больше не надо. Далее в настройках конфигурации меняем следующее:
sudo nano /etc/ssh/sshd_configотключаем вход по паролю:
PasswordAuthentication noПерезапускаем демон sshd:
sudo systemctl reload sshdТеперь если вы или кто-то другой попробует войти через пользователя root, у него ничего не получится.
Далее ставим dockerd, тут процесс уже не буду описывать, так как все может быть уже изменено, сходите по ссылке на официальный сайт и пройдите этапы установки docker на вашу виртуалку:
Генерация сертификатов
Чтобы управлять демоном докера удаленно требуется шифрованное TLS соединение. Для этого необходимо иметь сертификат и ключ, которые надо сгенерировать и перенести на удаленную вашу машину. Следуйте шагам, заданным в инструкции на официальном сайте docker: Все сгенерированные *.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Далее следует создать файл настроек, если его еще нет и прописать опции:
/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 deleivery на gitlab
Для того чтобы воркер гиталаба смог выполнять команды на удаленном хосте докера необхоимо определиться, как и где хранить сертификаты и ключ для шифрованного соединения с dockerd. Я решил данную проблему просто прописав в переменные в настройках gitlbab:
Заголовок спойлера
Просто выводите содержимое сертификатов и ключа через cat: cat ca.pem. Копируете и вставляете в значение переменных.
Пропишем сценарий для деплоя через гитлаб. Использовать будет 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’.
Далее в сценарий можно добавить пост-релизные таски на свое усмотрение. Ознакомиться с рабочей версией можете в моем репозитории
Источник: habr.com
