Automatizar las migraciones de bases de datos en el Cloud: cómo lo estamos abordando en Mercadona IT

Jesús Tapias
MercadonaIT
Published in
5 min readFeb 15, 2024

En el proceso de modernización de aplicaciones que hemos emprendido en Mercadona, decidimos apostar por la arquitectura de microservicios desplegados en Kubernetes.

En una arquitectura de microservicios, la gestión de base de datos se vuelve esencial en aquellos servicios que requieran persistencia y realizar migraciones de manera eficiente, es crucial.

En Mercadona IT estamos estandarizando el proceso de migración de bases de datos, ofreciendo el método y las herramientas necesarias a los equipos de desarrollo para que puedan ejecutar las migraciones.

El método parte de las siguientes premisas:

  • Los ficheros de migración de BBDD se encuentran en el mismo repositorio que alberga el código fuente del microservicio.
Ubicación de los ficheros de migración en el repositorio de código
  • El despliegue del microservicio es el resultado de un flujo de CI/CD, durante el cual se versiona de forma automática, tanto el código fuente, como los outputs del proceso (contenedor y chart de Helm), por lo que, los ficheros de migración se versionan junto al código fuente del microservicio.

El enfoque inicial

Inicialmente usamos una herramienta de migración, Flyway, para que los equipos de desarrollo pudiesen importarla en sus proyectos, de forma que las migraciones de base de datos se ejecutan durante la fase de inicio del servicio.

Este método, aunque es sencillo de configurar, tiene una serie de desventajas al ejecutarse en un entorno de Kubernetes:

  • En despliegues donde se ejecuten más de una réplica del servicio y se arranquen varias de forma concurrente, pueden darse errores en el arranque cuando se van a ejecutar las migraciones, debido a esa concurrencia.
  • En caso de una gran migración puede que el arranque del servicio exceda el tiempo de inicio establecido y sea Kubernetes el que lo reinicie.

Debido a las desventajas que presenta este enfoque, decidimos cambiarlo, y definir un nuevo método que nos permitiese desvincular las migraciones del arranque del servicio. Para ello, barajamos dos posibilidades que nos ofrece el desplegar en un contexto de Kubernetes.

  • Usar un initContainer (contenedores especializados que se ejecutan antes de los contenedores de aplicación en un Pod) que ejecute las migraciones, al inicio del arranque de los pods.
  • Usar un job de Kubernetes que ejecute las migraciones como paso previo al despliegue del servicio.

En ambos casos, usando un contenedor con una imagen de Flyway.

Una de las desventajas del uso de un initContainer es que al ejecutar las migraciones embebidas en el arranque de servicio tiene problemas con la concurrencia. Por lo que nos hemos decidido por la segunda opción: usar un job de Kubernetes.

Cambio de enfoque: Migraciones de bases de datos usando un Job de Kubernetes

Este nuevo enfoque se basa en desplegar un job de Kubernetes que se encargue de ejecutar las migraciones de BBDD.

Hemos creado una Chart de Helm específica con los recursos necesarios para desplegar el job que ha de ejecutar las migraciones.

El job que se despliega, utiliza un contenedor con la imagen oficial de la herramienta de migraciones, seguimos utilizando Flyway, y además, tiene un initContainer que obtiene los ficheros de migración de un tag concreto del propio repositorio de código del microservicio.

apiVersion: batch/v1
kind: Job
metadata:
generateName: flyway-tool-dummy-service
spec:
spec:
initContainers:
- name: init-clone-repo
image: <git_image_name>
imagePullPolicy: Always
command: ['/bin/bash', '-c', '/opt/mdona/configmap/clone.sh']
env:
- name: GITLAB_USERNAME
valueFrom:
secretKeyRef:
...
- name: GITLAB_TOKEN
valueFrom:
secretKeyRef:
...
- name: GITLAB_REPO_URL
value: <repository_url>
- name: GIT_REFERENCE
value: <repository_tag>
- name: FLYWAY_LOCATIONS
value: driven/datasource/sql/migration/versions
- name: APP_MOUNT_PATH
value: /app
volumeMounts:
- mountPath: /app
name: app-volume
- name: configmap-volume
mountPath: /opt/mdona/configmap
containers:
- name: app
image: flyway/flyway:10.1.0
imagePullPolicy: IfNotPresent
command: []
args:
- migrate
env:
- name: FLYWAY_URL
valueFrom:
secretKeyRef:
...
- name: FLYWAY_USER
valueFrom:
secretKeyRef:
...
- name: FLYWAY_PASSWORD
valueFrom:
secretKeyRef:
...
- name: FLYWAY_LOCATIONS
value: driven/datasource/sql/migration/versions
workingDir: /app
volumeMounts:
- name: app-volume
mountPath: /app
volumes:
- name: app-volume
emptyDir:
sizeLimit: 100Mi

La chart para ejecutar las migraciones se configura de forma muy sencilla desde la propia configuración de Helm del microservicio:

database:
enabled: true
name: <database_name>
migrations:
enabled: true
migrationFilesPath: driven/datasource/sql/migration/versions

Por último, para tener un mayor control del proceso, integramos la ejecución del job de migración en el flujo de CD.

En Mercadona IT, usamos Spinnaker como herramienta de despliegues multi-cloud.

Spinnaker is an open-source, multi-cloud continuous delivery platform that helps you release software changes with high velocity and confidence.

— Spinnaker — Concepts

Añadiendo los steps necesarios para que se despliegue y ejecute el job de migración de BBDD a las pipelines de despliegue de Spinnaker:

  • Orquestamos el proceso para que se ejecute como paso previo al despliegue del microservicio.
Pipeline de Spinnaker para despliegue de microservicio
  • Los equipos de desarrollo pueden visualizar los logs de la ejecución desde la propia UI de Spinnaker.
Log de ejecución de la migración en Spinnaker
  • Podemos realizar roll-backs automáticos en caso de que el despliegue del microservicio de error.

Conclusiones

Ejecutando las migraciones de base de datos con un job de Kubernetes, integrado en la pipeline de CD logramos:

  • Abstraer las migraciones de base de datos del lenguaje de programación en el que esta implementado el microservicio.
  • Evitar problemas que pueden surgir cuando ejecutamos la migración en el arranque del servicio, como los provocados por la concurrencia o migraciones grandes.
  • Tener mayor control del proceso.

Si tienes experiencia en Kubernetes y arquitectura de microservicios, no dudes en echar un ojo a las ofertas que tenemos activas en @MercadonaIT.

--

--