Configuración de CD a través de gitlab

Un día pensé en la automatización del despliegue de mi proyecto. gitlab.com amablemente proporciona todas las herramientas necesarias para ello, así que decidí aprovecharlo, investigando y escribiendo un pequeño guión de despliegue. En este artículo comparto mi experiencia con la comunidad.

TL;DR

  1. Configurar VPS: desactivar root, acceso por contraseña, instalar dockerd, configurar ufw
  2. Generar certificados para el servidor y el cliente docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Activar la gestión de dockerd a través de un socket tcp: eliminar la opción -H fd:// del archivo de configuración de Docker.
  3. Прописать пути до сертификатов в docker.json
  4. Escribir en las variables de gitlab en la configuración de CI/CD el contenido de los certificados. Escribir un script .gitlab-ci.yml para el despliegue.

Todos los ejemplos los mostraré en la distribución Debian.

Configuración inicial de VPS

Así que compraste una instancia, por ejemplo, en DO, lo primero que debes hacer es proteger tu servidor del mundo exterior agresivo. No voy a demostrar ni afirmar nada, solo mostraré el registro /var/log/messages de mi servidor virtual:

Captura de pantallaConfiguración de CD a través de gitlab

Primero, instalamos el cortafuegos ufw:

apt-get update && apt-get install ufw

Activamos la política por defecto: bloqueamos todas las conexiones entrantes, permitimos todas las conexiones salientes:

ufw default deny incoming
ufw default allow outgoing

Importante: no olvidemos permitir la conexión por ssh:

ufw allow OpenSSH

La sintaxis general es la siguiente: Permitir conexión en el puerto: ufw allow 12345, donde 12345 es el número del puerto o el nombre del servicio. Denegar: ufw deny 12345

Activamos el cortafuegos:

ufw enable

Salimos de la sesión y volvemos a iniciar sesión por ssh.

Agrega un usuario, asigna una contraseña y agrégalo al grupo sudo.

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

A continuación, se debe desactivar el acceso por contraseña. Para ello, copia tu clave ssh en el servidor:

ssh-copy-id root@10.101.10.28

la IP del servidor debe ser la tuya. Ahora intenta iniciar sesión con el usuario que creaste anteriormente, ya no necesitas ingresar la contraseña. Luego, en la configuración cambiamos lo siguiente:

sudo nano /etc/ssh/sshd_config

desactivar el acceso por contraseña:

PasswordAuthentication no

Reiniciamos el demonio sshd:

sudo systemctl reload sshd

Ahora, si tú o alguien más intenta ingresar como usuario root, no podrá hacerlo.

A continuación, instalamos dockerd, aquí no describiré el proceso, ya que todo puede haber cambiado, visita el enlace al sitio oficial y sigue los pasos de instalación de docker en tu máquina virtual: https://docs.docker.com/install/linux/docker-ce/debian/

Generación de certificados

Para gestionar el demonio de Docker de forma remota se requiere una conexión TLS cifrada. Para ello, es necesario disponer de un certificado y una clave, que deben ser generados y transferidos a su máquina remota. Siga los pasos establecidos en las instrucciones en el sitio oficial de Docker: https://docs.docker.com/engine/security/https/#create-a-ca-server-and-client-keys-with-openssl Todos los archivos *.pem generados para el servidor, a saber, ca.pem, server.pem, key.pem, deben colocarse en el directorio /etc/docker en el servidor.

Configuración de dockerd

En el script de inicio del demonio de Docker eliminamos la opción -H df://, esta opción define desde qué host se puede administrar el demonio de Docker.

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

A continuación, debemos crear un archivo de configuración, si aún no existe, y especificar las opciones:

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

Permitiremos conexiones por el puerto 2376:

sudo ufw allow 2376

Reiniciaremos dockerd con los nuevos ajustes:

sudo systemctl daemon-reload && sudo systemctl restart docker

Verifiquemos:

sudo systemctl status docker

Si todo está «verde», consideramos que hemos configurado Docker con éxito en el servidor.

Configuración de entrega continua en GitLab

Para que el trabajador de GitLab pueda ejecutar comandos en el host remoto de Docker, es necesario determinar cómo y dónde almacenar los certificados y la clave para la conexión cifrada con dockerd. He resuelto este problema simplemente definiendo las variables en la configuración de GitLab:

Título del spoilerConfiguración de CD a través de gitlab

Simplemente muestre el contenido de los certificados y la clave usando cat: cat ca.pem. Copie y pegue en el valor de las variables.

Escribiremos un script para la implementación a través de GitLab. Se utilizará la imagen docker-in-docker (dind).

.gitlab-ci.yml

image:
  name: docker/compose:1.23.2
  # reescribiremos entrypoint para que funcione en 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 # script de implementación aquí

Contenido del script de implementación con comentarios:

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

El principal problema fue «extraer» del entorno de variables de GitLab CI/CD el contenido de los certificados en un formato adecuado. No podía entender por qué no funcionaba la conexión con el host remoto. En el host revisé el registro usando sudo journalctl -u docker, donde encontré un error durante el apretón de manos. Decidí ver qué se almacenaba realmente en las variables, para lo cual se puede hacer así: cat -A $DOCKER_CERT_PATH/key.pem. Resolví el error eliminando el carácter de retorno de carro con tr -d ‘r’.

A continuación, en el guion se pueden agregar tareas post-lanzamiento a su criterio. Puede consultar la versión de trabajo en mi repositorio. https://gitlab.com/isqad/gitlab-ci-cd

Fuente: habr.com

Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS 🔥 Compra un hosting fiable para sitios web con protección contra DDoS, servidores VPS VDS | ProHoster