Cloud Intelligence™Cloud Intelligence™

Cloud Intelligence™

Protégez les données de vos StatefulSets avec Backup for GKE

By Felipe MartinezJul 20, 20237 min read

Cette page est également disponible en English, Deutsch, Español, Italiano, 日本語 et Português.

Introduction

Les StatefulSets sont une ressource Kubernetes puissante pour gérer les applications avec état. Ils peuvent toutefois s'avérer complexes et difficiles à sauvegarder, ce qui peut entraîner une perte de données en cas de défaillance.

L'an dernier (2022), Google a annoncé une nouvelle fonctionnalité add-on pour GKE baptisée Backup for GKE. Il s'agit d'une solution simple et cloud-native pour protéger, gérer et restaurer l'ensemble des applications conteneurisées et de leurs données.

Dans cet article, nous allons passer en revue les composants de Backup for GKE et voir comment sauvegarder les volumes d'un StatefulSet MySQL déployé dans un cluster GKE.

Architecture

Backup for GKE se compose de deux éléments principaux :

  • Un service qui s'exécute dans Google Cloud et expose une API REST orientée ressources. Ce service constitue le plan de contrôle de Backup for GKE et inclut des éléments d'interface dans la console Google Cloud qui interagissent avec cette API.
  • Un agent qui s'exécute dans chaque cluster où des sauvegardes ou des restaurations sont effectuées. L'agent réalise les opérations de sauvegarde et de restauration dans ces clusters en interagissant avec l'API Backup for GKE.

Le service Backup for GKE s'intègre à l'interface GKE, à la CLI Google Cloud et aux API REST, et offre des workflows cohérents pour le développement et l'exploitation. Une sauvegarde capture deux types de données :

  • Sauvegarde de configuration : un ensemble de manifestes de ressources Kubernetes extraits de l'API server du cluster sauvegardé, qui capture l'état du cluster.
  • Sauvegardes de volumes : un ensemble de sauvegardes de volumes correspondant aux ressources PersistentVolumeClaim présentes dans la sauvegarde de configuration.

Vous pouvez choisir les workloads à sauvegarder ou à restaurer, ou bien tout sauvegarder ou tout restaurer d'un coup. Vous pouvez aussi sauvegarder des workloads depuis un cluster et les restaurer dans un autre. Enfin, vous pouvez planifier vos sauvegardes pour qu'elles s'exécutent automatiquement et ainsi récupérer vos workloads rapidement en cas d'incident.

Mise en pratique

Dans les étapes qui suivent, nous allons créer un cluster GKE zonal, y déployer un StatefulSet MySQL, puis tester la création d'une sauvegarde ainsi que la restauration de notre base de données.

Définir les variables

Pour simplifier, créons quelques variables d'environnement :

export PROJECT_ID=felipe-playground-378415
export REGION=us-east1
export LOCATION=us-east1-c
export CLUSTER=backup-for-gke
export BK_PLAN_ALL_NAMESPACES=mysql-bk-plan-all-ns
export RESTORE_PLAN_ALL_NAMESPACES=mysql-bk-plan-all-ns
export BK_ALL_NAMESPACES=mysql-bk-all-namespaces
export RESTORE_ALL_NAMESPACES=mysql-restore-all-namespaces

Créer le cluster GKE

Définissons quelques variables pour faciliter les commandes. Pensez à renseigner votre propre PROJECT_ID. Pour cet exercice, nous allons créer un cluster GKE zonal dans la zone us-east1-c. Un cluster zonal possède un unique plan de contrôle dans une seule zone. Pour les workloads de production, je recommande plutôt des clusters régionaux : ils offrent une meilleure disponibilité grâce à plusieurs réplicas du plan de contrôle répartis dans plusieurs zones d'une même région. Nous conservons également toutes les valeurs par défaut du cluster : VPC et sous-réseaux par défaut, nombre de nœuds, compte de service par défaut, etc. Je déconseille l'usage des valeurs par défaut pour les clusters de production.

