Une infrastructure de conteneurs a besoin d'un type particulier de sauvegarde. Après un désastre, Kubernetes et Docker ne se rétabliront toutefois pas comme par magie. S’il n’est pas nécessaire de sauvegarder l'état de fonctionnement de chaque conteneur, il est indispensable de sauvegarder la configuration si l’on veut pouvoir exécuter et gérer les conteneurs. Voici ce qu’il faut sauvegarder.

Configuration et information sur l'état souhaité

- Les Dockerfiles utilisés pour construire les images et toutes les versions de ces fichiers.

- Les images créées à partir de Dockerfile et utilisées pour exécuter chaque conteneur.

- Kubernetes etcd & autres : les bases de données K8 qui informent sur l'état des clusters

- Déploiements : les fichiers YAML décrivant chaque déploiement

Données persistantes créées ou modifiées par les conteneurs

- Volumes persistants

- Bases de données 

Les Dockerfiles

Les conteneurs Docker sont gérés à partir d'images, et les images sont construites à partir des Dockerfiles. Déjà, une configuration Docker correcte utilise un certain type de référentiel - GitHub, par exemple - comme système de contrôle de version pour tous les Dockerfiles. Vous ne devez pas créer de conteneurs ad hoc en utilisant des images ad hoc construites à partir de Dockerfiles ad hoc. Tous les Dockerfiles devraient être stockés dans un référentiel qui vous permet de récupérer les versions historiques de ce Dockerfile s'il y a un problème avec la build en cours d’utilisation. Vous devriez également avoir une sorte de référentiel pour stocker les fichiers YAML associés à chaque déploiement de K8. Ces fichiers texte peuvent bénéficier d'un système de contrôle de version.

Il faut ensuite sauvegarder ces référentiels. GitHub est l’un des référentiels les plus populaires. Il offre plusieurs solutions pour sauvegarder votre référentiel. Différents scripts utilisant les API fournies permettent de télécharger une sauvegarde actuelle de votre référentiel. Vous pouvez aussi utiliser des outils tiers commerciaux pour sauvegarder GitHub ou tout autre référentiel que vous utilisez. Si vous n'avez pas suivi la méthode présentée ci-dessus et que vous avez des conteneurs en cours d'exécution basés sur des images pour lesquelles vous n'avez plus de Dockerfiles, vous pouvez utiliser la commande d'historique d’images de Docker ou un outil comme dfimage pour créer un Dockerfile à partir de vos images actuelles. Chargez ces Dockerfiles dans un référentiel et commencez à les sauvegarder ! Mais il est vraiment préférable de ne pas se retrouver dans cette situation. Stockez et sauvegardez toujours les Dockerfiles et les fichiers YAML utilisés pour créer votre environnement.

Images Docker

Il est également important de conserver les images actuelles utilisées pour exécuter vos conteneurs dans un référentiel. (Évidemment, si vous exécutez des images Docker dans Kubernetes, c’est déjà le cas). Vous pouvez utiliser un référentiel privé comme un registre Docker, ou un référentiel public comme Dockerhub. Les fournisseurs de cloud peuvent également vous fournir un référentiel privé pour stocker vos images. Il faudra aussi sauvegarder le contenu de ce référentiel. Une simple recherche sur Google avec comme mots clefs « sauvegarde Dockerhub » peut remonter un nombre inattendu d'options. Si vous n'avez pas l'image actuelle qui sert à exécuter vos conteneurs, vous pouvez en créer une en utilisant la commande docker commit. Vous pouvez ensuite créer un Dockerfile à partir de cette image en utilisant l'historique d’images de Docker ou l'outil dfimage. 

Kubernetes etcd

La base de données « Kubernetes etcd » est très importante et doit être sauvegardée en utilisant la commande etcdctl snapshot save db. Elle créera le fichier snapshot.db dans le répertoire courant. Ensuite il faudra sauvegarder ce fichier sur un support externe. Si vous utilisez un logiciel de sauvegarde commercial, vous pouvez facilement lancer la commande etcdctl snapshot save avant de faire une sauvegarde du répertoire où sera créé le fichier snapshot.db. Cela permettra d'intégrer cette sauvegarde dans votre environnement de sauvegarde commercial. (Vous pouvez consulter cette page GitUp sur la reprise après sinistre (en anglais) https://github.com/etcd-io/etcd/blob/master/Documentation/op-guide/recovery.md).

Volumes persistants

