doc-locale/fr-fr/administration/gitaly/kubernetes.md
{{< details >}}
{{< /details >}}
{{< history >}}
{{< /history >}}
L'exécution de Gitaly sur Kubernetes implique des compromis en termes de disponibilité. Tenez compte de ces compromis lors de la planification d'un environnement de production et définissez les attentes en conséquence. Ce document décrit et fournit des conseils sur la façon de minimiser et de planifier les limitations existantes.
Gitaly sur Kubernetes a été évalué par l'équipe Gitaly et jugé comme étant un moyen sûr de déployer Gitaly. Le reste de ce document présente les meilleures pratiques pour ce faire.
Gitaly sur Kubernetes est en disponibilité générale depuis GitLab 18.11. GitLab ne garantit pas la compatibilité avec des offres Kubernetes gérées spécifiques de fournisseurs cloud (tels qu'Amazon EKS, Google GKE ou Azure AKS). Vous devez valider votre environnement spécifique avant de déployer en production.
Par conception, Gitaly (non-Cluster) est un service à point unique de défaillance (SPoF). Les données sont sourcées et servies à partir d'une instance unique. Pour Kubernetes, lorsque le pod StatefulSet est remplacé (par exemple, lors de mises à niveau, de maintenance de nœud ou d'éviction), le remplacement provoque une interruption de service pour les données servies par le pod ou l'instance.
Dans une configuration Cloud Native Hybrid (Gitaly VM), le paquet Linux (Omnibus) masque le problème en :
La même approche ne convient pas à un cycle de vie basé sur des conteneurs, où un conteneur ou un pod doit s'arrêter complètement et démarrer en tant que nouveau conteneur ou pod.
Gitaly Cluster (Praefect) résout l'aspect de haute disponibilité des données et du service en répliquant les données entre les instances. Cependant, Gitaly Cluster (Praefect) ne convient pas pour s'exécuter dans Kubernetes en raison des problèmes existants et des contraintes de conception qui sont amplifiés par une plateforme basée sur des conteneurs.
Pour prendre en charge un déploiement Cloud Native, Gitaly (non-Cluster) est la seule option. En tirant parti des bonnes fonctionnalités et configurations de Kubernetes et de Gitaly, vous pouvez minimiser les interruptions de service et offrir une bonne expérience utilisateur.
Les informations sur cette page supposent :
1.29.runc du nœud Kubernetes égale ou supérieure à 1.1.9.systemd est prise en charge (valeur par défaut de Kubernetes)./sys/fs/cgroup.init-cgroups) aux permissions du système de fichiers de l'utilisateur root sur /sys/fs/cgroup. Utilisé pour déléguer le cgroup du pod au conteneur Gitaly (utilisateur git, UID 1000).nsdelegate. Pour plus d'informations, consultez le ticket Gitaly 6480.Lors de l'exécution de Gitaly dans Kubernetes, vous devez :
cgroup_writable dans containerd {#enable-cgroup_writable-field-in-containerd}La prise en charge des cgroups dans Gitaly nécessite un accès en écriture aux cgroups pour les conteneurs non privilégiés. containerd v2.1.0 a introduit l'option de configuration cgroup_writable. Lorsque cette option est activée, elle garantit que le système de fichiers cgroups est monté avec des permissions de lecture/écriture.
Pour activer ce champ, effectuez les étapes suivantes sur les nœuds où Gitaly sera déployé. Si Gitaly est déjà déployé, les pods doivent être recréés après la modification de la configuration.
Modifiez le fichier de configuration containerd situé à /etc/containerd/config.toml pour inclure le champ cgroup_writable :
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
cgroup_writable = true
Redémarrez les services Kubelet et containerd :
sudo systemctl restart kubelet
sudo systemctl restart containerd
Ces commandes peuvent marquer le nœud comme NotReady si les services mettent un certain temps à redémarrer.
Un pod peut être remplacé pour de nombreuses raisons. Comprendre et planifier le cycle de vie du service aide à minimiser les perturbations.
Par exemple, avec Gitaly, un StatefulSet Kubernetes effectue une rotation lors des modifications de l'objet spec.template, ce qui peut se produire lors des mises à niveau du Helm Chart (labels ou tags d'image) ou des mises à jour des demandes ou limites de ressources du pod.
Cette section se concentre sur les cas courants de perturbation des pods et sur la manière de les gérer.
Étant donné que le service n'est pas hautement disponible, certaines opérations peuvent provoquer de brèves interruptions de service. La planification de fenêtres de maintenance signale les perturbations de service potentielles et aide à définir les attentes. Vous devez utiliser des fenêtres de maintenance pour :
PriorityClass {#use-priorityclass}Utilisez PriorityClass pour attribuer aux pods Gitaly une priorité plus élevée par rapport aux autres pods, afin d'aider à gérer la pression de saturation des nœuds, la priorité d'éviction et la latence de planification :
Créez une classe de priorité :
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: gitlab-gitaly
value: 1000000
globalDefault: false
description: "GitLab Gitaly priority class"
Attribuez la classe de priorité aux pods Gitaly :
gitlab:
gitaly:
priorityClassName: gitlab-gitaly
Les outils de mise à l'échelle automatique des nœuds ajoutent et suppriment des nœuds Kubernetes selon les besoins pour planifier les pods et optimiser les coûts.
Lors des événements de réduction d'échelle, le pod Gitaly peut être évincé pour optimiser l'utilisation des ressources. Des annotations sont généralement disponibles pour contrôler ce comportement et exclure des charges de travail. Par exemple, avec Cluster Autoscaler :
gitlab:
gitaly:
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: "false"
L'utilisation des ressources du service Gitaly peut être imprévisible en raison de la nature indéterminable des opérations Git. Tous les dépôts ne sont pas identiques et la taille influence fortement les performances et l'utilisation des ressources, en particulier pour les monorepos.
Dans Kubernetes, une utilisation non contrôlée des ressources peut entraîner des événements Out Of Memory (OOM), ce qui force la plateforme à terminer le pod et à arrêter tous ses processus. La terminaison d'un pod soulève deux préoccupations importantes :
Cette section se concentre sur la réduction de la portée de l'impact et la protection du service dans son ensemble.
L'isolation des processus Git garantit qu'un seul appel Git ne peut pas consommer toutes les ressources du service et du pod.
Gitaly peut utiliser les Control Groups Linux (cgroups) pour imposer des quotas d'utilisation des ressources plus petits, par dépôt.
Vous devez maintenir les quotas cgroup en dessous de l'allocation globale des ressources du pod. Le CPU n'est pas critique car il ne fait que ralentir le service. Cependant, la saturation de la mémoire peut entraîner la terminaison du pod. Un tampon mémoire de 1 Gio entre la demande du pod et l'allocation cgroup Git est un bon point de départ. Le dimensionnement du tampon dépend des schémas de trafic et des données du dépôt.
Par exemple, avec une demande de mémoire de pod de 15 Gio, 14 Gio sont alloués aux appels Git :
gitlab:
gitaly:
cgroups:
enabled: true
# Total limit across all repository cgroups, excludes Gitaly process
memoryBytes: 15032385536 # 14GiB
cpuShares: 1024
cpuQuotaUs: 400000 # 4 cores
# Per repository limits, 50 repository cgroups
repositories:
count: 50
memoryBytes: 7516192768 # 7GiB
cpuShares: 512
cpuQuotaUs: 200000 # 2 cores
Pour plus d'informations, consultez la documentation de configuration de Gitaly.
Le dimensionnement du pod Gitaly est critique et les architectures de référence fournissent quelques conseils comme point de départ. Cependant, les différents dépôts et les modèles d'utilisation consomment des degrés variables de ressources. Vous devez surveiller l'utilisation des ressources et l'ajuster en conséquence au fil du temps.
La mémoire est la ressource la plus sensible dans Kubernetes car un manque de mémoire peut déclencher la terminaison du pod. L'isolation des appels Git avec les cgroups aide à restreindre l'utilisation des ressources pour les opérations sur les dépôts, mais cela n'inclut pas le service Gitaly lui-même. Conformément à la recommandation précédente sur les quotas cgroup, ajoutez un tampon entre l'allocation mémoire cgroup Git globale et la demande de mémoire du pod pour améliorer la sécurité.
Une classe Guaranteed de qualité de service du pod est préférable (les demandes de ressources correspondent aux limites). Avec ce paramètre, le pod est moins susceptible d'être affecté par la contention des ressources et ne sera jamais évincé en raison de la consommation d'autres pods.
Exemple de configuration des ressources :
gitlab:
gitaly:
resources:
requests:
cpu: 4000m
memory: 15Gi
limits:
cpu: 4000m
memory: 15Gi
init:
resources:
requests:
cpu: 50m
memory: 32Mi
limits:
cpu: 50m
memory: 32Mi
Vous pouvez utiliser des limites de concurrence pour aider à protéger le service contre les schémas de trafic anormaux. Pour plus d'informations, consultez la documentation de configuration de la concurrence et comment surveiller les limites.
Lors de l'exécution de plusieurs pods Gitaly, vous devez les planifier sur différents nœuds pour répartir le domaine de défaillance. Cela peut être appliqué à l'aide de l'anti-affinité des pods. Par exemple :
gitlab:
gitaly:
antiAffinity: hard
Cette section couvre les domaines d'optimisation pour réduire les temps d'arrêt lors d'événements de maintenance ou d'événements d'infrastructure non planifiés, en réduisant le temps nécessaire au pod pour commencer à servir le trafic.
À mesure que la taille des données augmente (historique Git et davantage de dépôts), le pod prend de plus en plus de temps à démarrer et à devenir prêt.
Lors de l'initialisation du pod, dans le cadre du montage du volume persistant, les permissions du système de fichiers et la propriété sont explicitement définies sur le uid et le gid du conteneur. Cette opération s'exécute par défaut et peut considérablement ralentir le temps de démarrage du pod car les données Git stockées contiennent de nombreux petits fichiers.
Ce comportement est configurable avec l'attribut fsGroupChangePolicy. Utilisez cet attribut pour effectuer l'opération uniquement si le uid ou le gid racine du volume ne correspond pas aux spécifications du conteneur :
gitlab:
gitaly:
securityContext:
fsGroupChangePolicy: OnRootMismatch
Le pod Gitaly commence à servir le trafic une fois que la sonde de disponibilité réussit. Les délais de sonde par défaut sont conservateurs pour couvrir la plupart des cas d'utilisation. La réduction de l'attribut readinessProbe initialDelaySeconds déclenche les sondes plus tôt, ce qui accélère la disponibilité du pod. Par exemple :
gitlab:
gitaly:
statefulset:
readinessProbe:
initialDelaySeconds: 2
periodSeconds: 10
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
Par défaut, lors de la terminaison, Gitaly accorde un délai d'attente de 1 minute pour que les requêtes en cours se terminent. Bien que bénéfique à première vue, ce délai d'attente :
Une meilleure approche dans un déploiement basé sur des conteneurs consiste à s'appuyer sur la logique de nouvelle tentative côté client. Vous pouvez reconfigurer le délai d'attente en utilisant le champ gracefulRestartTimeout. Par exemple, pour accorder un délai d'arrêt progressif de 1 seconde :
gitlab:
gitaly:
gracefulRestartTimeout: 1
Surveillez régulièrement l'utilisation du disque pour les conteneurs Gitaly à longue durée d'exécution, car la croissance des fichiers journaux peut causer des problèmes de stockage si la rotation des journaux n'est pas activée.
Pour migrer les dépôts existants depuis des nœuds Gitaly non-Kubernetes vers Gitaly sur Kubernetes :
Chaque dépôt est mis en lecture seule pendant toute la durée du déplacement et n'est pas accessible en écriture jusqu'à ce que le déplacement soit terminé.