Cuando habilitas el agente de Backup for GKE en tu clúster de Google Kubernetes Engine, Backup for GKE proporciona un CustomResourceDefinition
que introduce un nuevo tipo de recurso de Kubernetes: el ProtectedApplication
.
Para escribir un ProtectedApplication
, se deben realizar tres actividades:
Seleccionar el conjunto de recursos que quieras incluir en la copia de seguridad y la restauración de la aplicación.
Definir reglas de orquestación detalladas para un subconjunto de esos recursos.
Validando el
ProtectedApplication
para comprobar si está preparado para la copia de seguridad.
Los recursos de ProtectedApplication
te ofrecen estas funciones cuando personalizas la lógica de copia de seguridad y restauración a nivel de aplicación:
Operaciones de copia de seguridad y restauración más precisas. Sin
ProtectedApplications
, el ámbito de tus copias de seguridad debe definirse a nivel deNamespace
(seleccionando allNamespaces o selectedNamespaces). Se aplica una lógica similar a la restauración de recursos con espacio de nombres. Crear recursosProtectedApplication
te permite asignar un nombre a un subconjunto de los recursos de unNamespace
. Después, puedes crear una copia de seguridad y restaurar ese subconjunto incluyendo selectedApplications en el ámbito de la copia de seguridad (y, de forma similar, para restaurar).Orquestar los detalles de la copia de seguridad o del proceso de restauración, como:
Se omiten los volúmenes seleccionados durante la copia de seguridad.
Incorporar la topología de las aplicaciones a las copias de seguridad y la restauración (por ejemplo, crear una copia de seguridad de una sola instancia de una base de datos replicada y usarla para restaurar varias instancias).
Ejecutar enlaces definidos por el usuario antes y después de crear instantáneas de los volúmenes. Por ejemplo, se pueden usar para vaciar y silenciar una carga de trabajo antes de crear una instantánea y, después, reactivarla.
Puedes crear ProtectedApplication
con kubectl
, como otros recursos de Kubernetes.
Son completamente opcionales. Si no hay recursos de ProtectedApplication
, Backup for GKE crea copias de seguridad de volumen de todos los volúmenes incluidos en el ámbito de una copia de seguridad. Las copias de seguridad de volumen resultantes serán coherentes con los fallos: se capturarán todas las escrituras volcadas en el disco en un momento concreto (es decir, no habrá escrituras parciales). Sin embargo, es posible que algunas aplicaciones mantengan datos en la memoria que no se escriben en el disco, por lo que el hecho de que una aplicación pueda recuperarse correctamente de una copia de seguridad coherente en caso de fallo depende de la lógica de la aplicación.
Seleccionar recursos
El primer paso para crear el recurso ProtectedApplication
es identificar los demás recursos del mismo Namespace
que quieras incluir en la aplicación. Se trata del conjunto de recursos de los que se creará una copia de seguridad o que se restaurarán si proporcionas la opción de ámbito selectedApplications en tu configuración de BackupPlan
.
Los recursos se identifican mediante un selector de etiquetas.
Para ello, debe etiquetar todos sus recursos (mediante el campo metadata.label
de cada recurso) con la misma etiqueta. Ten en cuenta que esto también se aplica a los recursos que crean automáticamente los controladores. Estos recursos creados automáticamente se etiquetan con la plantilla correspondiente.
Ten en cuenta que es habitual reutilizar la misma etiqueta que ya estás usando para asociar los elementos Pods
y PersistentVolumeClaims
generados con su recurso principal.
Entre las consideraciones de uso se incluyen las siguientes:
- Si quieres proteger los recursos que crean recursos secundarios, tanto los recursos principales (como
StatefulSet
,Deployment
oDaemonSet
) como los secundarios (comoPod
oPersistentVolumeClaim
) deben tener la etiqueta que se usa en el campoSelector
delProtectedApplication
. - Si un operador crea automáticamente algunos de los recursos a los que hace referencia tu
ProtectedApplication
, también debes incluir los recursos personalizados del operador en tu selectorProtectedApplication
. De esta forma, se evitará una condición de carrera en el momento de la restauración que puede producirse cuando el operador intenta crear un recurso mientras se restaura simultáneamente a partir de una copia de seguridad.
En el siguiente ejemplo se muestra cómo puedes aplicar la etiqueta app: nginx
a los demás recursos, además de a Deployment
.
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-vars
namespace: webserver
labels:
app: nginx
data:
...
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: nginx-logs
namespace: webserver
labels:
app: nginx
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 50Mi
storageClassName: standard-rwo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: webserver
labels:
app: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
volumes:
- name: nginx-logs
persistentVolumeClaim:
claimName: nginx-logs
containers:
...
Una vez que hayas aplicado la etiqueta seleccionada a todos los recursos de destino (y a las plantillas a partir de las que se generan recursos adicionales), podrás hacer referencia a esos recursos desde un ProtectedApplication
. Por ejemplo:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: nginx
namespace: webserver
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
...
Definir reglas de orquestación
Una vez que hayas identificado todos los recursos de tu ProtectedApplication
, puedes definir reglas de orquestación detalladas para un subconjunto de estos recursos. Estas reglas solo se pueden aplicar a dos tipos de recursos:
Deployments
y StatefulSets, y se
hace referencia a ellas en la sección components
del ProtectedApplication
.
Descripción general de los componentes
Para configurar un componente, debes hacer lo siguiente:
Seleccionar una estrategia fundamental para determinar cómo funcionarán las copias de seguridad y la restauración de este componente. Hay tres estrategias disponibles:
BackupAllRestoreAll
: crea una copia de seguridad de los volúmenes asociados a todas las instancias del componente y restaura todos los volúmenes a partir de las copias de seguridad.BackupOneRestoreAll
: crea una copia de seguridad de los volúmenes de solo una instancia del componente y usa esas copias para restaurar todas las instancias.DumpAndLoad
: exporta datos de la aplicación a un solo volumen en el momento de la copia de seguridad e importa esos datos a la aplicación en el momento de la restauración.
Definir hooks de ejecución que se ejecuten durante la copia de seguridad (y posiblemente la restauración, según la estrategia). Un hook es un comando que se ejecuta en contenedores específicos.
Seleccionar un subconjunto de volúmenes para crear copias de seguridad.
Hooks de ejecución
Un hook es un comando shell que Copia de seguridad de GKE ejecuta en un contenedor en una fase concreta del proceso de copia de seguridad o restauración.
Hay cuatro tipos de ganchos:
pre hooks
: estos comandos se ejecutan justo antes de crear copias de seguridad de los volúmenes y, por lo general, se espera que vacíen los datos de la memoria en el disco y, a continuación, silencien la aplicación para que no se escriban datos nuevos en el disco. Estos hooks se usan en las estrategiasBackupAllRestoreAll
yBackupOneRestoreAll
.post hooks
: estos comandos se ejecutan durante el proceso de copia de seguridad del volumen justo después del paso de creación de instantáneas (SNAPSHOT) del proceso de copia de seguridad del volumen (antes del paso de subida [UPLOADING]). Por lo general, el paso de creación de la instantánea solo tarda unos segundos. Por lo general, se espera que reactiven la aplicación (es decir, que permitan que se lleven a cabo los procesos normales y las escrituras en disco). Estos ganchos se usan en las estrategiasBackupAllRestoreAll
,BackupOneRestoreAll
yDumpAndLoad
.dump hooks
: estos comandos se ejecutan antes de que se cree una copia de seguridad del volumen en la estrategiaDumpAndLoad
y, por lo general, se espera que exporten datos de la aplicación al volumen de copia de seguridad designado.load hooks
: estos comandos se ejecutan en el momento de la restauración después de que se restaure el volumen de la copia de seguridad en los casos de la estrategiaDumpAndLoad
. Por lo general, se espera que importen los datos del volumen de copia de seguridad a la aplicación.
Puedes proporcionar más de un hook para cada tipo y Backup for GKE los ejecutará en el orden en que los definas.
Los ganchos se definen en la sección de componentes de la especificación ProtectedApplication
. Todas las definiciones de ganchos tienen los mismos campos disponibles:
name
: nombre que asignas al hook.container
- (opcional) nombre del contenedor en el que se va a ejecutar el comando. Si no proporcionas el contenedor, Backup for GKE ejecutará el hook en el primer contenedor definido para losPod
(s) de destino.command
: es el comando real que se envía al contenedor, construido como un array de palabras. La primera palabra de la matriz es la ruta al comando y las palabras posteriores son los argumentos que se deben transmitir al comando.timeoutSeconds
: (opcional) tiempo antes de que se cancele la ejecución del hook. Si no lo indica, el valor predeterminado es de 30 segundos.onError
: (opcional) comportamiento que se adopta cuando falla el hook. Puede serIgnore
oFail
(valor predeterminado). Si le asignas el valorFail
, cuando falle un hook, también fallará la copia de seguridad del volumen. Si lo defines comoIgnore
, se ignorarán los errores de este hook.
Antes de aplicar los hooks de ProtectedApplication
a tu aplicación, debes probar el comando
con kubectl exec
para asegurarte de que los hooks se comportan como esperas:
kubectl exec POD_NAME -- COMMAND
Haz los cambios siguientes:
POD_NAME
: nombre del pod que contiene el recursoProtectedApplication
.COMMAND
: la matriz que contiene el comando que quieres ejecutar en el contenedor.
Seleccionar un subconjunto de volúmenes para crear una copia de seguridad
A veces, las aplicaciones escriben en volúmenes que no interesa restaurar (por ejemplo, determinados volúmenes de registro o de borrador). Puedes suprimir la copia de seguridad de estos volúmenes mediante un selector de volúmenes.
Para usar esta función, primero debes aplicar una etiqueta común a los recursos PersistentVolumeClaim
de los volúmenes de los que quieras crear una copia de seguridad. También debes desactivar esta etiqueta en los recursos PersistentVolumeClaim
de los volúmenes de los que no quieras crear copias de seguridad. A continuación, incluye una cláusula volumeSelector
en la definición del componente de la siguiente manera:
spec:
...
components:
...
strategy:
...
volumeSelector:
matchLabels:
label_name: label_value
Si proporciona un volumeSelector
para un componente, solo se crearán copias de seguridad y se restaurarán los volúmenes cuyos recursos PersistentVolumeClaim
tengan la etiqueta indicada. En el momento de la restauración, los demás volúmenes se aprovisionan como vacíos en lugar de restaurarse a partir de una copia de seguridad de volumen.
Estrategia: BackupAllRestoreAll
Esta es la estrategia más sencilla, ya que crea una copia de seguridad de todos los volúmenes del componente en el momento de la copia de seguridad y los restaura todos a partir de sus copias de seguridad de volumen en el momento de la restauración.
Es la mejor opción cuando tu aplicación no tiene replicación entre Pods
.
Esta estrategia admite los siguientes parámetros:
backupPreHooks
: (opcional) una lista ordenada de hooks que se ejecutan justo antes de crear copias de seguridad de los volúmenes. Estos comandos se ejecutan en todos losPods
del componente.backupPostHooks
: (opcional) una lista ordenada de hooks que se ejecutan después de que las copias de seguridad de los volúmenes hayan alcanzado la fase UPLOADING. Estos comandos se ejecutan en todos losPods
del componente.volumeSelector
: lógica (opcional) para hacer coincidir un subconjunto de volúmenes con la copia de seguridad.
En este ejemplo se crea un recurso ProtectedApplication
que detiene el sistema de archivos antes de crear una copia de seguridad del volumen de los registros y lo reactiva después de crear la copia de seguridad:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: nginx
namespace: sales
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: nginx
components:
- name: nginx-app
resourceKind: Deployment
resourceNames: ["nginx-deployment"]
strategy:
type: BackupAllRestoreAll
backupAllRestoreAll:
backupPreHooks:
- name: freeze
container: nginx
command:
- bash
- "-c"
- |
# Add application logic to flush data to disk before snapshot
# and freeze the application from further changes.
echo "Freezing the application"
# Return 0 on successful freeze of application, and non-zero
# for errors
exit 0
backupPostHooks:
- name: unfreeze
container: nginx
command:
- bash
- "-c"
- |
# Add application logic to unfreeze the application.
echo "Unfreezing the application"
# Return 0 on successful freeze of application, and non-zero
# for errors
exit 0
Estrategia: BackupOneAndRestoreAll
Esta estrategia crea una copia de seguridad de un Pod seleccionado. Esta única copia es la fuente para restaurar todos los pods durante una restauración. Este método puede ayudar a reducir el coste de almacenamiento y el tiempo de creación de copias de seguridad. Esta estrategia funciona en una configuración de alta disponibilidad
cuando un componente se implementa con un elemento primario PersistentVolumeClaim
y varios
secundarios PersistentVolumeClaims
.
Esta estrategia admite los siguientes parámetros:
backupTargetName
(obligatorio): especifica el Deployment o StatefulSet que quieres usar para crear la copia de seguridad de los datos. Se selecciona automáticamente el mejor Pod para hacer la copia de seguridad. En una configuración de alta disponibilidad, te recomendamos que lo definas en una de las réplicas de tu aplicación.backupPreHooks
: (opcional) una lista ordenada de hooks que se ejecutan justo antes de crear copias de seguridad de los volúmenes. Estos comandos solo se ejecutan en la copia de seguridadPod
seleccionada.backupPostHooks
: (opcional) una lista ordenada de hooks que se ejecutan después de que las copias de seguridad de los volúmenes hayan alcanzado la fase UPLOADING. Estos comandos solo se ejecutan en la copia de seguridadPod
seleccionada.volumeSelector
: lógica (opcional) para hacer coincidir un subconjunto de volúmenes con la copia de seguridad.
Si un componente se configura con varias implementaciones o StatefulSets, todos los recursos deben tener la misma estructura PersistentVolume, lo que significa que deben seguir estas reglas:
- El número de
PersistentVolumeClaims
que usan todos los Deployments o StatefulSets debe ser el mismo. - El propósito de
PersistentVolumeClaims
en el mismo índice debe ser el mismo. En el caso de los StatefulSets, el índice se define envolumeClaimTemplate
. En el caso de los despliegues, el índice se define enVolumes
y se omiten los volúmenes no persistentes. - Si el componente de la aplicación consta de implementaciones, cada implementación debe tener exactamente una réplica.
Teniendo en cuenta estas consideraciones, se pueden seleccionar varios conjuntos de volúmenes para la copia de seguridad, pero solo se seleccionará un volumen de cada conjunto.
En este ejemplo, suponiendo una arquitectura de un StatefulSet principal y un StatefulSet secundario, se muestra una copia de seguridad de los volúmenes de un Pod en el StatefulSet secundario y, a continuación, una restauración de todos los demás volúmenes:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: BackupOneRestoreAll
backupOneRestoreAll:
backupTargetName: mariadb-secondary
backupPreHooks:
- name: quiesce
container: mariadb
command: [...]
backupPostHooks:
- name: unquiesce
container: mariadb
command: [...]
Estrategia: DumpAndLoad
Esta estrategia usa un volumen específico para los procesos de copia de seguridad y restauración, y requiere un PersistentVolumeClaim
específico conectado a un componente que almacene datos de volcado.
Esta estrategia admite los siguientes parámetros:
dumpTarget
(obligatorio): especifica el Deployment o StatefulSet que quieres usar para crear una copia de seguridad de los datos. Se selecciona automáticamente el mejor Pod para hacer la copia de seguridad. En una configuración de alta disponibilidad, te recomendamos que asignes a este campo una de las réplicas de tu aplicación.loadTarget
- (obligatorio) especifica qué Deployment o StatefulSet se debe usar para cargar los datos. Se selecciona automáticamente el mejor Pod para hacer la copia de seguridad. El destino de carga no tiene por qué ser el mismo que el destino de volcado.dumpHooks
: (obligatorio) lista ordenada de hooks que se ejecutan para rellenar el volumen de copia de seguridad dedicado. Estos comandos solo se ejecutan en el volcado seleccionadoPod
.backupPostHooks
: (opcional) una lista ordenada de hooks que se ejecutan después de que las copias de seguridad de los volúmenes hayan alcanzado la fase UPLOADING. Estos comandos solo se ejecutan en el volcado seleccionadoPod
.loadHooks
- (obligatorio) una lista ordenada de hooks que se ejecutan para cargar los datos del volumen restaurado después de que se inicie la aplicación. Estos comandos solo se ejecutan en la cargaPod
seleccionada.volumeSelector
: lógica obligatoria para asociar un solo volumen a la copia de seguridad y la restauración (el volumen de "volcado"). Aunque solo debe coincidir con un volumen, se configura de la misma forma que el subconjunto de volúmenes que se va a crear como copia de seguridad que usan otras estrategias.
Si la aplicación consta de implementaciones, cada una de ellas debe tener exactamente una réplica.
En este ejemplo, se presupone una arquitectura de un StatefulSet principal y un StatefulSet secundario
con PersistentVolumeClaims
dedicados tanto al StatefulSet principal como al secundario.
Se muestra una estrategia DumpAndLoad
:
kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
name: mariadb
namespace: mariadb
spec:
resourceSelection:
type: Selector
selector:
matchLabels:
app: mariadb
components:
- name: mariadb-dump
resourceKind: StatefulSet
resourceNames: ["mariadb-primary", "mariadb-secondary"]
strategy:
type: DumpAndLoad
dumpAndLoad:
loadTarget: mariadb-primary
dumpTarget: mariadb-secondary
dumpHooks:
- name: db_dump
container: mariadb
command:
- bash
- "-c"
- |
mysqldump -u root --all-databases > /backup/mysql_backup.dump
loadHooks:
- name: db_load
container: mariadb
command:
- bash
- "-c"
- |
mysql -u root < /backup/mysql_backup.sql
volumeSelector:
matchLabels:
gkebackup.gke.io/backup: dedicated-volume
Comprobar si un ProtectedApplication
está listo para crear una copia de seguridad
Para comprobar si un ProtectedApplication
está listo para una copia de seguridad, ejecuta el siguiente comando:
kubectl describe protectedapplication APPLICATION_NAME
Sustituye APPLICATION_NAME
por el nombre de tu aplicación.
Si está lista, la descripción de la aplicación mostrará el estado Ready to backup
como true
, como en este ejemplo:
% kubectl describe protectedapplication nginx
Name: nginx
Namespace: default
API Version: gkebackup.gke.io/v1
Kind: ProtectedApplication
Metadata:
UID: 90c04a86-9dcd-48f2-abbf-5d84f979b2c2
Spec:
Components:
Name: nginx
Resource Kind: Deployment
Resource Names:
nginx
Strategy:
Backup All Restore All:
Backup Pre Hooks:
Command:
/sbin/fsfreeze
-f
/var/log/nginx
Container: nginx
Name: freeze
Backup Post Hooks:
Command:
/sbin/fsfreeze
-u
/var/log/nginx
Container: nginx
Name: unfreeze
Type: BackupAllRestoreAll
Resource Selection:
Selector:
Match Labels:
app: nginx
Type: Selector
Status:
Ready To Backup: true
Events: <none>