Les conteneurs disposent de plusieurs options pour accéder au stockage permanent utilisé pour stocker ou créer des données. Les volumes Docker traditionnels résident dans un sous-répertoire de la configuration Docker. Les bind mounts de Docker créent un lien avec n'importe quel répertoire sur un hôte Docker monté à l'intérieur d'un conteneur (en utilisant la commande bind mount). Pour diverses raisons, les volumes traditionnels sont préférés par la communauté Docker, mais pour la sauvegarde, il n’y a pas de différence entre les volumes traditionnels et les bind mounts. Vous pouvez également monter un répertoire NFS (Network-file-system) ou un objet d'un système de stockage objets en tant que volume à l’intérieur d’un conteneur. 

La méthode que vous utiliserez pour sauvegarder vos volumes persistants doit être basée sur l'une des options ci-dessus, utilisée pour le conteneur. Cependant, toutes ces options posent le même problème : si les données changent, il faudra s’en préoccuper pour générer une sauvegarde cohérente. Une manière de procéder consiste à fermer tous les conteneurs utilisant ce volume particulier. C'est un peu une méthode de la vieille école, mais c'est l’un des défis créés par le monde des conteneurs, puisque la méthode typique qui consiste à mettre un agent de sauvegarde dans le conteneur n'est pas vraiment une option. Une fois fermé, le volume peut être sauvegardé. S'il s'agit d'un volume Docker traditionnel, vous pouvez le sauvegarder en le montant sur un autre conteneur qui ne changera pas ses données pendant la sauvegarde, puis en créant une image .tar du volume dans un volume monté en bind que vous sauvegarderez ensuite en utilisant la même solution de sauvegarde que celle utilisée par votre système. Cependant, c'est vraiment difficile à faire dans Kubernetes. C'est l’une des raisons pour lesquelles il est préférable de stocker les informations d'état dans une base de données, et non dans un système de fichiers. C’est un problème à prendre en compte dès la conception de votre infrastructure K8. De plus, si vous utilisez un répertoire bind mounted, un système de fichiers monté en NFS, ou un système de stockage objets comme système de stockage persistant, vous pouvez utiliser n'importe quelle solution pour sauvegarder ce système de stockage. Faire par exemple un instantané suivi d'une réplication, ou simplement lancer votre logiciel de sauvegarde commercial sur ce système. Ces méthodes peuvent créer une sauvegarde beaucoup plus cohérente qu'une sauvegarde typique au niveau des fichiers de ce même volume. 

Bases de données

Autre défi en matière de sauvegarde : le conteneur utilise une base de données pour stocker ses données. Ces SGBD doivent être sauvegardés de manière à garantir leur intégrité. Selon la base de données, la méthode mentionnée ci-dessus peut fonctionner : arrêter le conteneur qui accède à la base de données, puis sauvegarder le répertoire où sont stockés ses fichiers. Cependant, le temps d'arrêt requis par cette méthode peut ne pas être approprié. Une autre méthode consiste à se connecter directement au moteur de la base de données lui-même et à lui demander d'exécuter une sauvegarde sur un fichier que vous pourrez ensuite sauvegarder. Si la base de données s'exécute à l'intérieur d'un conteneur, vous devrez d'abord utiliser un bind mount pour lier un volume qu'il peut sauvegarder, de façon à ce que sa sauvegarde puisse exister à l'extérieur du conteneur. Exécutez ensuite la commande que la base de données utilise (comme mysqldump) pour créer une sauvegarde. Enfin, assurez-vous de sauvegarder le fichier qu'elle crée en utilisant votre système de sauvegarde. Mais que faire si vous ne savez pas quel stockage ou quelles bases de données utilisent les conteneurs ? Dans ce cas, vous pouvez par exemple utiliser la commande docker ps pour lister les conteneurs en cours d'exécution, puis utiliser la commande docker inspect pour afficher la configuration de chaque conteneur. Une section appelée Mounts vous indiquera quels volumes sont montés et où ils se trouvent. Les bind mounts seront également spécifiés dans les fichiers YAML que vous avez soumis à Kubernetes.

Solutions de sauvegarde commerciales

Plusieurs solutions de sauvegarde commerciales peuvent protéger une partie ou la totalité des données mentionnées ci-dessus. En voici un aperçu rapide :

- L'agent de serveur virtuel de Commvault peut servir de proxy pour sauvegarder les conteneurs et leurs images.

- Cohesity offre une protection des données pour les espaces de noms K8.

- Heptio (désormais propriété de VMware) propose la solution de sauvegarde Velero conçue pour K8.

- Contino, Datacore et Portworx proposent un stockage conçu pour Kubernetes et les conteneurs, et prennent également en charge la sauvegarde de ces informations. 

Compte tenu de toutes les configurations possibles de K8 et de Docker, il est très difficile de couvrir tous les aspects du sujet en un seul article. Au minimum, ce tour d’horizon permet de se poser la question de la sauvegarde et peut inciter à prendre des mesures en ce sens.