Definire una logica di backup e ripristino personalizzata


Quando attivi l'agente Backup per GKE nel tuo cluster Google Kubernetes Engine, Backup per GKE fornisce un CustomResourceDefinition che introduce un nuovo tipo di risorsa Kubernetes: il ProtectedApplication.

La composizione di un ProtectedApplication prevede tre attività:

Le risorse ProtectedApplication ti offrono queste funzionalità per personalizzare la logica di backup e ripristino a livello di applicazione:

  • Operazioni di backup e ripristino più granulari. Senza ProtectedApplications, l'ambito dei backup deve essere definito a livello di Namespace (selezionando allNamespaces o selectedNamespaces). Una logica simile si applica al ripristino delle risorse con spazio dei nomi. Creazione in corso... Le risorse ProtectedApplication ti consentono di assegnare un nome a un sottoinsieme di le risorse in un Namespace. Puoi quindi eseguire il backup e il ripristino del sottoinsieme elencando selectedApplications nell'ambito del backup (e analogamente per il restore).

  • Orchestrazione dei dettagli granulari della procedura di backup o ripristino, tra cui:

    • I volumi selezionati vengono ignorati durante il backup.

    • Integrazione della topologia delle applicazioni nel backup e nel ripristino (ad eseguire il backup di un'istanza di un database replicato e utilizzarlo per ripristinare più istanze).

    • Esecuzione di hook definiti dall'utente prima e dopo l'acquisizione di snapshot dei volumi. Può essere usato, ad esempio, per eseguire il flush e la disattivazione di un carico di lavoro prima creare snapshot e riattivarli in seguito.

Puoi creare ProtectedApplication tramite kubectl come le altre risorse Kubernetes. Sono completamente facoltativi. Se le risorse ProtectedApplication non sono presente, Backup per GKE crea backup del volume per tutti i volumi all'interno nell'ambito di un backup e i backup del volume risultanti saranno coerenti con gli arresti anomali. verranno acquisite tutte le scritture sottoposte a svuotamento sul disco in un determinato momento (ovvero, nessuna scrittura parziale). Tuttavia, alcune applicazioni potrebbero conservare in memoria dati che non vengono svuotati sul disco, pertanto la possibilità o meno per un'applicazione di recuperare correttamente da un backup coerente con gli arresti anomali dipende dalla logica dell'applicazione.

Selezione delle risorse

Il primo passaggio per creare la risorsa ProtectedApplication è identificare le altre risorse nella stessa risorsa Namespace che desideri includere dell'applicazione. Si tratta dell'insieme di risorse di cui verrà eseguito il backup o il ripristino se fornisci l'opzione di ambito selectedApplications nella configurazione BackupPlan.

Le risorse sono identificate tramite un'etichetta selettore A questo scopo, devi etichettare tutte le risorse (utilizzando il campo metadata.label). in ogni risorsa) con la stessa etichetta. Tieni presente che si applica anche alle risorse create automaticamente dai controller. Questi le risorse create automaticamente sono etichettate usando il modello corrispondente. Tieni presente che capita di riutilizzare la stessa etichetta che stai già utilizzando associare gli elementi Pods e PersistentVolumeClaims generati al relativo elemento padre risorsa. L'esempio seguente mostra come applicare l'etichetta app: nginx alle altre risorse oltre 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:
      ...

Dopo aver applicato l'etichetta selezionata a tutte le risorse di destinazione (e ai modelli da cui vengono generate risorse aggiuntive), puoi fare riferimento a queste risorse da un ProtectedApplication. Ad esempio:

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1
metadata:
  name: nginx
  namespace: webserver
spec:
  resourceSelection:
    type: Selector
    selector:
      matchLabels:
        app: nginx
  ...

Definisci le regole di orchestrazione

Una volta identificate tutte le risorse nel tuo ProtectedApplication, puoi scegliere di definire regole di orchestrazione dettagliate per un sottoinsieme di questi Google Cloud. Queste regole possono essere applicate solo a due tipi di risorse: Deployment e gli StatefulSets e sono a cui viene fatto riferimento nella sezione components di ProtectedApplication.

Panoramica dei componenti

La configurazione di un componente prevede quanto segue:

  • Selezionare una strategia di base per il funzionamento del backup e del ripristino per questo componente. Sono disponibili tre strategie:

    • BackupAllRestoreAll: esegue il backup dei volumi associati a tutte le istanze il componente e ripristinarli tutti dai backup.

    • BackupOneRestoreAll: esegui il backup dei volumi da una sola istanza del componente e utilizza questi backup per ripristinare tutte le istanze.

    • DumpAndLoad: esporta i dati dall'applicazione in un singolo volume al momento del backup e importali nell'applicazione al momento del ripristino.

  • Definizione di hook di esecuzione da eseguire durante il backup (e possibilmente il recupero, a seconda della strategia). Un hook è un comando che viene eseguito in contenuti specifici.

  • Selezionare un sottoinsieme di volumi di cui eseguire il backup.

Hook di esecuzione

Un hook è un comando shell che Backup per GKE esegue in un container fase specifica del processo di backup o ripristino.

Esistono quattro tipi diversi di hook:

  • pre hooks: questi comandi vengono eseguiti subito prima del backup dei volumi e in genere dovrebbero eseguire il flush di tutti i dati in memoria su disco quindi chiudere l'applicazione in modo che non vengano scritture nuove su disco. Questi hook vengono utilizzati in BackupAllRestoreAll e BackupOneRestoreAll.

  • post hooks: questi comandi vengono eseguiti durante il processo di backup del volume subito dopo il passaggio SNAPSHOTTING (prima del passaggio UPLOADING). In genere, il passaggio SNAPSHOTTING richiede solo pochi secondi. Di solito ci si aspetta che questi utenti non attivino l'applicazione (ad es. consentono la normale elaborazione e le scritture su disco per procedere). Questi hook vengono utilizzati nelle strategie BackupAllRestoreAll, BackupOneRestoreAll e DumpAndLoad.

  • dump hooks: questi comandi vengono eseguiti prima del backup del volume su la strategia DumpAndLoad e generalmente si prevede che esporti i dati dall'applicazione al volume di backup designato.

  • load hooks: questi comandi vengono eseguiti al momento del ripristino dopo il ripristino del volume di backup nei casi di strategia DumpAndLoad. In genere, devono importare i dati dal volume di backup nell'applicazione.

Puoi fornire più di un hook per ogni tipo e Backup per GKE li executerà nell'ordine in cui li definisci.

Devi definire gli hook come parte della sezione dei componenti della Specifica ProtectedApplication. Tutte le definizioni degli hook hanno lo stesso campi disponibili:

  • name: un nome assegnato all'hook.

  • container: nome (facoltativo) del container in cui eseguire il comando. Se non fornisci il contenitore, Backup per GKE eseguirà l'hook nel primo contenitore definito per i Pod di destinazione.

  • command: questo è il comando effettivo inviato al container, creato come un array di parole. La prima parola dell'array è il percorso e le parole successive sono gli argomenti da passare al comando.

  • timeoutSeconds - (facoltativo) tempo prima dell'interruzione dell'esecuzione dell'hook. Se non specifichi questo valore, il valore predefinito sarà 30 secondi.

  • onError - (facoltativo) comportamento adottato in caso di errore dell'hook. Può essere impostato su Ignore o Fail (valore predefinito). Se la imposti su Fail, quando un hook non riesce, il backup del volume non andrà a buon fine. Se imposti a Ignore, gli errori di questo hook vengono ignorati.

Prima di applicare gli hook ProtectedApplication alla tua applicazione, devi testare il comando utilizzando kubectl exec per assicurarti che si comportino come previsto:

kubectl exec POD_NAME -- COMMAND

Sostituisci quanto segue:

  • POD_NAME: il nome del pod che contiene la risorsa ProtectedApplication.
  • COMMAND: l'array contenente il comando da eseguire nel container, ad esempio /sbin/fsfreeze, -f, /var/log/nginx.

Selezionare un sottoinsieme di volumi di cui eseguire il backup

A volte, le applicazioni scrivono in volumi che non è interessante ripristinare (ad esempio, determinati volumi di log o di scratchpad). Puoi eliminare il backup di questi volumi utilizzando un selettore di volume.

Per utilizzare questa funzionalità, devi prima applicare un'etichetta comune ai volumi che vuoi eseguire il backup e lasciare disattivata questa etichetta per i volumi che non vuoi sottoposti a backup. Poi includi una clausola volumeSelector nella definizione del componente come segue:

spec:
  ...
  components:
  ...
    strategy:
      ...
      volumeSelector:
        matchLabels:
          label_name: label_value

Se fornisci un volumeSelector per un componente, verrà eseguito il backup e il ripristino solo dei volumi che hanno l'etichetta specificata. Al momento del ripristino, per tutti gli altri volumi verrà eseguito il provisioning come vuoti anziché ripristinarli da un backup del volume.

Strategia: BackupAllRestoreAll

Questa è la strategia più semplice e esegue il backup di tutti i volumi del componente al momento del backup e li ripristina tutti dai backup dei volumi al momento del ripristino. È la scelta migliore quando l'applicazione non ha alcuna replica tra Pods.

Questa strategia supporta i seguenti parametri:

  • backupPreHooks: (facoltativo) un elenco ordinato di hook che sono appena prima del backup dei volumi. Questi comandi vengono eseguiti tutti gli elementi Pods nel componente.

  • backupPostHooks - (facoltativo) un elenco ordinato di hook che vengono eseguiti dopo che i backup dei volumi hanno raggiunto la fase di CARICAMENTO. Questi comandi sono eseguita su tutti gli elementi Pods del componente.

  • volumeSelector - (Facoltativo) logica per l'associazione di un sottoinsieme di volumi da eseguire il backup.

Questo esempio crea una risorsa ProtectedApplication che mette in stato di riposo il sistema di file prima di eseguire il backup del volume dei log e lo riattiva dopo il backup:

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"]
    strategy:
      type: BackupAllRestoreAll
      backupAllRestoreAll:
        backupPreHooks:
        - name: fsfreeze
          container: nginx
          command: [ /sbin/fsfreeze, -f, /var/log/nginx ]
        backupPostHooks:
        - name: fsunfreeze
          container: nginx
          command: [ /sbin/fsfreeze, -u, /var/log/nginx ]

Strategia: BackupOneAndRipristinaAll

Questa strategia esegue il backup di una copia di un pod selezionato. Questa singola copia è la fonte per il ripristino di tutti i pod durante un ripristino. Questo metodo può contribuire a ridurre i costi di archiviazione e il tempo di backup. Questa strategia funziona in una configurazione ad alta disponibilità quando viene eseguito il deployment di un componente con un PersistentVolumeClaim principale e più PersistentVolumeClaims secondario.

Questa strategia supporta i seguenti parametri:

  • backupTargetName - (obbligatorio) specifica il deployment o lo StatefulSet da utilizzare per eseguire il backup dei dati. Il pod migliore di cui eseguire il backup viene selezionato automaticamente. In una configurazione ad alta disponibilità, ti consigliamo di impostarlo su una delle repliche dell'applicazione.

  • backupPreHooks: (facoltativo) un elenco ordinato di hook che sono appena prima del backup dei volumi. Questi comandi vengono eseguiti sul backup selezionato: Pod.

  • backupPostHooks - (facoltativo) un elenco ordinato di hook che vengono eseguiti dopo che i backup dei volumi hanno raggiunto la fase di CARICAMENTO. Questi comandi vengono eseguiti sul backup selezionato: Pod.

  • volumeSelector - (Facoltativo) logica per l'associazione di un sottoinsieme di volumi da eseguire il backup.

Se un componente è configurato con più oggetti Deployment o StatefulSet, devono avere la stessa struttura PersistentVolume, ovvero seguire queste regole:

  • Il numero di PersistentVolumeClaims utilizzato da tutti i deployment o gli StatefulSet deve essere lo stesso.
  • Lo scopo di PersistentVolumeClaims nello stesso indice deve essere lo stesso. Per gli oggetti StatefulSet, è definito in volumeClaimTemplate. Per i deployment, l'indice è definito in Volumes e tutti i volumi non persistenti vengono ignorati.
  • Se il componente dell'applicazione è costituito da deployment, ogni deployment deve avere esattamente una replica.

Tenendo conto di queste considerazioni, è possibile selezionare più set di volumi per il backup, ma verrà selezionato un solo volume per ogni set di volumi.

Questo esempio, che presuppone un'architettura di un StatefulSet principale e un StatefulSet secondario, mostra un backup dei volumi di un pod nel StatefulSet secondario e un successivo ripristino in tutti gli altri volumi:

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: [...]

Strategia: DumpAndLoad

Questa strategia utilizza un volume dedicato per i processi di backup e ripristino e richiede un PersistentVolumeClaim dedicato collegato a un componente che archivia eseguire il dump dei dati.

Questa strategia supporta i seguenti parametri:

  • dumpTarget - (obbligatorio) specifica il Deployment o il StatefulSet da utilizzare per eseguire il backup dei dati. Il pod migliore di cui eseguire il backup viene selezionato automaticamente. In una configurazione ad alta disponibilità, ti consigliamo di impostare questo valore su una delle repliche dell'applicazione.

  • loadTarget - (obbligatorio) specifica quale Deployment o StatefulSet deve essere utilizzato per caricare i dati. Il pod migliore per il backup viene selezionato automaticamente. Il target di carico non ha in modo che sia uguale al target di dump.

  • dumpHooks - (obbligatorio) un elenco ordinato di hook che vengono eseguiti per compilare il volume di backup dedicato. Questi comandi vengono eseguiti solo sul dump selezionato Pod.

  • backupPostHooks - (facoltativo) un elenco ordinato di hook che vengono eseguiti dopo che i backup dei volumi hanno raggiunto la fase di CARICAMENTO. Questi comandi vengono eseguiti solo sul dump selezionato Pod.

  • loadHooks: (obbligatorio) un elenco ordinato di ganci che vengono eseguiti per caricare i dati dal volume ripristinato dopo . Questi comandi vengono eseguiti solo sul caricamento selezionato Pod.

  • volumeSelector: (obbligatoria) logica per associare un singolo volume al backup e ripristinare (il volume "dump"). Anche se deve corrispondere a un solo volume, lo configuri come il sottoinsieme di volumi di backup utilizzato da altre strategie.

Se l'applicazione consiste di deployment, ogni deployment deve avere esattamente una replica.

Questo esempio, presupponendo un'architettura di uno StatefulSet primario e uno StatefulSet secondario con PersistentVolumeClaims dedicato per gli StatefulSet primari e secondari mostra una strategia 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

Controllare se un ProtectedApplication è pronto per il backup

Per verificare se un file ProtectedApplication è pronto per un backup, puoi eseguire il seguente comando:

kubectl describe protectedapplication APPLICATION_NAME

Sostituisci APPLICATION_NAME con il nome della tua applicazione.

Se è tutto pronto, nella descrizione dell'applicazione lo stato Ready to backup sarà true, come in questo esempio:

% 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>

Passaggi successivi