19 Bonnes Pratiques Kubernetes Pour Des Clusters Efficaces

Introduction

Kubernetes offre un niveau de flexibilité extraordinaire pour orchestrer un grand cluster de conteneurs distribués.

Le grand nombre de fonctionnalités et d’options disponibles peut présenter un défi. L’application des meilleures pratiques vous aide à éviter les obstacles potentiels et à créer un environnement sécurisé et efficace dès le départ.

Utilisez les meilleures pratiques Kubernetes décrites pour créer des conteneurs optimisés, rationaliser les déploiements, administrer des services fiables et gérer un cluster complet.

Sécuriser Et Optimiser Les Conteneurs

Les conteneurs offrent beaucoup moins d’isolation que les machines virtuelles. Vous devez toujours vérifier les images de conteneur et maintenir un contrôle strict sur les autorisations des utilisateurs.

L’utilisation de petites images de conteneurs améliore l’efficacité, préserve les ressources et réduit la surface d’attaque pour les attaquants potentiels.

Utiliser Uniquement Des Images De Conteneurs De Confiance

Les images de conteneurs prêtes à l’emploi sont hautement accessibles et exceptionnellement utiles. Cependant, les images publiques peuvent rapidement devenir obsolètes, contenir des exploits, des bogues ou même des logiciels malveillants qui se propagent rapidement dans un cluster Kubernetes.

N’utilisez que des images provenant de référentiels de confiance et analysez toujours les images à la recherche de vulnérabilités potentielles. De nombreux outils en ligne, tels que Anchore ou Clair, fournissent une analyse statique rapide des images de conteneurs et vous informent des menaces et problèmes potentiels. Passez quelques instants à analyser les images de conteneurs avant de les déployer et évitez les conséquences potentiellement désastreuses.

Utilisateurs Non Root Et Systèmes De Fichiers En Lecture Seule

Modifiez le contexte de sécurité intégré pour forcer tous les conteneurs à s’exécuter uniquement avec des utilisateurs non root et avec un système de fichiers en lecture seule.

Évitez d’exécuter des conteneurs en tant qu’utilisateur racine. Une faille de sécurité peut rapidement s’aggraver si un utilisateur peut s’accorder des autorisations supplémentaires.

Si un système de fichiers est défini en lecture seule, il y a peu de chance de falsifier le contenu du conteneur. Au lieu de modifier les fichiers système, le conteneur entier devrait être supprimé et un nouveau mis à sa place.

Remarque : Découvrez les conteneurs Docker Privileged et pourquoi vous ne devriez pas les exécuter.

Créer Des Images Petites Et Superposées

Les petites images accélèrent vos constructions et nécessitent moins de stockage. La superposition efficace d’une image peut réduire considérablement la taille de l’image. Essayez de créer vos images à partir de zéro pour obtenir des résultats optimaux.

Utilisez plusieurs instructions FROM dans un seul Dockerfile si vous avez besoin de nombreux composants différents. Cette fonctionnalité crée des sections, chacune faisant référence à une image de base différente. L’image finale ne stocke plus les couches précédentes, uniquement les composants dont vous avez besoin de chacune, ce qui rend le conteneur Docker beaucoup plus mince.

Chaque couche est extraite en fonction de la commande FROM située dans le conteneur déployé.

Limiter L’accès Des Utilisateurs Avec RBAC

Le contrôle d’accès basé sur les rôles (RBAC) garantit qu’aucun utilisateur ne dispose de plus d’autorisations que nécessaire pour accomplir ses tâches. Vous pouvez activer RBAC en ajoutant l’indicateur suivant lors du démarrage du serveur d’API :

-authorization-mode=RBAC

RBAC utilise le groupe d’API rbac.authorization.k8s.io pour piloter les décisions d’autorisation via l’API Kubernetes.

Remarque : Conservez les secrets et les mots de passe isolés de vos images de conteneur. Un utilisateur disposant des autorisations pour créer des pods dans un espace de noms peut utiliser ce rôle pour créer un pod et accéder aux cartes de configuration ou aux secrets.

Journaux Stdout Et Stderr

Il est courant d’envoyer les journaux d’application au flux stdout (sortie standard) et les journaux d’erreurs au flux stderr (erreur standard). Une fois qu’une application écrit sur stdout et stderr, un moteur de conteneur, comme Docker, redirige et stocke les enregistrements dans un fichier JSON.

