Quando você ativa o agente do Backup para GKE no cluster do Google Kubernetes Engine, o Backup para GKE fornece um CustomResourceDefinition que introduz um novo tipo de recurso do Kubernetes: o ProtectedApplication.
A composição de um ProtectedApplication envolve três atividades:
Selecionar o conjunto de recursos que você quer fazer backup e restaurar como parte do aplicativo.
Definir regras detalhadas de orquestração para um subconjunto desses recursos.
Validar o
ProtectedApplicationpara verificar se ele está pronto para backup.
Os recursos do ProtectedApplication oferecem essas capacidades ao personalizar a lógica de backup e restauração no nível do aplicativo:
Operações de backup e restauração mais detalhadas. Sem
ProtectedApplications, o escopo dos backups precisa ser definido no nívelNamespace(selecionando allNamespaces ou selectedNamespaces). Uma lógica semelhante se aplica à restauração de recursos com namespace. A criação de recursosProtectedApplicationpermite que você forneça um nome a um subconjunto dos recursos em umNamespace. Em seguida, é possível fazer backup e restaurar esse subconjunto listando selectedApplications no escopo de backup e de maneira semelhante para restaurar.Orquestrar detalhes do processo de backup ou restauração, como:
ignorar volumes selecionados durante o backup;
incorporar a topologia do aplicativo no backup e na restauração (por exemplo, fazer backup de apenas uma instância de um banco de dados replicado e usá-la para restaurar várias instâncias).
A execução de ganchos definidos pelo usuário antes e depois dos volumes terem snapshots. Eles podem ser usados, por exemplo, para limpar e silenciar uma carga de trabalho antes de criar um snapshot e remover o silenciamento depois.
Crie ProtectedApplication usando kubectl como outros recursos do Kubernetes. Eles são completamente opcionais. Se recursos de ProtectedApplication não estão presentes, o Backup para GKE cria backups de volume para todos os volumes no escopo de um backup e os backups de volume resultantes sãoconsistentes com a falha. Todas as gravações transferidas para o disco em um determinado momento serão capturadas, ou seja, não serão gravadas parcialmente. No entanto, alguns aplicativos podem manter dados na memória que não são transferidos para o disco. Portanto, se um aplicativo pode ou não se recuperar de um backup consistente com falha, depende da lógica do aplicativo.
Como selecionar recursos
O primeiro passo para criar seu recurso ProtectedApplication é identificar os outros recursos no mesmo Namespace que você quer incluir como parte do aplicativo. Este é o conjunto de recursos que será armazenado em backup ou restaurado se você fornecer a opção de escopo selectedApplications na configuração BackupPlan.
Os recursos são identificados por um seletor de rótulo. Isso exige que você rotule todos os recursos (usando o campo metadata.label em cada recurso) com o mesmo rótulo. Observe que isso também se aplica a recursos criados automaticamente por controladores. Esses recursos criados automaticamente são identificados usando o modelo correspondente. É comum reutilizar o mesmo identificador que você já está usando para associar o Pods e o PersistentVolumeClaims gerados ao recurso pai.
As considerações de uso incluem o seguinte:
- Se você quiser proteger recursos que criam recursos filhos, os recursos principais (como
StatefulSet,DeploymentouDaemonSet) e os recursos filhos (comoPodouPersistentVolumeClaim) precisam ter o rótulo usado no campoSelectordoProtectedApplication. - Se alguns dos recursos referenciados por seu
ProtectedApplicationforem criados automaticamente por um operador, inclua também os recursos personalizados do operador no seu seletor deProtectedApplication. Isso ajuda a evitar uma disputa no momento da restauração que pode ocorrer quando o operador tenta criar um recurso enquanto ele é restaurado simultaneamente a partir do backup.
O exemplo a seguir mostra como aplicar o identificador app: nginx aos outros recursos, além de 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: ... Depois de aplicar o identificador selecionado a todos os recursos de destino e aos modelos dos quais outros recursos são gerados, será possível referenciar esses recursos de um ProtectedApplication. Exemplo:
kind: ProtectedApplication apiVersion: gkebackup.gke.io/v1 metadata: name: nginx namespace: webserver spec: resourceSelection: type: Selector selector: matchLabels: app: nginx ... Definir regras de orquestração
Depois de identificar todos os recursos no ProtectedApplication, é possível definir regras de orquestração detalhadas para um subconjunto desses recursos. Essas regras só podem ser aplicadas a dois tipos de recursos: implantações e StatefulSets e são referenciadas na seção components de ProtectedApplication.
Visão geral do componente
A configuração de um componente envolve o seguinte:
A seleção de uma estratégia fundamental para o funcionamento do backup e da restauração desse componente. Há três estratégias disponíveis:
BackupAllRestoreAll: fazer backup dos volumes associados a todas as instâncias do componente e restaurar todos eles usando os backups.BackupOneRestoreAll: fazer backup dos volumes de apenas uma instância do componente e usar esses backups para restaurar todas as instâncias.DumpAndLoad: exportar dados do aplicativo para um único volume no momento do backup e importar esses dados para o aplicativo no momento da restauração.
Definir ganchos de execução a serem executados durante o backup e, possivelmente, restaurar, dependendo da estratégia. Um gancho é um comando executado em contêineres específicos.
Ganchos de execução
Um gancho é um comando do shell que o Backup para GKE executa em um contêiner em uma fase específica do processo de backup ou restauração.
Há quatro tipos diferentes de ganchos:
pre hooks: esses comandos são executados logo antes de fazer backup dos volumes e geralmente transferem todos os dados na memória para o disco e desativa o aplicativo para que não ocorram novas gravações de disco. Esses ganchos são usados nas estratégiasBackupAllRestoreAlleBackupOneRestoreAll.post hooks: esses comandos são executados durante o processo de backup de volume logo após a etapa SNAPSHOTTING do processo de backup de volume (antes da etapa UPLOADING). Geralmente, a etapa SNAPSHOTTING leva apenas alguns segundos. Geralmente, espera-se que eles removam o silenciamento do aplicativo, o que permite continuar o processamento normal e as gravações de disco. Esses ganchos são usados nas estratégiasBackupAllRestoreAll,BackupOneRestoreAlleDumpAndLoad.dump hooks: esses comandos são executados antes de fazer o backup do volume na estratégiaDumpAndLoade geralmente espera-se que exportem os dados do aplicativo para o volume de backup designado.load hooks: esses comandos são executados no momento da restauração depois que o volume de backup é restaurado nos casos de estratégiaDumpAndLoad. Geralmente, é esperado que os dados sejam importados do volume de backup para o aplicativo.
É possível fornecer mais de um gancho para cada tipo, e o Backup para GKE os executará na ordem em que você os define.
Você define ganchos como parte da seção de componentes da especificação ProtectedApplication. Todas as definições de ganchos têm os mesmos campos disponíveis:
name: um nome que você atribui ao gancho.container: (opcional) nome do contêiner em que o comando será executado. Se você não informar o contêiner, o Backup para GKE executará o hook no primeiro contêiner definido para osPods de destino.command: é o comando atual enviado para o contêiner, construído como uma matriz de palavras. A primeira palavra na matriz é o caminho para o comando, e as palavras seguintes são os argumentos que vão ser transmitidos para o comando.timeoutSeconds(opcional): tempo antes do cancelamento da execução do gancho. Se você não informar esse valor, o padrão será de 30 segundos.onError: (opcional) comportamento tomado quando o gancho falha. Pode ser definido comoIgnoreouFail(padrão). Se você definir comoFail, quando o gancho falhar, o backup do volume falhará. Se você definir comoIgnore, as falhas desse gancho serão ignoradas.
Antes de aplicar os ganchos do ProtectedApplication ao seu aplicativo, teste o comando usando kubectl exec para garantir que os ganchos se comportem conforme o esperado:
kubectl exec POD_NAME -- COMMAND Substitua:
POD_NAME: o nome do pod que contém o recursoProtectedApplication.COMMAND: a matriz que contém o comando que você quer executar no contêiner.
Como selecionar um subconjunto de volumes para o backup
Às vezes, os aplicativos gravam em volumes que não são interessantes para restaurar (por exemplo, alguns volumes de registro ou de rascunho). É possível suprimir o backup desses volumes usando um seletor de volume.
Para usar esse recurso, primeiro aplique um identificador comum aos recursos PersistentVolumeClaim dos volumes que você quer fazer backup. Você também precisa deixar esse identificador desativado nos recursos PersistentVolumeClaim dos volumes que você não quer fazer backup. Em seguida, inclua uma cláusula volumeSelector na definição do componente da seguinte maneira:
spec: ... components: ... strategy: ... volumeSelector: matchLabels: label_name: label_value Se você fornecer um volumeSelector para um componente, somente os volumes cujos recursos PersistentVolumeClaim têm o identificador especificado serão salvos em backup e restaurados. No momento da restauração, qualquer outro volume será provisionado como vazio em vez de restaurado de um backup de volume.
Estratégia: BackupAllRestoreAll
Essa é a estratégia mais simples, faz backup de todos os volumes do componente no momento do backup e restaura todos eles a partir dos backups de volume no momento da restauração. Essa é melhor opção quando o aplicativo não tem replicação entre Pods.
Essa estratégia é compatível com os seguintes parâmetros:
backupPreHooks(opcional): uma lista ordenada de ganchos que são executados logo antes do backup dos volumes. Esses comandos são executados em todos osPodsno componente.backupPostHooks(opcional): uma lista ordenada de ganchos que são executadas após os backups de volume alcançarem a fase UPLOADING. Esses comandos são executados em todos osPodsno componente.volumeSelector(opcional): lógica para corresponder um subconjunto de volumes ao backup.
Este exemplo cria um recurso ProtectedApplication que desativa o sistema de arquivos antes de fazer backup do volume de registros e cancela a desativação após o 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-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 Estratégia: BackupOneAndRestoreAll
Essa estratégia faz backup de uma cópia de um pod selecionado. Essa cópia única é a fonte para restaurar todos os pods durante uma restauração. Esse método ajuda a reduzir o custo de armazenamento e o tempo de backup. Essa estratégia funciona em uma configuração de alta disponibilidade quando um componente é implantado com um PersistentVolumeClaim primário e vários PersistentVolumeClaims secundários.
Essa estratégia é compatível com os seguintes parâmetros:
backupTargetName(obrigatório): especifica qual implantação ou StatefulSet você quer usar para fazer backup dos dados. O melhor pod para fazer backup é selecionado automaticamente. Em uma configuração de alta disponibilidade, recomendamos que você a defina como uma das réplicas do seu aplicativo.backupPreHooks: (opcional) uma lista ordenada de ganchos que são executados logo antes do backup dos volumes. Esses comandos são executados apenas noPodde backup selecionado.backupPostHooks(opcional): uma lista ordenada de ganchos que são executadas após os backups de volume alcançarem a fase UPLOADING. Esses comandos são executados apenas noPodde backup selecionado.volumeSelector(opcional): lógica para corresponder um subconjunto de volumes ao backup.
Se um componente for configurado com várias implantações ou StatefulSets, todos os recursos precisarão ter a mesma estrutura PersistentVolume, o que significa que eles precisam seguir estas regras:
- O número de
PersistentVolumeClaimsusado por todas as implantações ou StatefulSets precisa ser o mesmo. - A finalidade de
PersistentVolumeClaimsno mesmo índice precisa ser a mesma. Para StatefulSets, o índice é definido novolumeClaimTemplate. Para implantações, o índice é definido emVolumese todos os volumes não permanentes são ignorados. - Se o componente do aplicativo consistir em implantações, cada implantação precisará ter exatamente uma réplica.
Considerando essas considerações, vários conjuntos de volumes podem ser selecionados para backup, mas apenas um volume de cada conjunto será selecionado.
Neste exemplo, supondo uma arquitetura de um StatefulSet principal e um StatefulSet secundário, mostramos um backup de volumes de um pod no StatefulSet secundário e uma restauração para todos os outros volumes:
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: [...] Estratégia: DumpAndLoad
Essa estratégia usa um volume dedicado para processos de backup e restauração e requer um PersistentVolumeClaim dedicado anexado a um componente que armazena dados dump.
Essa estratégia é compatível com os seguintes parâmetros:
dumpTarget(obrigatório): especifica qual implantação ou StatefulSet você quer usar para fazer backup dos dados. O melhor pod para fazer backup é selecionado automaticamente. Em uma configuração de alta disponibilidade, recomendamos que você a defina como uma das réplicas do seu aplicativo.loadTarget(obrigatório): especifica qual implantação ou StatefulSet será usado para carregar os dados. O melhor pod para fazer backup é selecionado automaticamente. O destino de carregamento não precisa ser o mesmo que o destino de despejo.dumpHooks(obrigatório): uma lista ordenada de ganchos que são executados para preencher o volume de backup dedicado. Esses comandos são executados apenas noPodde despejo selecionado.backupPostHooks(opcional): uma lista ordenada de ganchos que são executadas após os backups de volume alcançarem a fase UPLOADING. Esses comandos são executados apenas noPodde despejo selecionado.loadHooks(obrigatório): uma lista ordenada de ganchos que são executados para carregar os dados do volume restaurado após o início do aplicativo. Esses comandos são executados apenas noPoddo carregamento selecionado.volumeSelector(obrigatório): lógica para corresponder um único volume para backup e restauração (o volume "despejo"). Embora ela só precise corresponder a um único volume, você a configura da mesma forma que o subconjunto de volumes para backup usado por outras estratégias.
Se o aplicativo consistir em implantações, cada implantação precisará ter exatamente uma réplica.
Neste exemplo, suponha que uma arquitetura de um StatefulSet principal e um StatefulSet secundário com PersistentVolumeClaims dedicado para StatefulSets principais e secundários mostre uma estratégia 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 Verificar se um ProtectedApplication está pronto para backup
É possível verificar se um ProtectedApplication está pronto para um backup executando o seguinte comando:
kubectl describe protectedapplication APPLICATION_NAME Substitua APPLICATION_NAME pelo nome do aplicativo.
Se estiver pronto, a descrição do aplicativo mostrará o status Ready to backup como true, como neste exemplo:
% 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> A seguir
- Saiba mais sobre como planejar um conjunto de backups.