Замислих се веднъж как да автоматизирам разгръщането на проекта си. gitlab.com любезно предоставя всички инструменти за това и, разбира се, реших да се възползвам, разбирайки и пишейки малък сценарий за деплой. В статията споделям опита си с общността.
TL;DR
- Настройване на VPS: деактивиране на root, вход с парола, инсталиране на dockerd, настройка на ufw.
- Генериране на сертификати за сървъра и клиента. Включване на управлението на dockerd чрез tcp сокет: премахнете опцията -H fd:// от конфигурацията на Docker.
- Прописать пути до сертификатов в 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 на вашата виртуалка:
Генерация на сертификати
За да управлявате Docker демона отдалечено, е необходимо криптирано TLS свързване. За това е нужно да имате сертификат и ключ, които трябва да генерирате и прехвърлите на отдалечената машина. Следвайте стъпките, зададени в инструкциите на официалния сайт на Docker: Всички генерирани *.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:
Заглавие на спойлера
Просто изведете съдържанието на сертификатите и ключа чрез 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’.
В сценария можете да добавите пост-релизни задачи по собствено желание. Можете да се запознаете с работната версия в моето хранилище
Източник: habr.com
