Backups de GitLab en un NAS QNAP

Hace tiempo que tengo un GitLab en casa donde guardo mis proyectos personales funcionando sobre una máquina virtual en un microserver HP con ESXi.

El caso es que actualizando el ESXi he visto que uno de los discos del RAID 10 del server está en rebuilding desde hace más de un día y me he decidido a configurar de una vez los backups del GitLab, más que nada por lo que pueda pasar..

Como mi GitLab no tiene mucho movimiento y no me apetece pagar por tener un montón de datos repetidos en la nube, buscando alternativas he visto que QNAP tiene la opción de instalar un ‘Object Storage Server’: Hosting S3 and OpenStack-compatible object storage services in QTS, y como además poseo un NAS QNAP pues perfecto.

El guardar los backups únicamente en un NAS que se encuentra al lado del servidor no es muy resiliente que digamos, pero para mi requisito de evitar un fallo de hardware es más que suficiente. Además es tinfoil friendly, y siempre puedo subir manualmente una copia encriptada a Glacier.

Configuración del NAS QNAP

Para habilitar el Object Storage Server en el QNAP (ver link más arriba), tras instalarlo, he creado un Account Storage llamada ‘OSS’, que en realidad no es más que una carpeta compartida (sería el equivalente de una cuenta en AWS o un tenant en OS). Y después he creado un Container dentro del Account Storage llamado ‘gitlab-backups’. El container sería el equivalente a un bucket de S3.

Para poder acceder a ese ‘bucket’ necesitamos un par de claves. Para ello, aplicando el principio de mínimo privilegio, he creado un nuevo grupo de usuarios otorgando permiso de lectura/escritura sobre la carpeta compartida ‘OSS’ y denegando el acceso al resto de carpetas compartidas y a los servicios de red y aplicaciones. Tras ello he creado un usuario para gitlab perteneciente al grupo anterior, y en el panel del Object Storage Server he añadido el usuario gitlab como usuario del O.S.S., y se lo he asociado al Account Storage. Por último he generado un par de claves para dicho usuario.

Y ya deberíamos poder conectarnos al Object Storage.

Configuración de GitLab

En mi caso al ser una instalación de GitLab basada en Omnibus la configuración se realiza a través del fichero ‘gitlab.rb’, como podemos ver en la documentación. En mi caso las modificaciones las tengo automatizadas con Ansible, así me evito el entrar al servidor a modificar el fichero de configuración y recargar Gitlab, y además lo tengo bajo control de versiones.

Tras intentar que GitLab usara el protocolo de S3 para conectarse contra en NAS y no conseguirlo, al final lo he configurado con el protocolo de OpenStack Swift y ha funcionado a la primera (al fin y al cabo el Object Storage Server es un Swift). La configuración quedaría tal que así:

###! The duration in seconds to keep backups before they are allowed to be deleted
gitlab_rails['backup_keep_time'] = 1296000

gitlab_rails['backup_upload_connection'] = {
  'provider' => 'OpenStack',
  'openstack_username' => 'OSS:{{ access_key_id }}',
  'openstack_api_key' => '{{ secret_access_key }}',
  'openstack_auth_url' => 'http://url.de.mi.nas:8010/auth/v1.0'
}
gitlab_rails['backup_upload_remote_directory'] = 'gitlab-backups'

Con esto GitLab cada vez que haga un backup subirá el fichero al NAS, pero aún nos falta configurar el CRON del servidor para que los backups se ejecuten de manera periódica.

Como ya he dicho mi GitLab no tiene mucho movimiento y no me interesa almacenar mucha información duplicada. GitLab no soporta backups incrementales pero sí permite seleccionar que queremos excluir de la copia de seguridad por lo he creado dos esquemas de backup: uno diario con la base de datos y los repos, y otro semanal con el servidor completo los lunes.

Las líneas del crontab quedarían tal que así:

0 3 * * * /opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1 DIRECTORY=daily SKIP=uploads,artifacts,lfs,registry,pages
30 3 * * 1 /opt/gitlab/bin/gitlab-rake gitlab:backup:create CRON=1 DIRECTORY=weekly

Con todo esto ya tendríamos nuestro código un poco más protegido contra incidentes, pero si de verdad queremos asegurarnos tendríamos que hacer un plan de backup más serio, como por ejemplo seguir la regla 3-2-1: tener al menos 3 copias en como mínimo 2 medios diferentes, y en al menos 1 lugar alejado del resto de copias.

Por último, si queremos poder restaurar el servidor GitLab no nos tenemos que olvidar de hacer copia de seguridad de la configuración y los secretos (en mi caso los regeneraría con Ansible) ya que no están incluidos en los backups de aplicación.