web-dev-qa-db-fra.com

Déploiements continus Kubernetes et migrations de bases de données

Lors du traitement d'une mise à jour continue avec des migrations de base de données, comment kubernetes gère-t-il cela?

Par exemple, j'ai une application qui est mise à jour de app-v1 vers app-v2, qui comprend une étape de migration pour modifier une table existante. Cela signifierait donc qu'il me faut exécuter quelque chose comme db:migrate pour une application Rails une fois déployée.

Lorsqu'un déploiement continu a lieu sur 3 réplicas. Il se déploiera d'un pod à l'autre. Permettre potentiellement aux POD qui n'ont pas la nouvelle version de l'application de se casser.

Bien que ce scénario ne se produise pas très souvent. Il est tout à fait possible que ce soit le cas. Je voudrais en savoir plus sur les meilleures approches/recommandées pour ce scénario.

24
Gayan Hewa

Une façon d'empêcher une ancienne version de se casser consiste à diviser une migration en plusieurs étapes.

Par exemple. vous souhaitez renommer une colonne dans la base de données. Renommer directement la colonne romprait les anciennes versions de l'application. Cela peut être divisé en plusieurs étapes:

  • Ajouter une migration de base de données qui insère la nouvelle colonne
  • Modifiez l'application de sorte que toutes les écritures passent à l'ancienne et à la nouvelle colonne
  • Exécutez une tâche qui copie toutes les valeurs de l'ancienne vers la nouvelle colonne
  • Changer l'application qu'elle lit dans la nouvelle colonne
  • Ajouter une migration qui supprime l'ancienne colonne

Ceci est malheureusement assez compliqué, mais empêche d'avoir un temps d'arrêt avec une page de maintenance.

13
mbuechmann

Kubernetes ne gère PAS nativement les mises à jour continues avec les migrations db. Ceci est spécifique à l'application, donc le développeur de l'application devra le gérer. Vous devrez peut-être faire les mêmes choses que vous feriez dans un environnement non k8s.

Quoi qu'il en soit, la façon dont je le ferais est:

  • Faites évoluer vos répliques à 1.
  • Mettez à jour l'image.
  • Faites évoluer vos répliques à 3.

Ce n'est pas infaillible mais n'implique pas de changement de code. Il y a une petite fenêtre entre l'étape db: migrate et l'écoute réelle du serveur où une demande ira à l'ancienne réplique (qui se terminera dès que la nouvelle réplique sera prête). Cette demande peut ou non échouer selon que le bloc de code est directement lié au changement de schéma.

Si je ne me souciais pas beaucoup des temps d'arrêt, j'utiliserais simplement la stratégie de recréation.

5
tselvan

Je résolvais ce problème récemment, et voici ma façon:

  • Utilisez annotations de déploiement pour stocker les commandes que vous devez normalement exécuter avant ou après le déploiement.
  • Créez un script qui pourra lire votre déploiement par son nom, puis créez un travail pour exécuter les commandes spécifiées dans les annotations de déploiement.
  • Lorsque vous poussez une image dans un registre Docker, ajoutez un webhook qui appellera votre script spécifié au point précédent.
  • Pour éviter les problèmes avec une structure de base de données incompatible:
    • Ne modifiez pas les colonnes db d'une manière incompatible en arrière.
    • Ne supprimez pas les colonnes inutilisées immédiatement dans vos migrations. Vous pouvez le faire dans la prochaine version. De cette façon, vous n'aurez qu'un seul script de migration à exécuter avant le déploiement.

P.S. Pour pouvoir travailler avec Kubernetes dans votre script, vous souhaiterez peut-être vous familiariser avec ces liens: API Kubernetes , Présentation de l'API Kubernetes , Accéder aux clusters à l'aide de la API Kubernetes , Bibliothèques clientes .

3
Denis V