Un peu de vocabulaire pour commencer ! Bon bien comprendre cet article, nous devons parler le même langage, les concepts essentiels sont présentés ci-dessous :
Demandes (Requests) et Limites
Les classes de qualité de service des pods (QoS Classes).
Maintenant que nous savons ce que sont les requests/limites et que celles-ci définissent la QoS Class des pods, nous allons étudier le processus d'expulsion.
Lorsqu'un nœud atteint sa limite de disque ou de mémoire, un flag est mis sur le nœud Kubernetes pour indiquer qu'il est sous pression. Ce flag bloque également une nouvelle allocation de pod sur ce nœud, et suite à cela, un processus d'éviction est lancé pour libérer certaines ressources afin d’alléger la charge sur le nœud.
C'est le Kubelet du nœud sous pression qui s'occupera du processus d'expulsion. Celui-ci commencera à expulser des pods jusqu'à ce que les ressources utilisées du nœud soient inférieures au seuil d'éviction. Lorsque le Kubelet expulse un pod, il met fin à tous les conteneurs du pod et passe son statut en “Failed”.
Si le pod expulsé est géré par un deployment, le deployment crée un autre pod à déployer (schedule) par Kubernetes.
La première chose que le Kubelet fera sera de libérer du disque en supprimant les pods qui ne sont pas en cours d'exécution et leurs images (quick win). Ensuite, si le nettoyage du disque ne suffit pas, le Kubelet lancera une éviction des pods dans un ordre défini par leur QoS Class :
Quant aux pods ”Guaranteed”, ils sont (en théorie) à l’abri d’une expulsion.
Par exemple, prenons un nœud qui a des problèmes de CPU. Si un Pod a une request sur la ressource CPU et utilise la moitié de sa request CPU, il sera expulsé après un pod avec une request sur la ressource CPU mais qui utilise plus que sa requête.
Le plus important :
Vous l'aurez compris, il est impératif de définir correctement les requests et les limites sur vos pods.
Pour commencer, vous pouvez utiliser les QoS classes suivantes en fonction de la criticité de vos applications :
Il y a quelques mois, mon pod de serveur Prometheus s’est fait expulser. En jetant un coup d'œil aux événements du Pod, j’ai vu le message suivant :
Message: The node was low on resource: memory. Container prometheus-server was using 2890108Ki, which exceeds its request of 2000Mi.
Voici les requests configurées sur ce pod :
$ k describe pods prometheus-server-5c949c44f7-rc9sv | grep -iA2 Requests
Requests
cpu: 500m
memory: 2000Mi
Eh bien, il n'est pas choquant que le Pod consomme plus que sa demande de mémoire. Le problème survient quand, dans le cas où le nœud sur lequel tourne le Pod est en difficulté avec sa mémoire (ce qui est mon cas ici), alors le Pod se fait expulser assez rapidement, juste après ceux en Best Effort.
Si vous voulez en savoir plus sur le processus d'expulsion, je vous encourage à lire la documentation officielle de Kubernetes, qui explique plus en détail le comportement des nœuds pression.
Cette documentation couvre les signaux d'expulsion, le seuil d'expulsion, etc.