Lors du déploiement d'un StatefulSet avec montage de volumes de disque, le démarrage de l'application peut échouer en raison de problèmes tels que des zones de disponibilité mal configurées ou des types de disque incompatibles. Cette rubrique fournit des recommandations de configuration pour les déploiements multi-zones afin de prévenir ces problèmes d'infrastructure et de minimiser les interruptions de mise en production.
Contexte
Les puissantes capacités d'orchestration de conteneurs de Kubernetes facilitent la construction d'applications avec état à grande échelle (StatefulSets). Toutefois, bien que Kubernetes simplifie le déploiement, il masque également le matériel sous-jacent. Cette abstraction peut entraîner des comportements inattendus si vous ne maîtrisez pas la topologie et les limitations de l'infrastructure sous-jacente.
Dans un cluster s'étendant sur plusieurs zones de disponibilité, un pod destiné à la zone de disponibilité A est planifié sur un nœud situé dans la zone de disponibilité B.
Une erreur se produit lors de la création d'un volume de disque, par exemple : l'approvisionnement dynamique d'un PV échoue avec l'erreur InvalidDataDiskCatagory.NotSupported.
Un pod ne parvient pas à monter un volume et renvoie l'erreur suivante :
The instanceType of the specified instance does not support this disk category.La planification d'un pod échoue et renvoie l'erreur suivante :
0/x node are available, x nodes had volume node affinity conflict.
Ces problèmes peuvent interrompre ou bloquer les mises en production d'applications. Cette rubrique propose des recommandations de configuration pour la haute disponibilité afin de réduire le risque de ces échecs.
Configurations
Objectifs de configuration
Pour les StatefulSets, nous recommandons d'utiliser des disques pour le stockage persistant. Par rapport au NAS, les disques offrent une stabilité supérieure et une meilleure bande passante de transfert de données.
Assurez-vous que le cluster s'étend sur plusieurs zones de disponibilité disposant de ressources de calcul et de stockage suffisantes pour répondre à la demande.
Le cluster doit pouvoir augmenter automatiquement le nombre de nœuds pour répondre aux besoins de planification lorsqu'une zone de disponibilité entière devient indisponible.
Utilisez une StorageClass haute disponibilité pour éviter les échecs de montage de disque.
Veillez à ce que les pods soient répartis uniformément sur les nœuds et les zones de disponibilité.
Configurations du pool de nœuds
-
Utilisez une seule zone de disponibilité par pool de nœuds.
Lorsque vous ajoutez une zone de disponibilité, créez un nouveau pool de nœuds dédié. Pour plus d'informations, consultez Créer et gérer un pool de nœuds.
Lors de la création des pools de nœuds, assurez-vous que chaque pool correspond à une zone de disponibilité différente. Utilisez les noms des pools de nœuds pour distinguer les zones de disponibilité.
-
Activez la mise à l'échelle automatique pour les pools de nœuds. Pour plus d'informations, consultez Activer la mise à l'échelle automatique des nœuds.
Si aucun nœud n'est disponible dans une zone de disponibilité, le système crée automatiquement un nouveau nœud dans cette zone pour planifier le pod, comme illustré dans le journal suivant.
Warning FailedScheduling 3m26s xxx 0/2 nodes are available: 2 node(s) had volume node affinity conflict. Warning FailedScheduling 3m26s xxx 0/2 nodes are available: 2 node(s) had volume node affinity conflict. Normal Scheduled 14s xxx Successfully assigned default/web-csi-available-test4-1 to cn-wulanchabu.172.xxx Warning FailedScheduling 86s xxx 0/3 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate, 2 node(s) had volume node affinity conflict. Warning FailedScheduling 76s xxx 0/3 nodes are available: 1 node(s) had taint {node.kubernetes.io/not-ready: }, that the pod didn't tolerate, 2 node(s) had volume node affinity conflict. Warning FailedScheduling 25s xxx 0/3 nodes are available: 3 node(s) had volume node affinity conflict. Normal TriggeredScaleUp 3m8s cluster-autoscaler pod triggered scale-up: [xxx 0->1 (max: 10)}] Normal NotTriggerScaleUp 2m39s cluster-autoscaler pod didn't trigger scale-up (it wouldn't fit if a new node is added): 1 can't increase node group size Normal TriggeredScaleUp 37s cluster-autoscaler pod triggered scale-up: [{xxx 1->2 (max: 10)}] Normal SuccessfulAttachVolume 15s attachdetach-controller AttachVolume.Attach succeeded for i3uqre" Warning FailedMount 9s (x3 over 11s) kubelet MountVolume.MountDevice failed for volume "xxx" : rpc error: code = Aborted desc = NodeStageVolume: Attach volume: d-xxx with error: rpc error: code = Aborted desc = NodeStageVolume: Previous attach action is still in process: d xxx Normal Pulling 3s kubelet Pulling image "nginx" -
Utilisez le même type d'instance ECS dans toutes les zones de disponibilité. Si cela n'est pas possible, optez pour des types d'instances qui prennent tous en charge les mêmes catégories de stockage par blocs.
Certains types de disque ne peuvent pas être montés sur certains types d'instance ECS. Même si un pod est planifié dans la bonne zone de disponibilité, son démarrage peut échouer en raison d'erreurs de montage de disque si le nœud ne prend pas en charge le type de disque demandé.
Configurez des taints pour tous les pools de nœuds afin d'empêcher la planification de charges de travail non désirées sur ces nœuds, ce qui pourrait impacter votre application. Lors de la création d'un pool de nœuds, configurez les taints de ses nœuds dans la section Taints. Par exemple, définissez la clé sur
app, la valeur surstset l'effet sur NoSchedule. Cela empêche la planification des pods sans tolérance correspondante sur les nœuds de ce pool.
Configurations du cluster
Assurez-vous que la version de votre cluster est 1.20 ou ultérieure.
Vérifiez que la version de votre plug-in CSI est 1.22 ou ultérieure. Pour plus d'informations, consultez Gérer le plug-in CSI.
-
Utilisez une StorageClass haute disponibilité.
L'exemple suivant présente la configuration YAML :
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: alicloud-disk-topology-alltype parameters: type: cloud_essd,cloud_ssd,cloud_efficiency provisioner: diskplugin.csi.alibabacloud.com reclaimPolicy: Delete volumeBindingMode: WaitForFirstConsumer allowVolumeExpansion: true allowedTopologies: - matchLabelExpressions: - key: topology.diskplugin.csi.alibabacloud.com/zone values: - cn-beijing-a - cn-beijing-bParamètres clés :
type: cloud_essd,cloud_ssd,cloud_efficiency: spécifie une liste priorisée de types de disque pour un mécanisme de secours. Le plug-in CSI tente de créer un disque en essayant les types spécifiés dans l'ordre : ESSD, SSD standard, puis ultra-disque. Cette approche prévient les échecs de démarrage des pods causés par un stock insuffisant pour un type de disque spécifique.volumeBindingMode: WaitForFirstConsumer: retarde la création du disque jusqu'à ce qu'un pod soit planifié sur un nœud spécifique. Cela garantit que le disque est créé dans la même zone de disponibilité que le nœud, évitant ainsi les échecs de démarrage dus à des incompatibilités de zone.allowedTopologies: restreint l'approvisionnement des volumes à des zones de disponibilité spécifiques. LorsquevolumeBindingModeest défini surWaitForFirstConsumer, le planificateur place les pods dans l'une des zones de disponibilité spécifiées, garantissant ainsi un approvisionnement réussi du disque.
Configurations de l'application
Le modèle suivant illustre une configuration standard de StatefulSet. Vous pouvez l'adapter selon vos besoins.
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: "mysql"
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
topologySpreadConstraints:
- labelSelector:
matchLabels:
app: mysql
maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: ScheduleAnyway
containers:
- image: mysql:5.6
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "mysql"
volumeMounts:
- name: disk-csi
mountPath: /var/lib/mysql
tolerations:
- key: "app"
operator: "Exists"
effect: "NoSchedule"
volumeClaimTemplates:
- metadata:
name: disk-csi
spec:
accessModes: [ "ReadWriteMany" ]
storageClassName: alicloud-disk-topology-alltype
resources:
requests:
storage: 40Gi
Paramètres clés :
topologySpreadConstraints: répartit les pods aussi uniformément que possible entre les différentes zones de disponibilité. Pour plus d'informations, consultez Contraintes de répartition topologique.volumeClaimTemplates: crée automatiquement le nombre requis de disques en fonction du nombre de réplicas, ce qui simplifie la mise à l'échelle.
Lorsqu'un PV est approvisionné dynamiquement, sa définition YAML inclut la zone de disponibilité du nœud. Par conséquent, le PV et son PVC lié ne peuvent être utilisés que par des pods planifiés dans cette même zone de disponibilité, ce qui garantit un montage réussi.
Références
Pour renforcer la sécurité des données de vos volumes de disque, consultez Meilleures pratiques pour la sécurité des données des volumes de disque.
Pour surveiller l'utilisation des disques en temps réel, consultez Vue d'ensemble de la surveillance du stockage des conteneurs.
Si un disque est plein ou si vous devez augmenter sa taille, consultez Étendre les volumes de disque.
Pour d'autres problèmes liés au montage de disque, consultez FAQ sur les volumes de disque.