J'ai une application basée sur Kubernetes consistant en plusieurs services (et pods) gérés avec un graphique de barre.
Postgres est utilisé comme base de données pour tous les services.
Lorsque l'application est mise à niveau vers une version plus récente, j'exécute un script de migration de base de données via initContainers
.
Le problème se produit lorsque les scripts de migration nécessitent un accès exclusif à la base de données (toutes les autres connexions doivent être terminées), sinon le script est bloqué.
La solution idéale serait d’arrêter tous les pods, d’effectuer la migration et de les recréer. Mais je ne sais pas comment y parvenir correctement avec Kubernetes.
Tnx
La solution idéale serait d’arrêter tous les pods, d’effectuer la migration et de Les recréer. Mais je ne sais pas comment y parvenir correctement avec Kubernetes.
Dans l'un des commentaires, je vois que vous utilisez Helm. J'aimerais donc proposer une solution utilisant les crochets de Helm:
Helm fournit un mécanisme de raccordement permettant aux développeurs de graphiques d'intervenir À certains moments du cycle de vie d'une publication. Par exemple, vous pouvez utiliser les crochets Pour:
Chargez un ConfigMap ou un secret lors de l’installation avant que tous les autres graphiques ne soient chargés.
Exécutez un travail pour sauvegarder une base de données avant d'installer un nouveau graphique , Puis exécutez un deuxième travail après la mise à niveau afin de restaurer les données.
Exécutez un Job avant de supprimer une version pour supprimer gracieusement un service Avant de le supprimer.
https://github.com/kubernetes/helm/blob/master/docs/charts_hooks.md
Vous pouvez créer un package pour votre migration sous la forme k8s Job
et utiliser le pointeur pre-install
ou pre-upgrade
pour exécuter le travail. Ces points d'ancrage sont exécutés après le rendu des modèles, mais avant la création de nouvelles ressources dans Kubernetes. Ainsi, vos migrations seront exécutées avant le déploiement de vos pods.
Pour supprimer les déploiements avant d'exécuter vos migrations, créez un deuxième hook de pré-installation/pré-mise à niveau avec un helm.sh/hook-weight
inférieur qui supprime les déploiements cibles:
apiVersion: batch/v1
kind: Job
metadata:
name: "pre-upgrade-hook1"
annotations:
"helm.sh/hook": pre-upgrade
"helm.sh/hook-weight": "-1"
"helm.sh/hook-delete-policy": hook-succeeded
spec:
template:
metadata:
name: "pre-upgrade-hook1"
spec:
restartPolicy: Never
serviceAccountName: "<an SA with delete RBAC permissions>"
containers:
- name: kubectl
image: "lachlanevenson/k8s-kubectl:latest"
command: ["delete","deployment","deploy1","deploy2"]
Le poids de crochet inférieur garantit que ce travail est exécuté avant le travail de migration. Cela assurera la série d'événements suivante:
helm upgrade
Assurez-vous simplement de conserver tous les déploiements pertinents dans le même graphique.
Du point de vue de l’automatisation/orchestration, j’ai le sentiment que de tels problèmes doivent être résolus avec des opérateurs, à l’aide de la version récemment publiée de l’opérateur:
https://github.com/operator-framework
L'idée est qu'il y aurait un opérateur Postgres Migrations - qui, à ma connaissance, n'existe pas encore - et qui resterait inactif dans l'attente d'une définition de ressource personnalisée décrivant la migration à publier dans le cluster/espace de noms.
L'opérateur se réveillerait, comprendrait les implications de la migration envisagée, effectuerait une analyse sur le cluster pour élaborer un plan de migration, puis suivrait les étapes décrites.
Cela ne vous aide pas maintenant, cependant.
La solution idéale serait d’arrêter tous les pods, d’effectuer la migration et de Les recréer. Mais je ne sais pas comment y parvenir correctement avec Kubernetes.
Cela dépend en grande partie de votre approche, en particulier de vos outils CI/CD. Vous pouvez appliquer plusieurs stratégies, mais à titre d’exemple, en supposant que vous disposiez d’un pipeline Gitlab (Jenkins pourrait faire de même, la terminologie est différente, etc.), voici les étapes:
Ce même principe peut également être appliqué à d'autres outils d'orchestration/de déploiement, et vous pouvez même créer un simple script pour exécuter ces commandes kubectl directement en une fois si la précédente a abouti.