Les conteneurs, pods et nœuds Kubernetes sont des entités dynamiques. Les journaux doivent être cohérents et disponibles en permanence. Il est donc recommandé de conserver vos journaux à l’échelle du cluster dans un système de stockage principal distinct.

Kubernetes peut être intégré à une large gamme de solutions de journalisation existantes, telles que la pile ELK.

Rationalisez Les Déploiements

Un déploiement Kubernetes établit un modèle qui garantit que les pods sont opérationnels, régulièrement mis à jour ou annulés comme défini par l’utilisateur.

L’utilisation d’étiquettes, d’indicateurs, de conteneurs liés et de DaemonSets clairs peut vous donner un contrôle précis sur le processus de déploiement.

Utilisation Du Drapeau D’enregistrement

Lorsque vous ajoutez l’ indicateur -record , la commande kubectl exécutée est stockée sous forme d’annotation.

Revenez à n’importe quelle révision en déclarant le numéro de révision dans la commande d’annulation.

déploiement de kubectl annuler le déploiement example-deployment -to-revision=1

Sans l’ indicateur -record , il serait difficile d’identifier la révision spécifique.

Étiquettes Descriptives

Essayez d’utiliser autant d’étiquettes descriptives que possible. Les étiquettes sont des paires clé:valeur qui permettent aux utilisateurs de regrouper et d’organiser les pods en sous-ensembles significatifs. La plupart des fonctionnalités, plugins et solutions tierces ont besoin d’étiquettes pour pouvoir identifier les pods et contrôler les processus automatisés.

Par exemple, les DaemonSets Kubernetes dépendent des libellés et des sélecteurs de nœuds pour gérer le déploiement des pods au sein d’un cluster.

Créer Plusieurs Processus Dans Un Pod

Utilisez les capacités de liaison de conteneurs de Kubernetes au lieu d’essayer de résoudre tous les problèmes à l’intérieur d’un conteneur. Il déploie efficacement plusieurs conteneurs sur un seul pod Kubernetes. Un bon exemple est l’externalisation des fonctionnalités de sécurité vers un conteneur proxy side -car .

Un conteneur couplé peut prendre en charge ou améliorer les fonctionnalités de base du conteneur principal ou aider le conteneur principal à s’adapter à son environnement de déploiement.

Utiliser Des Conteneurs D’initialisation

Un ou plusieurs conteneurs d’initialisation effectuent généralement des tâches utilitaires ou des contrôles de sécurité que vous ne souhaitez pas inclure dans le conteneur d’application principal. Vous pouvez utiliser des conteneurs init pour vous assurer qu’un service est prêt avant de lancer le conteneur principal du pod.

Chaque conteneur d’initialisation doit s’exécuter avec succès jusqu’à la fin avant que le conteneur d’initialisation suivant ne démarre. Les conteneurs d’initialisation peuvent retarder l’apparition du conteneur principal du pod jusqu’à ce qu’une condition préalable soit satisfaite. Sans cette condition préalable, Kubernetes redémarre le pod. Une fois la condition préalable remplie, le conteneur init s’arrête automatiquement et permet au conteneur principal de démarrer.

Évitez D’utiliser La Dernière Balise

Évitez d’utiliser aucune balise ou la balise :latest lors du déploiement de conteneurs dans un environnement de production. La dernière balise rend difficile la détermination de la version de l’image en cours d’exécution.

Un moyen efficace de s’assurer que le conteneur utilise toujours la même version de l’image consiste à utiliser le résumé d’image unique comme balise. Dans cet exemple, une version d’image Redis est déployée à l’aide de son condensé unique :

Kubernetes ne met pas automatiquement à jour la version de l’image, sauf si vous modifiez la valeur de condensé.

Configurer Les Sondes De Préparation Et De Vivacité

Les sondes de vivacité  et  de préparation aident Kubernetes à surveiller et à interpréter la santé de vos applications. Si vous définissez un contrôle de vivacité et qu’un processus répond aux exigences, Kubernetes arrête le conteneur et démarre une nouvelle instance pour le remplacer.

Les sondes de préparation effectuent des audits au niveau du pod et évaluent si un pod peut accepter le trafic. Si un pod ne répond pas, une sonde de préparation déclenche un processus pour redémarrer le pod.

Remarque : Il est recommandé de configurer un délai lors de la configuration des sondes de préparation. Les fichiers de configuration volumineux peuvent prendre un certain temps à se charger. Une sonde de préparation peut arrêter le pod avant qu’il ne parvienne à se charger, déclenchant une boucle de redémarrage.