Veillez à ajouter le flag --addons=BackupRestore dans votre commande afin que les contrôleurs de sauvegarde et l'ensemble des CRD soient également déployés.

gcloud container clusters create ${CLUSTER} \
    --release-channel stable \
    --zone ${LOCATION} \
    --node-locations ${LOCATION} \
    --project ${PROJECT_ID} \
    --addons=BackupRestore

Connectons-nous maintenant au cluster :

gcloud container clusters get-credentials ${CLUSTER} \
--zone ${LOCATION} \
--project ${PROJECT_ID}

Installer un StatefulSet

Créons à présent notre StatefulSet. Pour cet exercice, j'ai choisi l'opérateur MySQL, particulièrement simple et rapide à installer via Helm.

helm repo add mysql-operator https://mysql.github.io/mysql-operator/
helm repo update
helm install my-mysql-operator mysql-operator/mysql-operator \
   --namespace mysql-operator --create-namespace

Installer MySQL

Installez MySQL avec Helm — pensez bien à modifier votre mot de passe !

helm install mycluster mysql-operator/mysql-innodbcluster \
   --set tls.useSelfSigned=true \
   --set credentials.root.user=safeuser \
   --set credentials.root.password=notsupersafepassword \
   --set credentials.root.host="%"

Avec la commande kubectl get pods,pvc, vous devriez obtenir un résultat proche de celui-ci :

NAME                                    READY   STATUS    RESTARTS   AGE
pod/mycluster-0                         2/2     Running   0          23m
pod/mycluster-1                         2/2     Running   0          23m
pod/mycluster-2                         2/2     Running   0          23m
pod/mycluster-router-67585969f6-m9nd7   1/1     Running   0          22m

NAME                                        STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/datadir-mycluster-0   Bound    pvc-d5214172-9b81-4d29-9bf0-9e0dcdc8f691   2Gi        RWO            standard-rwo   23m
persistentvolumeclaim/datadir-mycluster-1   Bound    pvc-df8e188a-51aa-4c4f-acb1-73daa72bc721   2Gi        RWO            standard-rwo   23m
persistentvolumeclaim/datadir-mycluster-2   Bound    pvc-defb5e6e-5946-4183-99d2-c168b05a3d6c   2Gi        RWO            standard-rwo   23m

Parfait ! Étape suivante : configurer les ressources Backup for GKE pour notre cluster.

Backup for GKE inclut deux types de ressources de configuration et de contrôle :

  • BackupPlan : ressource parente des ressources Backup, qui représente une chaîne de sauvegardes. Elle contient une configuration de sauvegarde comprenant le cluster source, la sélection des workloads à sauvegarder et la région dans laquelle sont stockés les artefacts Backup produits par ce plan.
  • RestorePlan : fournit un modèle de restauration réutilisable. Cette ressource contient une configuration de restauration comprenant le cluster cible, le plan de sauvegarde source, la portée de la restauration, la gestion des conflits et les règles de substitution.

Créer un plan de sauvegarde pour tous les namespaces

gcloud beta container backup-restore backup-plans create ${BK_PLAN_ALL_NAMESPACES} \
    --project=${PROJECT_ID} \
    --location=${REGION} \
    --cluster=projects/${PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER} \
    --all-namespaces \
    --include-secrets \
    --include-volume-data

Créer un plan de restauration pour tous les namespaces

gcloud beta container backup-restore restore-plans create ${RESTORE_PLAN_ALL_NAMESPACES}\
  --all-namespaces \
  --project=${PROJECT_ID} \
  --location=${REGION} \
  --backup-plan=projects/${PROJECT_ID}/locations/${REGION}/backupPlans/${BK_PLAN_ALL_NAMESPACES} \
  --cluster=projects/${PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER} \
  --cluster-resource-conflict-policy=use-existing-version \
  --namespaced-resource-restore-mode=delete-and-restore \
  --volume-data-restore-policy=restore-volume-data-from-backup \
  --cluster-resource-restore-scope="storage.k8s.io/StorageClass","scheduling.k8s.io/PriorityClass"

