Definisci una logica di backup e ripristino personalizzata


Quando abiliti 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: ProtectedApplication.

La creazione di un ProtectedApplication prevede due attività:

Le risorse ProtectedApplication ti offrono le seguenti funzionalità quando personalizzi 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. La creazione di risorse ProtectedApplication consente di fornire un nome a un sottoinsieme delle risorse in un Namespace. Puoi quindi eseguire il backup e ripristinare quel sottoinsieme elencando selectedApplications nell'ambito del backup (e, analogamente, per il ripristino).

  • Orchestrare dettagli granulari del processo di backup o ripristino, tra cui:

    • I volumi selezionati verranno ignorati durante il backup.

    • Incorporazione della topologia delle applicazioni nel backup e ripristino (ad esempio, eseguendo il backup di un'unica istanza di un database replicato e utilizzandolo per ripristinare più istanze).

    • Esecuzione di hook definiti dall'utente prima e dopo lo snapshot dei volumi. Possono essere utilizzate, ad esempio, per svuotare e disattivare un carico di lavoro prima di eseguire un'istantanea e disattivare il blocco in seguito.

Puoi creare ProtectedApplication tramite kubectl come faresti con le altre risorse Kubernetes. Sono completamente facoltativi. Se non sono presenti risorse ProtectedApplication, Backup per GKE crea backup per tutti i volumi nell'ambito di un backup e i backup dei volumi risultanti saranno coerenti con arresti anomali: verranno acquisite tutte le scritture scaricate sul disco in un determinato momento (ovvero, nessuna scrittura parziale). Tuttavia, alcune applicazioni potrebbero conservare i dati che non vengono svuotati su disco, di conseguenza la possibilità di un'applicazione di recuperare correttamente da un backup coerente con arresto anomalo dipende dalla logica dell'applicazione.

Selezione delle risorse

Il primo passaggio nella creazione della risorsa ProtectedApplication è identificare le altre risorse nella stessa Namespace che vuoi includere come parte dell'applicazione. Questo è l'insieme di risorse di cui verrà eseguito il backup o il ripristino se fornisci l'opzione dell'ambito selectedApplications nella configurazione di BackupPlan.

Le risorse sono identificate utilizzando un selettore di etichette, che richiede l'etichettatura di tutte le risorse (utilizzando il campo metadata.label in ogni risorsa) con la stessa etichetta. Tieni presente che questo vale anche per le risorse create automaticamente dai controller. Queste risorse create automaticamente sono etichettate utilizzando il modello corrispondente. Tieni presente che è pratica comune riutilizzare la stessa etichetta che già utilizzi per associare i campi Pods e PersistentVolumeClaims generati alla risorsa padre. L'esempio seguente mostra come applicare l'etichetta app: nginx ad 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 le risorse aggiuntive), puoi fare riferimento a queste risorse da un ProtectedApplication. Ad esempio:

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

Definire le regole di orchestrazione

Dopo aver identificato tutte le risorse nel tuo ProtectedApplication, puoi scegliere di definire le regole di orchestrazione dettagliate per un sottoinsieme di queste risorse. Queste regole possono essere applicate solo a due tipi di risorse: Deployment e StatefulSets; sono vendute nella sezione components di ProtectedApplication.

Panoramica dei componenti

La configurazione di un componente prevede quanto segue:

  • Selezione di una strategia fondamentale per il funzionamento di backup e ripristino per questo componente. Sono disponibili tre strategie:

    • BackupAllRestoreAll: esegui il backup dei volumi associati a tutte le istanze del componente e ripristinali tutti dai backup

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

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

  • Definizione degli hook di esecuzione da eseguire durante il backup (e potenzialmente per il ripristino, a seconda della strategia). Un hook è un comando eseguito in container specifici.

  • Seleziona 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 in una determinata fase del processo di backup o ripristino.

Esistono quattro diversi tipi di hook:

  • pre hooks: questi comandi vengono eseguiti appena prima del backup dei volumi e in genere devono svuotare la memoria dei dati sul disco e quindi disattivare l'applicazione in modo che non vengano eseguite nuove scritture. Questi hook vengono utilizzati nelle strategie BackupAllRestoreAll e BackupOneRestoreAll.

  • post hooks: questi comandi vengono eseguiti durante il processo di backup del volume subito dopo il passaggio SNAPSHOTTING della procedura di backup del volume (prima del passaggio CARICAMENTO). In genere, lo SNAPSHOTTING richiede solo pochi secondi. In genere ci si aspetta che riducano i disturbi dell'applicazione (ovvero consentono la normale elaborazione e le scritture del disco per continuare). Questi hook vengono utilizzati nelle strategie BackupAllRestoreAll, BackupOneRestoreAll e DumpAndLoad.

  • dump hooks: questi comandi vengono eseguiti prima che venga eseguito il backup del volume nella strategia DumpAndLoad e in genere si prevede che esportino 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 della strategia DumpAndLoad. Generalmente devono importare nell'applicazione i dati dal volume di backup.

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

Gli hook vengono definiti come parte della sezione dei componenti della specifica ProtectedApplication. Tutte le definizioni di hook hanno gli stessi campi disponibili:

  • name: un nome assegnato all'hook.

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

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

  • timeoutSeconds: (facoltativo) tempo prima dell'interruzione dell'esecuzione dell'hook. Se non lo fornisci, il valore predefinito sarà di 30 secondi.

  • onError: (facoltativo) comportamento adottato quando l'hook non funziona. Può essere impostato su Ignore o Fail (valore predefinito). Se la imposti su Fail, il backup del volume non andrà a buon fine quando un hook non va a buon fine. Se lo imposti su 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 gli hook 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 che vuoi eseguire nel container, ad esempio /sbin/fsfreeze, -f, /var/log/nginx.

Selezione di un sottoinsieme di volumi di cui eseguire il backup

A volte le applicazioni scrivono in volumi che non sono interessanti da ripristinare (ad esempio, alcuni volumi di log o errori). Puoi eliminare il backup di questi volumi utilizzando un selettore di volume.

Per utilizzare questa funzionalità, devi prima applicare un'etichetta comune ai volumi di cui vuoi eseguire il backup, quindi disattivarla per quelli di cui non vuoi eseguire il backup. Poi includi una clausola volumeSelector nella definizione del componente come segue:

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

Se fornisci volumeSelector per un componente, verrà eseguito il backup e il ripristino solo dei volumi che hanno l'etichetta specificata. Al momento del ripristino, verrà eseguito il provisioning di qualsiasi altro volume vuoto anziché ripristinato da un backup del volume.

Strategia: BackupTuttiRipristinatutto

Questa è la strategia più semplice ed 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 la tua applicazione non ha una replica tra Pods.

Questa strategia supporta i seguenti parametri:

  • backupPreHooks (facoltativo) un elenco ordinato di hook che vengono eseguiti appena prima del backup dei volumi. Questi comandi vengono eseguiti su tutti i Pods del componente.

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

  • volumeSelector: (facoltativa) la logica per la corrispondenza di un sottoinsieme di volumi al backup.

In questo esempio viene creata una risorsa ProtectedApplication che interrompe il file system prima di eseguire il backup del volume dei log e dell'interruzione dopo il backup:

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
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: BackupUnoERipristinaTutti

Questa strategia esegue il backup di una copia di un pod selezionato. Questa singola copia è l'origine per il ripristino di tutti i pod durante un ripristino. Questo metodo può aiutare a ridurre i costi di archiviazione e i tempi di backup. Questa strategia funziona in una configurazione ad alta disponibilità quando viene eseguito il deployment di un componente con un elemento PersistentVolumeClaim principale e più PersistentVolumeClaims secondari.

Questa strategia supporta i seguenti parametri:

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

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

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

  • volumeSelector: (facoltativa) la logica per la corrispondenza di un sottoinsieme di volumi al backup.

Se un componente è configurato con più deployment o StatefulSet, tutte le risorse devono avere la stessa struttura di PersistentVolume, ovvero devono seguire queste regole:

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

Alla luce 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, supponendo che un'architettura sia uno StatefulSet principale e uno StatefulSet secondario, mostra un backup dei volumi di un pod nello StatefulSet secondario, quindi un ripristino in tutti gli altri volumi:

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
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 i dati di dump.

Questa strategia supporta i seguenti parametri:

  • dumpTarget: (obbligatorio) specifica il deployment o l'oggetto StatefulSet da utilizzare per eseguire il backup dei dati. Viene selezionato automaticamente il pod migliore di cui eseguire il backup. In una configurazione a disponibilità elevata, ti consigliamo di impostarlo su una delle repliche dell'applicazione.

  • loadTarget: (obbligatorio) specifica il Deployment o l'oggetto StatefulSet da utilizzare per caricare i dati. Viene selezionato automaticamente il pod migliore di cui eseguire il backup. La destinazione del carico non deve essere uguale alla destinazione del dump.

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

  • backupPostHooks: (facoltativo) un elenco ordinato di hook 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 hook eseguiti per caricare i dati dal volume ripristinato dopo l'avvio dell'applicazione. Questi comandi vengono eseguiti solo sul caricamento selezionato Pod.

  • volumeSelector: logica (obbligatoria) per associare un singolo volume al backup e al ripristino (il volume "dump"). Anche se deve corrispondere a un solo volume, la configurazione avviene nello stesso modo in cui utilizzi il sottoinsieme di volumi di cui eseguire il backup.

Se l'applicazione è composta da deployment, ogni deployment deve avere esattamente una replica.

Questo esempio, supponendo che un'architettura sia uno StatefulSet principale e uno StatefulSet secondario con PersistentVolumeClaims dedicato per gli StatefulSet primari e secondari, mostra una strategia DumpAndLoad:

kind: ProtectedApplication
apiVersion: gkebackup.gke.io/v1alpha2
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

Controlla se un dispositivo ProtectedApplication è pronto per il backup

Puoi verificare se un oggetto ProtectedApplication è pronto per un backup eseguendo questo comando:

kubectl describe protectedapplication APPLICATION_NAME

Sostituisci APPLICATION_NAME con il nome della tua applicazione.

Se è pronta, la descrizione dell'applicazione mostrerà lo stato Ready to backup come true, come in questo esempio:

% kubectl describe protectedapplication nginx
Name:         nginx
Namespace:    default
API Version:  gkebackup.gke.io/v1alpha2
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