La documentation relative à la configuration des sondes de préparation et de vivacité est disponible sur le site Web officiel de Kubernetes.

Essayez Différents Types De Services

Ports Statiques Avec NodePort

Exposez les pods aux utilisateurs externes en définissant le type de service sur NodePort. Si vous spécifiez une valeur dans le champ nodePort , Kubernetes réserve ce numéro de port sur tous les nœuds et transfère tout le trafic entrant destiné aux pods qui font partie du service. Le service est accessible en utilisant à la fois l’IP interne du cluster et l’IP du nœud avec le port réservé.

Les utilisateurs peuvent contacter le service NodePort depuis l’extérieur du cluster en demandant :

NodeIP:NodePort

Utilisez toujours un numéro de port dans la plage configurée pour NodePort (30000-32767). Si une transaction d’API échoue, vous devrez résoudre les éventuelles collisions de ports.

Ingress Vs LoadBalancer

Le type LoadBalancer expose les services en externe à l’aide de l’équilibreur de charge de votre fournisseur. Chaque service que vous exposez à l’aide du type LoadBalancer reçoit son adresse IP. Si vous disposez de nombreux services, vous pouvez rencontrer des coûts supplémentaires imprévus en fonction du nombre de services exposés.

Qu’est-ce qu’une entrée ? Une entrée vous permet d’exposer plusieurs services extérieurs au cluster à des services au sein du cluster, à l’aide d’une seule adresse IP. L’entrée n’est pas un type de service, mais est positionnée pour acheminer le trafic vers plusieurs services et agir comme un point d’entrée unique pour votre service. Les contrôleurs d’entrée fournissent un ensemble de fonctionnalités qui vous permettent de configurer un sous-domaine et un routage basé sur le chemin vers les services principaux.

Une exigence de configuration standard consiste à fournir un contrôleur d’entrée avec une adresse IP publique statique existante. L’adresse IP publique statique reste si le contrôleur d’entrée est supprimé. Cette approche vous permet d’utiliser les enregistrements DNS et les configurations réseau actuels de manière cohérente tout au long du cycle de vie de vos applications.

Mapper Des Services Externes à Un DNS

Le type ExternalName ne mappe pas les services à un sélecteur mais utilise un nom DNS à la place. Utilisez le paramètre externalName pour mapper les services à l’aide d’un enregistrement CNAME. Un enregistrement CNAME est un nom de domaine complet et non une adresse IP numérique.

Les clients qui se connectent au service vont contourner le proxy de service et se connecter directement à la ressource externe. Dans cet exemple, le service pnap est mappé à la ressource externe admin.phoenixnap.com .

L’accès au service pnap fonctionne de la même manière qu’avec les autres services. La différence cruciale est que la redirection se produit désormais au niveau du DNS.

Conception D’applications

Le déploiement automatisé de conteneurs avec Kubernetes garantit que la plupart des opérations s’exécutent désormais sans intervention humaine directe. Concevez vos applications et vos images de conteneurs de manière à ce qu’elles soient interchangeables et ne nécessitent pas une microgestion constante.

Accent Mis Sur Les Services Individuels

Essayez de diviser votre application en plusieurs services et évitez de regrouper trop de fonctionnalités dans un seul conteneur. Il est beaucoup plus facile de redimensionner les applications horizontalement et de réutiliser les conteneurs s’ils se concentrent sur une seule fonction.

Lors de la création de vos applications, partez du principe que vos conteneurs sont des entités à court terme qui vont être arrêtées et redémarrées régulièrement.

Remarque : Kubernetes est un outil d’automatisation, et vos images ne doivent pas dépendre d’une gestion ou d’une saisie manuelle une fois déployées. Les conteneurs sont immuables et ne doivent pas être modifiés mais redémarrés à partir de l’image de base.

Utiliser Les Cartes Helm

Helm, le gestionnaire de packages d’applications Kubernetes, peut rationaliser le processus d’installation et déployer très rapidement des ressources dans l’ensemble du cluster. Les packages de l’application Helm sont appelés Charts.

Des applications comme MySQL, PostgreSQL, MongoDB, Redis, WordPress sont des solutions en demande. Au lieu de créer et de modifier plusieurs fichiers de configuration complexes, vous pouvez déployer des Helm Charts facilement disponibles.

Utilisez la commande suivante pour créer les déploiements, services, PersistentVolumeClaims et secrets nécessaires pour exécuter le gestionnaire Kafka sur votre cluster.

helm install -name mon-messenger stable/kafka-manager

