logocloudstic

Resumen

Velero es un servicio de copias de seguridad y recuperación de Kubernetes. Permite crear copias de seguridad de los objetos de Kubernetes y restaurarlos en caso de pérdida de datos. Velero puede ser usado para realizar copias de seguridad periódicas y guardarlas en un sistema de almacenamiento externo. Además, también se puede usar para migrar recursos entre clusters de Kubernetes. En este tutorial se usará MinIO (un sistema de almacenamiento de objetos compatible con Amazon S3) como sistema de almaenamiento de las copias de seguridad.

Objetivos
  • Instalar Velero en un cluster de Kubernetes.

  • Crear y restaurar backups de un namespace de Kubernetes.

  • Crear y restaurar backups de un cluster de Kubernetes.

1. Introducción a Velero

Velero es un servicio de copias de seguridad y recuperación de Kubernetes. Permite crear copias de seguridad de los objetos de Kubernetes y restaurarlos en caso de pérdida de datos. Velero puede ser usado para realizar copias de seguridad de un namespace o de un cluster completo. Puede configurarse para realizar copias de seguridad periódicas y puede ser usado para migrar un cluster de Kubernetes de un proveedor a otro.

Velero ofrece varios proveedores de almacenamiento para guardar las copias de seguridad, como Amazon S3, Azure Blob Storage, Google Cloud Storage, OpenStack Swift, entre otros. En este tutorial veremos cómo configurar Velero para realizar copias de seguridad en MinIO, un sistema de almacenamiento de objetos compatible con Amazon S3.

Velero también permite realizar copias de seguridad de los volúmenes de Kubernetes. Sin embargo, para ello, Velero necesita un plugin de Velero para el sistema de almacenamiento de volúmenes. En este tutorial usaremos el plugin de Velero para OpenStack Cinder, que permite a Velero interactuar con el sistema de almacenamiento de volúmenes de OpenStack. En la documentación oficial de Velero se indica cómo configurar el soporte para snapshots que sigan la especificación CSI.

2. Componentes de Velero

Velero está compuesto por varios componentes:

  • Velero CLI: Herramienta de línea de comandos para administrar e interactuar con Velero. En nuestro caso lo instalaremos en nuestro equipo local.

  • Velero Server: Servidor que ejecuta los procesos de Velero. Se instala en el cluster de Kubernetes.

  • Plugins de Velero: Plugins que permiten a Velero interactuar con los sistemas de almacenamiento. En nuestro caso, usaremos el plugin de Velero para AWS, que permite a Velero interactuar con sistemas de almacenamiento de objetos compatibles con Amazon S3. Otro ejemplo de plugins son los plugins de CSI, que permiten a Velero interactuar con sistemas de almacenamiento de volúmenes como OpenStack Cinder, VMware vSAN, entre otros.

3. Instalación de Velero

En este apartado veremos cómo instalar Velero en un cluster de Kubernetes. Esto implicará instalar el CLI de Velero en nuestro equipo local y el servidor de Velero en el cluster de Kubernetes.

3.1. Instalación del CLI de Velero

El CLI lo descargamos en nuestro equipo local de acuerdo con la documentación oficial. Para ello, ejecutaremos el comando siguiente:

  • En Windows, lo instalaremos con Chocolatey con el comando siguiente:

    choco install velero

  • En Linux, lo instalaremos con el gestor de paquetes de nuestro sistema operativo. En Ubuntu, lo instalaremos con el comando siguiente:

    sudo apt install velero

  • En macOS, lo instalaremos con el comando siguiente:

    brew install velero

3.2. Preparación del cluster de Kubernetes

La instalación de Velero en Kubernetes crea varios objetos de Kubernetes en el namespace velero, como CustomResourceDefinition para extender la API de Kubernetes creando una serie de objetos nuevos relacionados con las copias de seguridad de Velero, como son los de copias de seguridad, copias de seguridad programadas, restores y localizaciones de backups. Además crea los objetos ClusterRole, ServiceAccount, ClusterRoleBinding, Deployment, BackupStorageLocation, VolumeSnapshotLocation necesarios.

Para poder instalar Velero 1.10 en un cluster de Kubernetes y poder hacer los backups en MinIO, el cluster de Kubernetes debe cumplir los siguientes requisitos:

  • Kubernetes 1.16 o superior.

  • Acceso a MiniIO desde el cluster de Kubernetes.

