Kubernetes — Comprendre les différentes options de scheduling

Yann
5 min readMar 28, 2019

--

Bien que Kubernetes soit bien plus qu’un simple orchestrateur de conteneurs, c’est la première chose qui nous vient à l’esprit quand on doit définir cette plateforme. Comment Kubernetes choisit de disposer les pods sur les nœuds et quelles sont les options de scheduling à notre disposition pour garantir au mieux la performance et la résilience de nos applications?

Cet article a pour but d’expliquer simplement les différentes règles de scheduling et n’a pas vocation à expliquer en détail la configuration des différentes options.

Le scheduler Kubernetes

Le scheduler est un processus faisant parti du master Kubernetes dont le rôle est de trouver un node pour chaque pod en attente de placement sur le cluster. L’algorithme de sélection de node est assez simple dans sa logique et se fait en 3 principales étapes:

  • Préalablement, il va trouver des affirmations pour filtrer les nœuds inappropriés. Par exemple, il va regarder si un node a les ressources (CPU/RAM) disponibles suffisantes pour faire fonctionner l’unité de travail concernée ou encore prendre en compte son état de santé.
  • Ensuite, avec cette liste filtrée de nœuds éligibles, le scheduler va déterminer un score de priorité en fonction de plusieurs paramètres comme par exemple, le nombre de ressources déjà consommées ou encore la présence ou non des images docker sur le node.
  • Pour finir, le nœud qui aura le plus haut score de priorité se verra accueillir le nouveau pod. En cas d’égalité de score, un des nodes sera choisi de manière aléatoire.

La majorité du temps, cette logique d’allocation garantit une qualité de service suffisante pour la plupart des applications et des entreprises. Cependant, il arrive souvent qu’il faille renseigner à Kubernetes des indications ou des contre-indications supplémentaires de placement afin d’améliorer les performances ou la résilience des services.

la liste complète des prédicats utilisés par le scheduler est documentée dans ce document: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduler_algorithm.md

Les options de scheduling avancées

Dans les sections suivantes, les bonhommes représentent des pods et les maisons représentent des nodes.

Affinité de pods

Dans le cas d’une affinité de pods, chaque unité indiquera au scheduler avec quelles autres charge de travail ils souhaitent faire collocation. Ce cas d’usage pourrait être utile pour consolider le plus possible les pods sur le cluster et ainsi éviter l’effet d’étalement naturel du scheduler. Cette fonctionnalité est peu utilisée par rapport aux autres options suivantes.

Anti-affinité de pods

C’est une option très intéressante pour forcer la dissémination des pods sur le cluster et ainsi augmenter la résilience et la performance des applications. Dans le cadre d’une maintenance ou une panne d’un des nodes, cette règle permet de s’assurer que un seul pod par application soit défaillant à la fois. En effet, même si l’algorithme de base du scheduler encourage la dispersion, il ne la garantit pas (cf. la dernière étape aléatoire du scheduler). Aussi, dans le cadre d’une application vorace en IOPS disque ou réseau, il est probablement préférable de l’isoler le plus possible des applications avec les mêmes exigences.

Affinité de nœud

Les charges de travail sur un cluster peuvent être très différentes les unes des autres. C’est pourquoi nous avons généralement besoin de varier les types de nœud dans un même cluster. Par exemple, une application de machine learning aura besoin d’une carte graphique pour fonctionner de manière performante, à l’instar d’une base de données qui aura, elle, besoin d’un SSD. Pour cela, nous allons appliquer aux nodes spécialisés en machine learning ou base de données des labels les caractérisants plus précisément:

diskType=ssd
graphics=yes
color=blue
etc...

Après les nodes correctement étiquetés, on peut renseigner les paramètres d’affinité de nœud sur les pods. Le scheduler prendra en compte cette contrainte dans la première étape de filtrage des nodes.

Les taints

Les taints sont des caractéristiques à appliquer sur des nodes et qui empêchent tout pod d’être placé dessus sans avoir été vacciné au préalable. Ces attributs permettent de réserver les ressources du nœud pour des pods spécifiques et tolérants aux particularités répulsives. Par exemple, il est courant de réserver un node spécifique pour le monitoring Prometheus afin qu’il n’impacte pas les performances des autres pods du cluster. Dans ce cas, on va lui appliquer une toleration.

Les tolerations

Les tolerations sont des attributs à appliquer aux pods et qui définissent leur tolérance à être placé sur un node infecté par un taint. C’est en quelque sorte une vaccination. La tolérance n’est pas une affinité de noeud, il faut utiliser ces deux concepts (toleration et node affinity) en parallèle pour réserver un node à un seul pod.

Conclusion

Même si le comportement du scheduler par défaut convient à la plupart des cas d’usage, il est souvent nécessaire de définir des règles de placement personnalisées afin de garantir au mieux le fonctionnement des pods du cluster. Kubernetes ne manque pas d’options à ce niveau là et la version 1.14 apporte encore d’autres possibilités comme les pod priority ou encore les preemption qui permettent de garantir un placement sur des pods de haute importance, quitte à libérer de la place en supprimant les pods moins primordiaux.

Sources

--

--

Yann

Head of innovation @SKALE-5. #Kubernetes #Golang