Vous n’avez plus besoin d’analyser des composants spécifiques et d’apprendre à les configurer pour exécuter correctement Kafka.

Si vous débutez avec Helm, consultez nos guides Comment installer Helm sur Ubuntu, Mac et Windows et Comment ajouter ou mettre à jour Helm Repo. Et si vous voulez en savoir plus ou comparer Helm avec d’autres outils, consultez notre article Helm vs Kustomize.

Utiliser L’affinité De Nœud Et De Pod

La fonction d’affinité est utilisée pour définir à la fois l’affinité de nœud et l’affinité inter-pod. L’affinité de nœud vous permet de spécifier les nœuds sur lesquels un pod peut être planifié à l’aide d’étiquettes de nœud existantes.

  • requiredDuringSchedulingIgnoredDuringExecution – Établit les contraintes obligatoires qui doivent être respectées pour qu’un pod soit planifié sur un nœud.
  • preferedDuringSchedulingIgnoredDuringExecution – Définit les préférences qu’un planificateur priorise mais ne garantit pas.

Si les étiquettes de nœud changent au moment de l’exécution et que les règles d’affinité du pod ne sont plus respectées, le pod n’est pas supprimé du nœud. Le  paramètre nodeSelector  limite les pods à des nœuds spécifiques à l’aide d’étiquettes. Dans cet exemple, le pod Grafana va être planifié uniquement sur les nœuds portant l’ étiquette ssd .

La fonctionnalité d’affinité/anti-affinité de pod élargit les types de contraintes que vous pouvez exprimer. Au lieu d’utiliser des étiquettes de nœud, vous pouvez utiliser des étiquettes de pod existantes pour délimiter les nœuds sur lesquels un pod peut être planifié. Cette fonctionnalité vous permet de définir des règles afin que les pods individuels soient planifiés en fonction des étiquettes des autres pods.

Node Taints Et Tolérances

Kubernetes essaie automatiquement de déployer des pods aux emplacements avec la charge de travail la plus faible. L’affinité de nœud et de pod vous permet de contrôler sur quel nœud un pod est déployé. Les teintes peuvent empêcher le déploiement de pods sur des nœuds spécifiques sans altérer les pods existants. Les pods que vous souhaitez déployer sur un nœud contaminé doivent s’inscrire pour utiliser le nœud.

  • Taints – Empêchez la planification de nouveaux pods sur les nœuds, définissez les préférences des nœuds et supprimez les pods existants d’un nœud.
  • Tolérances – Activez la planification des pods uniquement sur les nœuds avec des Taints existants et correspondants.

Les teintes et les tolérances produisent des résultats optimaux lorsqu’elles sont utilisées ensemble pour garantir que les pods sont planifiés sur les nœuds appropriés.

Remarque : Découvrez ce qu’il faut rechercher lors de la migration d’une application héritée vers des conteneurs dans notre article Comment conteneuriser les applications héritées.

Regrouper Des Ressources Avec Des Espaces De Noms

Utilisez les espaces de noms Kubernetes pour partitionner les grands clusters en groupes plus petits et facilement identifiables. Les espaces de noms vous permettent de créer des environnements de test, d’assurance qualité, de production ou de développement distincts et d’allouer des ressources adéquates au sein d’un espace de noms unique. Les noms des ressources Kubernetes doivent uniquement être uniques au sein d’un même espace de noms. Différents espaces de noms peuvent avoir des ressources portant le même nom.

Si plusieurs utilisateurs ont accès au même cluster, vous pouvez limiter les utilisateurs et leur permettre d’agir dans les limites d’un espace de noms spécifique. Séparer les utilisateurs est un excellent moyen de délimiter les ressources et d’éviter les conflits potentiels de nommage ou de version.

Les espaces de noms sont des ressources Kubernetes et sont exceptionnellement faciles à créer. Créez un fichier YAML définissant le nom de l’espace de noms et utilisez kubectl pour le publier sur le serveur d’API Kubernetes. Vous pouvez ensuite utiliser l’espace de noms pour administrer le déploiement de ressources supplémentaires.

Conclusion

Un cluster Kubernetes représente une structure complexe avec un grand nombre de solutions et de fonctionnalités. Toutes les pratiques suggérées ne sont pas applicables à tous les cas d’utilisation.

Essayez d’appliquer certaines des pratiques décrites dans cet article et voyez l’impact que cela aura sur la cohésion et la fonctionnalité de votre cluster Kubernetes.

Cet article a-t-il été utile?

Oui Non