Para instalar Velero en el cluster de Kubernetes, ejecutaremos el comando velero install con los parámetros necesarios indicando que usaremos MiniIO como sistema de almacenamiento de objetos. Necesitaremos crear un archivo de credenciales (p.e. di-minio.credentials) que contenga las credenciales de acceso a MiniIO.

Archivo de credenciales para MiniIO (p.e. di-minio.credentials)
[default]
aws_access_key_id = your-user
aws_secret_access_key = your-password
Note

Partimos de que ya tenemos creado un bucket en MiniIO (p.e. velero-di) para almacenar las copias de seguridad.

Para instalar Velero en el cluster de Kubernetes ejecutaremos el comando siguiente:

velero install \
--kubeconfig cluster-terraform-di.yaml \ (1)
--provider aws \ (2)
--plugins velero/velero-plugin-for-aws:v1.6.0 \ (3)
--bucket velero-di \ (4)
--secret-file ./di-minio.credentials \ (5)
--backup-location-config region=minio,s3ForcePathStyle="true",s3Url=http://<minio-dns-or-ip> \ (6)
--image velero/velero:v1.10.2 (7)
  1. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

  2. Indica el proveedor de almacenamiento de objetos. En este caso, usaremos aws para indicar que usaremos un sistema de almacenamiento de objetos compatible con Amazon S3.

  3. Indica el plugin de Velero para AWS que usaremos para interactuar con el sistema de almacenamiento de objetos en el que almacenaremos los backups.

  4. Indica el nombre del bucket de MinIO donde se guardarán las copias de seguridad.

  5. Indica el archivo que contiene las credenciales para acceder al sistema de almacenamiento de objetos. En este caso, usaremos el archivo di-minio.credentials que contiene las credenciales de acceso a MiniIO.

  6. Indica la configuración del sistema de almacenamiento de objetos. Lo importante aquí es indicar la región y la URL de acceso a MinIO.

  7. Indica la imagen de Velero que usaremos. Este parámetro es conveniente para poder replicar la instalación con la versión concreta.

Note

Los valores de versión de instalación de Velero se pueden obtener de Docker Hub

Tras esto, se instalarán en el cluster de Kubernetes los objetos siguientes:

  • Un namespace llamado velero.

  • Un Deployment llamado velero que ejecuta el servidor de Velero.

  • Un Secret llamado cloud-credentials que contiene las credenciales de acceso al sistema de almacenamiento de objetos.

  • Un BackupStorageLocation llamado default que contiene la configuración del sistema de almacenamiento de objetos.

  • Un VolumeSnapshotLocation llamado default que contiene la configuración del sistema de almacenamiento de volúmenes.

Para comprobar que Velero está instalado correctamente, ejecutaremos el comando siguiente:

$ kubectl --kubeconfig cluster-terraform-di.yaml get all -n velero

NAME                          READY   STATUS    RESTARTS   AGE
pod/velero-6d8f45bfbc-589ft   1/1     Running   0          2m

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/velero   1/1     1            1           2m

NAME                                DESIRED   CURRENT   READY   AGE
replicaset.apps/velero-6d8f45bfbc   1         1         1       2m

4. Operaciones cotidianas

A continuación, veremos una serie de operaciones cotidianas que podemos realizar con Velero. Realizaremos ejemplos de creación de backups sobre un namespace y simularemos la pérdida de un namespace para ver cómo se restaura. Probaremos también a migrar un namespace de un cluster a otro.

4.1. Creación de backups

Para crear un backup de un namespace, ejecutaremos el comando siguiente:

velero backup \
--kubeconfig cluster-terraform-di.yaml \ (1)
create demo-backup-$(date +'%Y%m%d-%H%M') \ (2)
--include-namespaces demo (3)
  1. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

  2. Indica el nombre del backup. En este caso, usaremos la fecha y hora actual.

  3. Indica el namespace que queremos incluir en el backup (p.e. demo).

Para crear un backup del cluster completo (incluyendo todos los namespaces) basta con quitar el parámetro --include-namespaces y el nombre del namespace.

Esta sería la salida del comando anterior:

Backup request "demo-backup-20230420-2248" submitted successfully.

Run `velero backup describe demo-backup-20230420-2248` or `velero backup logs demo-backup-20230420-2248` for more details.
Important

