Pourquoi avez-vous besoin d’un contrôleur d’admission Kubernetes
Chris Laux
25 avril 2022
0 minutes de lectureSi vous n’avez jamais travaillé comme opérateur ou administrateur Kubernetes, les contrôleurs d’admission sont peut-être une nouveauté pour vous. Ces contrôleurs fonctionnent principalement en arrière-plan et sont souvent disponibles sous forme de plug-ins intégrés, mais ils peuvent contribuer de manière significative à la sécurité d’un déploiement.
Les contrôleurs d’admission interceptent les requêtes API avant leur transmission au serveur API et peuvent les interdire ou les modifier. Cela concerne la plupart des types de requêtes Kubernetes, à l’exception des requêtes de lecture seule, qui ne sont pas transmises aux contrôleurs. Les contrôleurs d’admission traitent les requêtes après leur authentification et leur autorisation.
Cet article explique pourquoi intégrer des contrôleurs d’admission Kubernetes. Il souligne également les avantages d’une meilleure connaissance de leur fonctionnement.
Plusieurs contrôleurs d’admission sont activés par défaut, car la plupart des opérations Kubernetes courantes en dépendent. La plupart font partie de l’arborescence du code source Kubernetes et sont compilés sous forme de plug-ins. Il est également possible de coder et de déployer des contrôleurs d’admission tiers. Nous présenterons quelques exemples plus loin. Pour en savoir plus sur la mise en œuvre des contrôleurs d’admission, consultez la documentation Kubernetes.
Contrôleurs d’admission par défaut
Kubernetes propose plusieurs contrôleurs d’admission intégrés. Par exemple, DefaultIngressClass applique la classe d’ingress par défaut aux objets ingress qui n’en ont pas encore de définie. De même, DefaultStorageClass applique la classe de stockage par défaut aux PersistentVolumeClaims qui n’en ont pas encore. Ce contrôleur doit être activé pour permettre le provisionnement dynamique du stockage en fonction de la classe de stockage.
Les contrôleurs d’admission peuvent être très utiles pour assurer la sécurité. Ils peuvent, par exemple, atténuer les attaques par déni de service (DoS) sur les clusters mutualisés. Prenons le plug-in LimitRanger qui, comme son nom l’indique, applique des plages de limites. Celles-ci définissent, pour chaque espace de noms, les plages de consommation des ressources qui doivent être respectées. Cela empêche les locataires d’épuiser les ressources des autres.
L’inondation d’événements constitue un autre risque : le cluster se retrouve submergé et ne peut plus traiter correctement les autres requêtes légitimes. Le contrôleur EventRateLimit est un outil efficace pour atténuer ce type de situation. Il peut limiter la fréquence des événements par espace de noms ou par utilisateur.
Deux autres contrôleurs importants permettent aux développeurs d’exécuter leurs plug-ins d’admission sous forme de webhooks configurables à l’exécution. MutatingAdmissionWebhook permet aux webhooks de modifier les ressources soumises et sert généralement à appliquer des valeurs par défaut personnalisées. De son côté, le contrôleur ValidatingAdmissionWebhook permet aux webhooks enregistrés de décider si une ressource validée par l’API, dans son état final, poursuit son cheminement ou est entièrement rejetée.
Rôle des contrôleurs
À l’origine, pour exécuter plusieurs services sur une machine physique, on hébergeait des machines virtuelles sur le même hôte, leurs systèmes d’exploitation étant isolés par un hyperviseur. Un système complexe de configurations cloud — celles définies par AWS, par exemple — séparait les systèmes et empêchait les locataires de se nuire, accidentellement ou délibérément.
Kubernetes a d’abord été conçu comme un système collaboratif destiné à une seule organisation ou à un seul utilisateur. Il reposait également bien davantage sur le respect mutuel que les autres systèmes cloud. Cependant, à mesure que Kubernetes se diversifie et devient capable de gérer des clusters plus grands, il est de plus en plus important d’appliquer des politiques garantissant qu’un utilisateur ne puisse pas perturber le fonctionnement du système.
Pour automatiser ce processus, les organisations ont besoin d’un système de politiques. Kubernetes propose certaines fonctionnalités intégrées, mais ne dispose pas des capacités d’un moteur de politiques complet et spécialisé.
Moteurs de politiques externes
Deux moteurs de politiques open source majeurs sont disponibles pour Kubernetes : Open Policy Agent (OPA) Gatekeeper et Kyverno.
Ces deux moteurs sont des projets confiés à la Cloud Native Computing Foundation (CNCF), qui œuvre à la normalisation et à la diffusion des technologies cloud natives. Elle dépend de son organisation mère, la Linux Foundation. Kubernetes est également un projet de la CNCF.
Le principal avantage de Kyverno est qu’il n’est pas nécessaire d’apprendre un langage supplémentaire. Toutes ses politiques sont définies sous forme de ressources Kubernetes. Gatekeeper, en revanche, s’appuie sur Rego, le langage déclaratif d’OPA. Gatekeeper fait partie de l’écosystème OPA, tandis que Kyverno est un projet autonome pour Kubernetes. En résumé, Gatekeeper est le projet le plus mature, mais Kyverno est plus facile à prendre en main.
Votre contrôleur d’admission personnalisé
Vous pouvez utiliser des webhooks pour coder la logique d’un contrôleur d’admission personnalisé dans n’importe quel langage capable de traiter des requêtes HTTP et de renvoyer du JavaScript Object Notation (JSON). Go, Python ou Ruby, par exemple, sont tous de bons choix.
L’exemple ci-dessous montre comment configurer un webhook pour un contrôleur d’admission personnalisé. Il ressemble à LimitRanger, présenté plus haut, qui rejette les requêtes de pods dépassant les limites de ressources de leur espace de noms. Notez que cet exemple ne contient pas l’intégralité du code source du contrôleur. Pour approfondir le sujet, consultez la documentation Kubernetes sur les serveurs de webhooks d’admission.
Commencez par enregistrer le webhook à l’aide d’un objet de configuration :
Cela indique le webhook au ValidatingWebhookController. Cela précise également le service à contacter et le chemin à sonder sur le conteneur qui exécute le serveur. Enfin, cela définit les règles à appliquer pour déterminer s’il faut appeler le webhook. Cet exemple porte sur la création de nouveaux pods.
En pratique, cette ressource serait créée dans le cluster en dernier, après le déploiement du serveur webhook. Le déploiement comprend un service correspondant à la définition du fichier ci-dessus :
Voici un exemple de déploiement d’un webhook, qui ne diffère pas de celui d’une application classique. Nous n’aborderons pas la sécurisation des communications à l’aide de TLS (Transport Layer Security), bien que cela soit vivement recommandé.
Après l’envoi d’une requête de nouveau pod à Kubernetes et son passage par ValidatingWebhook, les informations pertinentes sont envoyées par une requête POST au chemin d’URL configuré. Elles contiennent un objet JSON que le webhook doit traiter. Pour valider la requête, renvoyez une réponse semblable à la suivante, accompagnée du code d’état 200 OK :
Le champ uid est repris de la requête afin de faire correspondre les requêtes et les réponses. Pour empêcher la création du pod, le champ allowed doit être défini sur false et une erreur HTTP doit être signalée.
Un contrôleur d’admission personnalisé peut être aussi simple que cet exemple, ou bien beaucoup plus complexe. Pour une présentation plus complète, consultez la documentation sur les webhooks d’admission.
Conclusion
Un contrôleur d’admission Kubernetes peut modifier ou rejeter les requêtes destinées au serveur API avant que l’objet soit enregistré. Kubernetes propose de nombreux contrôleurs intégrés polyvalents, notamment plusieurs plug-ins précompilés et deux types de webhooks de contrôle d’admission. Cependant, coder des webhooks et des contrôleurs spécifiques permet une plus grande flexibilité et un contrôle plus précis.
Les contrôleurs d’admission et les webhooks permettent aux projets de proposer des moteurs de politiques comme OPA Gatekeeper et Kyverno. De plus, il est facile de mettre en place un système d’admission personnalisé à l’aide de webhooks compatibles HTTP, dans n’importe quel langage capable de renvoyer des réponses HTTP contenant une charge utile JSON.
En définitive, les contrôleurs d’admission ne sont qu’un élément d’une stratégie complète de sécurité Kubernetes. Des risques et des vulnérabilités existent à chaque étape du cycle de développement logiciel, mais leur atténuation ne doit pas nécessairement perturber l’ensemble du workflow. Une organisation spécialisée en sécurité peut vous apporter une expertise précieuse pour trouver la bonne approche.
Une sécurité IaC pensée pour les développeurs
Snyk sécurise votre infrastructure en tant que code, du cycle de développement logiciel à l’exécution dans le cloud, grâce à un moteur unifié de politiques sous forme de code. Chaque équipe peut ainsi développer, déployer et exploiter ses applications en toute sécurité.
Chris Laux développe des logiciels depuis plus de 20 ans dans différents langages de programmation.



