Kubernetes est généralement décrit comme un système déclaratif. La plupart du temps, vous travaillez avec YAML qui définit l’état final du système. Cependant, Kubernetes prend également en charge les API impératives, qui permettent de lancer une commande et d’obtenir un résultat immédiat.
Dans cet article, nous allons explorer les différences entre ces deux formes de gestion d’objets. Il y a de fortes chances que vous ayez déjà utilisé les deux, même si vous ne reconnaissez pas les termes.
Déclaratif vs impératif : Définitions
Tout d’abord, il est utile d’examiner la terminologie.
Quelque chose de déclaratif fait une déclaration sur le résultat final, indiquant l’intention mais pas le processus pour y parvenir. Dans Kubernetes, cela revient à dire « Il devrait y avoir un ReplicaSet avec trois Pods ».
Un impératif agit comme une commande. Alors qu’une déclarative est passive, les impératifs sont actifs et immédiats : « Créez un ReplicaSet avec trois Pods. »
L’écosystème Kubernetes fournit des mécanismes pour interagir avec votre cluster sous l’une ou l’autre de ces formes. Les approches impératives sont prises en charge par des commandes CLI et des fichiers YAML individuels. La configuration déclarative est facilitée par des répertoires de fichiers qui sont combinés dans la représentation finale des ressources.
Gestion des objets de manière impérative
Voici un exemple de création d’un déploiement de manière impérative :
kubectl create deployment my-deployment –image my-image:latest
Vous donnez l’ordre à Kubernetes d’ajouter immédiatement un nouveau déploiement à votre cluster. La commande comprend un seul verbe (create) et le nom du type de ressource avec lequel vous travaillez (deployment).
Vous pouvez également écrire un fichier YAML et l’appliquer impérativement à l’aide de la commande create :
apiVersion : apps/v1
kind : Déploiement
spec :
réplicas : 3
sélecteur :
matchLabels :
app : exemple
modèle :
métadonnées :
labels :
app : exemple
spec :
# …
kubectl create -f deployment.yml
Comme précédemment, vous émettez une commande immédiate via un verbe actif. Kubernetes va prendre la configuration de votre fichier et créer les ressources correspondantes dans le cluster. Si vous devez mettre à jour une ressource, vous devez modifier votre YAML et utiliser la commande replace pour effectuer le changement :
kubectl replace -f deployment.yml
Cette opération supprimera la spec de toute ressource existante et la remplacera par la version de votre fichier de configuration. C’est ce qu’indique le nom de la commande replace. Cela signifie que vous perdrez toutes les modifications apportées à vos objets vivants qui ne sont pas présentes dans votre YAML.
Lorsque Kubernetes utilise des commandes impératives, il faut lui dire exactement ce qu’il doit faire. Par conséquent, il n’y a aucun moyen d’appliquer sélectivement les parties modifiées de votre YAML. Pour cela, vous devez passer à des opérations déclaratives.
Essayer la gestion déclarative
La gestion déclarative n’est disponible que lorsque vous utilisez des fichiers de configuration YAML. Il n’existe pas de commande déclarative. Lorsque vous utilisez des opérations déclaratives, vous ne dites pas à Kubernetes ce qu’il doit faire en fournissant un verbe (créer/remplacer). Au lieu de cela, vous utilisez la commande unique apply et vous faites confiance à Kubernetes pour déterminer les actions à effectuer.
kubectl apply -f deployment.yml
En continuant l’exemple de déploiement ci-dessus, appliquer le YAML ci-dessus à votre cluster agirait initialement de la même manière qu’une commande de création impérative. Aucune ressource correspondante n’existe au départ et Kubernetes doit donc en créer une nouvelle.
Vous pouvez ensuite modifier le champ « replicas » en 5 et répéter la commande apply. Cette fois, Kubernetes fera correspondre la ressource existante, détectera la modification de votre YAML et mettra à l’échelle le déploiement sans avoir d’impact sur les autres champs.
En utilisant l’approche impérative, vous devriez utiliser la commande kubectl scale pour modifier le nombre de répliques d’un déploiement existant. Si vous modifiez le YAML que vous avez utilisé avec kubectl create, vous devrez exécuter kubectl replace – mais cela remplacera la spécification complète du déploiement, au lieu de simplement mettre à l’échelle son nombre de répliques.
Déclaratif vs impératif : Comparaison des compromis
Les opérations impératives sont simples à comprendre et à raisonner. Chaque action est exprimée sous forme de verbe avec une conséquence clairement définie. C’est la raison pour laquelle la plupart des gens commenceront leurs premières interactions avec Kubernetes en utilisant des commandes impératives qui peuvent être vaguement mises en correspondance avec d’autres technologies telles que Docker.
La gestion déclarative expose la véritable puissance de Kubernetes. Vous déclarez à quoi doit ressembler l’état final, puis vous laissez Kubernetes faire le reste. Chaque commande a la même action impérative – appliquer cet ensemble de fichiers YAML et faire progresser le cluster vers l’état qu’ils définissent.
La gestion déclarative est idéale pour les déploiements automatisés. Vous n’avez pas besoin de passer du temps à élaborer un ensemble d’instructions de migration chaque fois que vous mettez à jour une ressource. Au lieu de cela, ajustez votre YAML afin qu’il produise des objets correctement configurés s’ils étaient créés à nouveau à l’heure actuelle. Kubernetes se chargera des mises à jour des objets existants afin qu’ils correspondent également au nouvel état.
Les fichiers YAML déclaratifs sont faciles à versionner, à réviser et à fusionner dans le cadre de votre système de contrôle des sources. Si vous utilisez des commandes impératives, vous n’avez aucun moyen de suivre l’évolution de votre cluster et il sera plus difficile de revenir à un état antérieur. Contrairement aux opérations impératives, les mises à jour déclaratives n’écrasent pas la totalité de l’objet. Vous conserverez donc les modifications apportées par d’autres mécanismes, indépendamment de vos fichiers YAML.
Néanmoins, la gestion impérative conserve certains avantages. La configuration déclarative ajoute des couches de complexité et peut être plus difficile à déboguer, en particulier lorsque Kubernetes choisit un mode d’action inattendu. Chaque modification entraîne une opération de fusion et de correction pour aligner vos objets sur l’état souhaité. Avec le modèle impératif, ce que vous demandez est ce que vous obtiendrez, sauf si une erreur se produit.
Comme toujours lorsque deux approches sont proposées, les deux stratégies sont utiles et celle que vous choisissez doit dépendre du contexte. Pour les clusters de production hébergeant des applications vivantes avec des changements fréquents, vous voulez probablement des fichiers YAML déclaratifs versionnés. Si vous créez rapidement de nouveaux conteneurs dans un cluster de développement, les commandes impératives vous feront gagner du temps et seront plus faciles à utiliser.
Conclusion
La gestion déclarative et impérative sont deux façons d’interagir avec votre cluster Kubernetes et ses ressources. Kubectl a intégré un support pour ces deux stratégies mais les techniques ne doivent pas être mélangées sur une base par objet. Si vous créez un objet de manière déclarative, il doit être géré de cette manière tout au long de sa vie – l’utilisation de commandes impératives avec lui peut conduire à un comportement inattendu.
Les opérations impératives affectent les objets vivants dans votre cluster. Vous définissez un verbe, une ressource et une configuration via les arguments et les drapeaux de la commande. La gestion déclarative est basée sur les modifications des fichiers de configuration locaux que Kubectl diffère et applique au cluster via des correctifs lorsque vous utilisez les commandes kubectl diff et kubectl apply.