Los nombres de los backups deben ser únicos. Si se intenta crear un backup con un nombre que ya existe, Velero devolverá un error.

Duración de los backups

De forma predeterminada, los backups caducan a los 30 días y se eliminan automáticamente. Para evitar este comportamiento, se puede usar el parámetro --ttl del comando velero backup create. En el valor de este parámetro se puede indicar el número de días que queremos que dure el backup. Por ejemplo, para que el backup dure 365 días, ejecutaríamos el comando siguiente:

velero backup create demo-backup-$(date +'%Y%m%d-%H%M') \
--include-namespaces demo \
--ttl 365d (1)
  1. Indica que el backup caducará a los 365 días.

4.2. Listado de backups

Para listar los backups, ejecutaremos el comando siguiente:

velero backup get \ (1)
--kubeconfig cluster-terraform-di.yaml (2)
  1. Comando de Velero para listar los backups.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

Esta sería la salida del comando anterior:

NAME                        STATUS      ERRORS   WARNINGS   CREATED                          EXPIRES   STORAGE LOCATION   SELECTOR
demo-backup-20230420-2248   Completed   0        0          2023-04-20 22:48:12 +0200 CEST   29d       default            <none>

4.3. Restauración de backups

La restauración de un backup crea un objeto Restore que contiene la información de los objetos que se van a restaurar. Por tanto, la llamada al comando de restauración no consiste en restaurar la copia de seguridad, sino en crear un objeto Restore, que es el que contiene la información de los objetos que se van a restaurar.

Para restaurar un backup, ejecutaremos el comando siguiente. Este comando restaura un backup en otro cluster de Kubernetes. Las credenciales de acceso al cluster de Kubernetes donde se va a realizar la recuperación del backup se indican en el archivo cluster-terraform-di-dev.yaml:

velero restore create \ (1)
--kubeconfig cluster-terraform-di-dev.yaml \  (2)
--from-backup  demo-backup-20230420-2248 \ (3)
  1. Comando de Velero para crear un restore.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

  3. Indica el nombre del backup que queremos restaurar.

Esta sería la salida del comando anterior:

Restore request "demo-backup-20230420-2248-20230420-2248" submitted successfully.

Run `velero restore describe demo-backup-20230420-2248-20230420-2248` or `velero restore logs demo-backup-20230420-2248-20230420-2248` for more details.

Tras esto, podemos comprobar que el namespace demo se ha restaurado en el otro cluster de Kubernetes.

kubectl \
--kubeconfig cluster-terraform-di-dev.yaml \
-n demo \
get all

Esta sería la salida del comando anterior:

NAME                              READY   STATUS    RESTARTS   AGE
pod/tennis-api-68c9c7dddb-682cf   1/1     Running   0          8m6s
pod/tennis-api-68c9c7dddb-p2cp8   1/1     Running   0          8m6s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/tennis-api   2/2     2            2           8m6s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/tennis-api-68c9c7dddb   2         2         2       8m6s

Podemos comprobar que la restaruración del backup ha sido satisfactoria, habiendo creado en este caso el namespace, el replicaset, el deployment y los pods que se encontraban en el backup.

4.4. Listado de restores

Para listar los restores, ejecutaremos el comando siguiente. El comando se tendrá que lanzar en el cluster de Kubernetes donde se ha realizado la restauración del backup.:

velero restore get \ (1)
--kubeconfig cluster-terraform-di-dev.yaml (2)
  1. Comando de Velero para listar los restores.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

Esta sería la salida del comando anterior:

NAME                                         BACKUP                        STATUS      STARTED                          COMPLETED                        ERRORS   WARNINGS   CREATED                          SELECTOR
demo-backup-20230420-2248-20230420230139     demo-backup-20230420-2248     Completed   2023-04-20 23:01:40 +0200 CEST   2023-04-20 23:01:43 +0200 CEST   0        1          2023-04-20 23:01:40 +0200 CEST   <none>

4.5. Listado de plugins

Para listar los plugins, ejecutaremos el comando siguiente:

velero plugin get \ (1)
--kubeconfig cluster-terraform-di.yaml (2)
  1. Comando de Velero para listar los plugins instalados.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

4.6. Programación de backups