Si les commandes précédentes se sont bien déroulées, tous les plans sont en place.

Créer une sauvegarde pour tous les namespaces

gcloud beta container backup-restore backups create ${BK_ALL_NAMESPACES} \
--project=${PROJECT_ID} \
--location=${REGION} \
--backup-plan=${BK_PLAN_ALL_NAMESPACES} \
--wait-for-completion

L'opération peut prendre un certain temps selon la taille de vos volumes, mais le message ci-dessous devrait apparaître dès qu'elle est terminée :

Backup completed. Backup state: SUCCEEDED

Tester la restauration

gcloud beta container backup-restore restores create ${RESTORE_ALL_NAMESPACES} \
  --project=${PROJECT_ID} \
  --location=${REGION} \
  --restore-plan=${RESTORE_PLAN_ALL_NAMESPACES} \
  --backup=projects/$PROJECT_ID/locations/${REGION}/backupPlans/${BK_PLAN_ALL_NAMESPACES}/backups/${BK_ALL_NAMESPACES} \
  --wait-for-completion

Restore Completed. Restore stat: SUCCEEDED

Et voilà, ça fonctionne !

Backup for GKE permet également de sauvegarder un bundle d'application unique créé via la CRD ProtectedApplication, mais ce sera le sujet d'un autre article.

IaC

À ce jour (juin 2023), une seule ressource Terraform permet de créer un GKE Backup Plan : google_gke_backup_backup_plan, ajoutée dans la version 4.5.0 du provider Google, comme indiqué ici. Espérons que d'autres ressources arriveront bientôt.

Tarification

Backup for GKE est facturé selon deux dimensions : d'une part, des frais de gestion de sauvegarde GKE, basés sur le nombre de pods GKE protégés ; d'autre part, des frais de stockage, basés sur le volume de données (Go) stockées. Ces deux frais sont calculés mensuellement, comme pour la facturation des autres fonctionnalités GKE.

Prenons un exemple : un client disposant d'un seul plan de sauvegarde dans l'Iowa (us-central1), qui sauvegarde en moyenne 20 pods sur un mois et stocke 200 Go de données de sauvegarde dans l'Iowa, sera facturé 25,60 $. Ce montant comprend 20 $ pour la gestion mensuelle des sauvegardes GKE (20 × 1,00 $ / pod-mois) et 5,60 $ pour le stockage des sauvegardes (200 × 0,028 $ / Go-mois).

À compter du 26 juin 2023, de nouveaux frais de sortie réseau s'appliqueront aux sauvegardes stockées dans une région différente de celle de leur cluster GKE source. Ces frais dépendront des régions source et de destination ainsi que du nombre d'octets transférés pour chaque opération de sauvegarde "inter-régions".

Nettoyage

Supprimez le cluster :

gcloud container clusters delete ${CLUSTER} --project $PROJECT_ID --zone ${LOCATION}

N'oubliez pas non plus de supprimer les sauvegardes et les plans :

# Supprimer la sauvegarde
gcloud beta container backup-restore backups delete ${BK_ALL_NAMESPACES} \
  --location=${REGION} \
  --backup-plan=${BK_PLAN_ALL_NAMESPACES}
# Supprimer le plan de sauvegarde
gcloud beta container backup-restore backup-plans delete ${BK_PLAN_ALL_NAMESPACES} \
  --location=${REGION}
# Supprimer le plan de restauration
gcloud beta container backup-restore restore-plans delete ${RESTORE_PLAN_ALL_NAMESPACES} \
  --location=${REGION}

J'espère que ce parcours vous a plu — n'hésitez pas à me contacter si vous avez la moindre question !