Los backups pueden programarse para que se ejecuten de forma periódica. La forma para especificar la frecuencia de ejecución es mediante un cron`. Para programar backups, ejecutaremos el comando siguiente:

velero schedule create demo-backups \ (1)
--kubeconfig cluster-terraform-di.yaml \ (2)
--schedule='*/5 * * * *' \ (3)
--include-namespaces demo (4)
  1. Comando de Velero para crear schedules e indicación del nombre del schedule.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

  3. Indica la frecuencia de ejecución del schedule. En este caso, cada 5 minutos.

  4. Indica el namespace que queremos incluir en el backup (p.e. demo).

Esta sería la salida del comando anterior:

Schedule "demo-backups" created successfully.

A partir de este momento, Velero se encargará de crear backups cada 5 minutos. Los nombres de los backups se generarán de forma automática, añadiendo un sufijo con la fecha y hora de creación del backup (p.e. demo-backups-20230420212556).

Tras unos minutos, podemos comprobar que se han creado los backups programados:

velero backup get \
--kubeconfig cluster-terraform-di.yaml

Esta sería la salida del comando anterior:

NAME                          STATUS      ERRORS   WARNINGS   CREATED                          EXPIRES   STORAGE LOCATION   SELECTOR
demo-backup-20230420-2248     Completed   0        0          2023-04-20 22:48:12 +0200 CEST   29d       default            <none>
demo-backups-20230420212556   Completed   0        0          2023-04-20 23:25:57 +0200 CEST   29d       default            <none> (1)
  1. Backup programado finalizado.

Tip

También se puede usar la sintaxis más legible del parámetro --schedule. Por ejemplo, para indicar que el schedule se ejecute cada 5 minutos, se puede usar la sintaxis --schedule='@every 5m'.

Duración de los backups

Tal y como se indicón en la sección de Creación de backups, de forma predeterminada los backups caducan a los 30 días y se eliminan automáticamente. Para evitar este comportamiento, se puede usar el parámetro --ttl del comando velero backup schedule create. En el valor de este parámetro se puede indicar el número de días que queremos que dure el backup. Por ejemplo, para que el backup dure 365 días, ejecutaríamos el comando siguiente:

velero schedule create demo-backups \
--kubeconfig cluster-terraform-di.yaml \
--schedule='*/5 * * * *' \
--include-namespaces demo \
--ttl 365d (1)
  1. Indica que el backup caducará a los 365 días.

4.7. Listado de schedules

Para listar los schedules, ejecutaremos el comando siguiente:

velero schedule get \ (1)
--kubeconfig cluster-terraform-di.yaml (2)
  1. Comando de Velero para listar los schedules.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

Esta sería la salida del comando anterior:

NAME           STATUS    CREATED                          SCHEDULE      BACKUP TTL   LAST BACKUP   SELECTOR   PAUSED
demo-backups   Enabled   2023-04-20 23:23:26 +0200 CEST   */5 * * * *   0s           22s ago       <none>     false

4.8. Eliminación de un schedule

Para eliminar un schedule y que dejen de hacerse backups programados, ejecutaremos el comando siguiente:

velero schedule delete demo-backups\ (1)
--kubeconfig cluster-terraform-di.yaml (2)
  1. Comando de Velero para eliminar un schedule. Se indica el nombre del schedule.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

La salida del comando anterior será la siguiente:

Are you sure you want to continue (Y/N)? Y
Schedule deleted: demo-backups

4.9. Eliminación de un backup

Para eliminar un backup, ejecutaremos el comando siguiente:

velero backup delete demo-backup-20230420-2248 \ (1)
--kubeconfig cluster-terraform-di.yaml (2)
  1. Comando de Velero para eliminar un backup. Se indica el nombre del backup.

  2. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de Kubernetes.

La salida del comando anterior será la siguiente:

Are you sure you want to continue (Y/N)? Y
Request to delete backup "demo-backup-20230420-2248" submitted successfully.
The backup will be fully deleted after all associated data (disk snapshots, backup files, restores) are removed.

Tras unos instantes, podemos comprobar que el backup ha sido eliminado de la lista de backups de MinIO y de la lista de backups de Velero, quedando sólo en nuestro caso los backups que creó el schedule programado mientras el schedule estaba activo:

NAME                          STATUS      ERRORS   WARNINGS   CREATED                          EXPIRES   STORAGE LOCATION   SELECTOR
demo-backups-20230420213056   Completed   0        0          2023-04-20 23:30:57 +0200 CEST   29d       default            <none>
demo-backups-20230420212556   Completed   0        0          2023-04-20 23:25:57 +0200 CEST   29d       default            <none>

5. Simulación de pérdida de un namespace

Partimos de la siguiente situación:

  • Tenemos un cluster de Kubernetes con un namespace llamado demo.

  • Tenemos un backup del namespace demo en el cluster de Kubernetes.

Para simular la pérdida de un namespace, ejecutaremos los siguientes pasos:

  1. Creamos un backup del namespace.

  2. Eliminamos el namespace del cluster.

  3. Restauramos el backup en el cluster.

El código siguiente muestra cómo ejecutar estos pasos:

# Creamos un backup del namespace
velero backup create demo-backups-$(date +'%Y%m%d-%H%M') \
--kubeconfig cluster-terraform-di.yaml \
--include-namespaces demo

# Eliminamos el namespace del cluster
kubectl delete namespace demo \
--kubeconfig cluster-terraform-di.yaml

# Restauramos el backup en el cluster
velero restore create \
--kubeconfig cluster-terraform-di.yaml \
--from-backup  demo-backups-20230420212556

La salida del comando anterior será la siguiente:

Restore request "demo-backups-20230420212556-20230420235238" submitted successfully.
Run `velero restore describe demo-backups-20230420212556-20230420235238` or `velero restore logs demo-backups-20230420212556-20230420235238` for more details.

Podemos comprobar que el namespace demo ha sido restaurado en el cluster:

kubectl \
--kubeconfig cluster-terraform-di.yaml \
-n demo \
get all

La salida del comando anterior será la siguiente y nos muestra que el namespace demo ha sido restaurado en el cluster:

NAME                              READY   STATUS    RESTARTS   AGE
pod/tennis-api-68c9c7dddb-682cf   1/1     Running   0          4m38s
pod/tennis-api-68c9c7dddb-p2cp8   1/1     Running   0          4m37s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/tennis-api   2/2     2            2           4m37s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/tennis-api-68c9c7dddb   2         2         2       4m37s
Note

Si queremos restaurar un backup en un cluster diferente, deberemos indicar el archivo de credenciales de acceso al cluster de destino en el comando velero restore create.

Por ejemplo, si queremos restaurar el backup demo-backups-20230420212556 en un cluster de destino con credenciales de acceso almacenadas en cluster-terraform-di-dev.yaml, ejecutaríamos el siguiente comando:

velero restore create \
--kubeconfig cluster-terraform-di-dev.yaml \ (1)
--from-backup  demo-backups-20230420212556
  1. Indica el archivo de configuración de Kubernetes que contiene las credenciales de acceso al cluster de destino.

6. Migración de namespaces entre clusters

Para migrar un namespace de un cluster a otro, ejecutaremos los siguientes pasos:

  1. Creamos un backup del namespace en el cluster de origen.

  2. Restauramos el backup en el cluster de destino.

  3. Opcional. Eliminamos el backup del cluster de origen.

El código siguiente muestra cómo ejecutar estos pasos:

# Creamos un backup del namespace en el cluster de origen
velero backup create demo-backup-$(date +'%Y%m%d-%H%M') \
--kubeconfig cluster-terraform-di.yaml \
--include-namespaces demo

# Restauramos el backup en el cluster de destino
velero restore create \
--kubeconfig cluster-terraform-di-dev.yaml \
--from-backup  demo-backups-20230411144511

# Opcional. Eliminamos el backup del cluster de origen
velero backup delete demo-backups-20230411144511 \
--kubeconfig cluster-terraform-di.yaml

7. Desinstalación de Velero

Para desinstalar Velero de un cluster de Kubernetes, ejecutaremos los comandos siguientes:

kubectl --kubeconfig cluster-terraform-di.yaml delete namespace/velero
kubectl --kubeconfig cluster-terraform-di.yaml delete clusterrolebinding/velero
kubectl --kubeconfig cluster-terraform-di.yaml delete crds -l component=velero

8. Conclusiones

Velero es una herramienta muy útil para realizar backups de namespaces y para migrar namespaces entre clusters. En este tutorial hemos visto cómo instalar Velero en un cluster de Kubernetes, cómo realizar backups y restores de namespaces, cómo programar backups y cómo migrar namespaces entre clusters. En próximas versiones de este tutorial, veremos cómo incorporar soporte para backups de volúmenes persistentes OpenStack Cinder.

Referencias