Optimiser son paysage applicatif sous Kubernetes

Dernière mise à jour : 15 mai 2023

Optimiser son paysage applicatif sous Kubernetes
Découvrez comment gérer efficacement les environnements de développement, de staging et de production dans Kubernetes, en utilisant des techniques comme les taints et tolerations, les labels et annotations, et les Network Policies.

Lors de l’élaboration d’une architecture technique qui puisse prendre en charge de nouvelles applications, il est crucial de définir la nature et le nombre d’environnements à mettre en place - développement, préproduction (staging), production…

Kubernetes, en complément des méthodes habituelles de séparation des environnements, propose des fonctionnalités qui simplifient cette gestion de manière à la fois efficace et sécurisée. Dans cet article, nous allons examiner comment exploiter des techniques spécifiques, notamment les "taints et tolerations", les "labels et annotations", et les "Network Policies", afin d’améliorer la gestion de vos environnements sous Kubernetes.

Pourquoi diversifier les environnements applicatifs ?

Qui n’a jamais eu besoin, même temporairement, d’un nouvel environnement de développement, de test, de formation ou de démonstration ? Accroître le nombre d’environnements applicatifs peut s’avérer complexe, mais c’est une nécessité pour répondre à des enjeux majeurs en termes de besoins projet et d’exigences techniques.

… en cours de projet

Ces demandes peuvent concerner la configuration, le paramétrage, la personnalisation, les tests, la validation, la démonstration, la formation, etc. Elles peuvent survenir à tout moment du projet et nécessiter des approches variées : initialisation à blanc, importation de jeux de données précis ou de jeux de tests, pseudonymisation de données, etc. Dans tous les cas, il est nécessaire de pouvoir mettre en place rapidement et efficacement ces nouveaux environnements applicatifs.

… ou à la suite de la mise en service

  1. Sécurité : La diversification des environnements applicatifs améliore la sécurité en séparant les différentes phases du cycle de vie de l’application. Par exemple, un environnement de développement, souvent plus flexible et moins sécurisé car en constante évolution doit être distingué de l’environnement de production, qui doit être hautement sécurisé pour protéger les données sensibles et les fonctionnalités de l’application. Cette séparation, généralement associée à celle des réseaux, minimise le risque de propagation de vulnérabilités d’un environnement à l’autre.

  2. Niveaux de services (SLA - Service Level Agreement) : Chaque environnement a ses propres exigences en termes de fiabilité et de disponibilité. Par exemple, l’environnement de production requiert généralement une haute disponibilité et une tolérance aux pannes pour assurer une expérience utilisateur optimale. En revanche, ces exigences peuvent être moins strictes pour les environnements de développement. La diversification des environnements permet de définir et de respecter les SLA appropriés pour chaque environnement, sans gaspiller inutilement les ressources ou le budget.

  3. Performances : Les différents environnements applicatifs peuvent nécessiter des infrastructures différentes. Par exemple, l’environnement de production peut requérir des ressources matérielles plus performantes et coûteuses pour gérer un volume de trafic plus élevé, tandis que l’environnement de développement peut se contenter de ressources moins puissantes. La diversification des environnements permet de personnaliser l’infrastructure de chaque environnement en fonction de ses besoins spécifiques.

Comparaison des méthodes d’isolation des environnements

L’optimisation du paysage applicatif par la multiplication des environnements peut apporter de nombreux bénéfices. Kubernetes, en particulier, propose plusieurs options qui facilitent cette tâche.

Il existe trois méthodes principales pour isoler les environnements dans Kubernetes : la séparation des clusters, l’isolation physique des Node Pools et l’isolation logique des Namespaces. Chacune présente des avantages et inconvénients en termes d’isolation, de coûts, de gestion des configurations, de sauvegarde et de reprise, de scalabilité et de sécurité. Les facteurs suivants peuvent influencer notre décision d’opter pour une méthode d’isolation plutôt qu’une autre :

  1. Complexité de l’application : Dans le cas d’une application complexe avec des dépendances ou configurations spécifiques à l’environnement, la méthode d’isolation peut être influencée. Par exemple, des clusters distincts pourraient s’avérer plus faciles à gérer si les environnements de développement et de production nécessitent des versions différentes d’un service spécifique.
  2. Exigences réglementaires : Des normes industrielles ou réglementations spécifiques peuvent exiger une isolation stricte entre les environnements. C’est souvent le cas dans les industries où les données de production sont très sensibles.
  3. Ressources disponibles : La quantité de ressources (CPU, mémoire, stockage) disponibles peut orienter le choix de la méthode d’isolation. Par exemple, s’il existe des contraintes en termes de ressources, l’utilisation de namespaces au lieu de clusters ou de Node Pools distincts pourrait être une option plus économique.
  4. Équipe et compétences : La taille de l’équipe et les compétences disponibles sont aussi des facteurs importants. La gestion de plusieurs clusters ou Node Pools peut être plus complexe et nécessiter des compétences spécifiques par rapport à la gestion d’un seul cluster avec des namespaces.
  5. Taille et durée de vie des environnements : Si les environnements diffèrent grandement en termes de taille (par exemple, un environnement de production bien plus grand que les environnements de développement ou de test), cela peut influencer le choix de la méthode d’isolation. De même, une durée de vie très variable des environnements (par exemple, des environnements de test créés et détruits fréquemment) peut également orienter ce choix.
  6. Outils et processus existants : Les outils et processus déjà en place pour la gestion des environnements peuvent aussi influencer le choix. Par exemple, l’existence d’outils qui fonctionnent bien avec une certaine approche peut être un argument en faveur de cette approche.
  7. Objectifs à long terme : Enfin, les objectifs à long terme sont également déterminants. Une croissance rapide prévue ou le déploiement de futures applications plus complexes peuvent influencer le choix de la méthode d’isolation d’environnement.

Stratégies pour la gestion des environnements dans Kubernetes

L’approche traditionnelle de séparation des clusters

Une des méthodes les plus efficaces pour isoler les environnements Kubernetes consiste à simplement créer des clusters distincts pour chaque environnement : développement, mise en préproduction et production. Cette approche procure le plus haut niveau d’isolation, garantissant une séparation complète des ressources pour chaque environnement.

Dans cette configuration, chaque environnement dispose de son propre cluster Kubernetes, avec ses propres nœuds, pods, services et autres ressources.

gcloud container clusters \
    create <cluster> \
    --zone <zone>

La gestion des mises à jour et déploiements offre un haut degré de contrôle et de sécurité. Chaque cluster peut être mis à jour individuellement, ce qui permet de tester les nouvelles versions dans les environnements de développement et de staging avant de les déployer en production. Néanmoins, cela induit que chaque déploiement soit géré individuellement pour chaque cluster, ce qui augmente considérablement la charge de travail pour les équipes d’exploitation.

En outre, cette approche peut s’avérer être plus coûteuse, chaque cluster nécessitant son propre ensemble de ressources. La sauvegarde et la reprise après sinistre peuvent être plus compliquées car chaque cluster doit être sauvegardé et restauré séparément. Par ailleurs, cette approche offre en général moins de flexibilité en cas de demandes de changements. Elle requiert en effet de définir un plan d’adressage IP dédié, de configurer les nouveaux flux, les règles de pare-feu et de définir les autorisations RBAC pour chaque cluster.

Malgré ces inconvénients, la séparation des environnements au niveau des clusters est souvent le choix le plus sûr pour les organisations qui ont besoin d’une forte isolation et qui peuvent assumer les coûts supplémentaires.

Isolation des Node Pools

La seconde stratégie d’isolation des environnements dans Kubernetes consiste à utiliser des Node Pools distincts pour chaque environnement au sein d’un même cluster. Cette approche offre un niveau d’isolation élevé, tout en permettant de partager les ressources entre les environnements.

Taints et Tolerations pour le contrôle des Workloads

Une fois les Node Pools configurés, il est possible d’utiliser les taints et tolerations de Kubernetes pour contrôler l’ordonnancement des pods. Les taints sont appliqués aux nœuds, indiquant que certains pods ne doivent pas être exécutés sur ces nœuds. A l’inverse, les pods qui peuvent tolérer ces taints peuvent être ordonnancés sur ces nœuds. Cela permet de diriger les workloads de développement, de préproduction ou de production vers les Node Pools appropriés.

kubectl taint nodes <node> \
    environment=dev:NoSchedule

Identification des ressources via les labels et annotations

Les labels et annotations de Kubernetes constituent un autre outil essentiel pour la gestion des environnements. Les labels permettent de marquer les ressources Kubernetes (tels que les pods et les services) avec des informations concernant l’environnement. Les annotations peuvent être utilisées pour ajouter des informations supplémentaires qui ne sont pas directement utilisées pour identifier les ressources.

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
    env: prod
spec:
replicas: 3
selector:
    matchLabels:
    app: my-app
template:
    metadata:
    labels:
        app: my-app
    spec:
    nodeSelector:
        environment: prod
    tolerations:
    - key: "environment"
        operator: "Equal"
        value: "prod"
        effect: "NoSchedule"
    containers:
    - name: my-app
        image: my-app:1.0.0

Network Policies pour l’isolation du réseau

Pour isoler le trafic réseau entre les environnements, les Network Policies peuvent être utilisées. Ces politiques permettent de contrôler le trafic réseau entre les pods dans un cluster. Par exemple, elles peuvent être utilisées pour empêcher le trafic entre les environnements de développement et de production, améliorant ainsi la sécurité.

Dans cet exemple, une Network Policy est utilisée pour interdire le trafic entrant vers les pods de l’environnement de production provenant des pods de l’environnement de développement au sein d’un même cluster.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-dev-to-prod
spec:
podSelector:
    matchLabels:
    env: production
policyTypes:
- Ingress
ingress:
- from:
    - podSelector:
        matchLabels:
        env: dev

Ingress Controllers et DNS pour l’accès aux applications

Enfin, pour permettre l’accès aux applications dans différents environnements, des Ingress Controllers distincts peuvent être configurés pour chaque environnement. Chacun d’eux peut avoir sa propre classe Ingress et son propre DNS. Cela permet à chaque application d’être accessible via des URLs distinctes dans chaque environnement. Cette approche assure une isolation claire et une gestion simplifiée de l’accès aux applications en fonction de l’environnement.

Gestion des mises à jour et déploiements

Dans ce scénario, les mises à jour et déploiements peuvent être gérés de manière plus centralisée. Les mises à jour peuvent être déployées sur différents Node Pools au sein du même cluster, ce qui permet de tester les nouvelles versions dans des environnements isolés avant de les déployer en production. De plus, étant donné que tous les Node Pools se trouvent dans le même cluster, certaines tâches de déploiement peuvent être simplifiées ou automatisées à l’aide de pipelines CI/CD. La version de Kubernetes, est par ailleurs la même pour tous les environnements, ce qui permet de simplifier la gestion des mises à jour.

Isolation logique des namespaces

L’isolation des environnements au niveau des namespaces est une approche qui offre un niveau d’isolation moins élevé que les clusters ou les Node Pools séparés. Etant plus abordable et plus facile à gérer, elle peut convenir aux startups et aux petites entreprises qui ont des ressources limitées. Cette solution peut également répondre aux besoins des grandes entreprises qui souhaitent mettre en place rapidement des environnements temporaires à des fins de tests ou de formation par exemple.

Dans cette configuration, tous les environnements cohabitent dans le même cluster, chaque environnement étant isolé dans son propre namespace. Cela signifie qu’un namespace “développement”, un namespace “staging” et un namespace “production” peuvent coexister dans le même cluster.

Les namespaces sont des subdivisions logiques au sein d’un cluster Kubernetes. Ils permettent de segmenter les ressources du cluster. Ces subdivisions peuvent être utilisées pour isoler les environnements de manière à ce que les ressources, les rôles et les autorisations soient gérés indépendamment dans chaque environnement.

kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace prod

Resource Quotas et Limit Ranges

Pour éviter qu’un environnement n’épuise les ressources d’un autre dans le même cluster, il est possible de mettre en place des Resource Quotas pour limiter les ressources qui peuvent être consommées dans un namespace donné.

apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-resources
spec:
hard:
    pods: "100"
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

De même, il est possible d’utiliser des Limit Ranges pour contrôler les ressources minimales et maximales qu’un pod ou un conteneur peut consommer.

apiVersion: v1
kind: LimitRange
metadata:
name: resource-limits
spec:
limits:
- type: Pod
    max:
    cpu: "2"
    memory: 2Gi
    min:
    cpu: "200m"
    memory: 200Mi
- type: Container
    max:
    cpu: "2"
    memory: 2Gi
    min:
    cpu: "100m"
    memory: 100Mi
    default:
    cpu: "300m"
    memory: 300Mi
    defaultRequest:
    cpu: "200m"
    memory: 200Mi

Rôles et autorisations RBAC

En plus de l’isolation des ressources, il est également préconisé d’utiliser un contrôle d’accès basé sur les rôles (RBAC) de sorte à gérer les autorisations au niveau des namespaces. Il est par exemple envisageable de définir des rôles qui permettent à certains utilisateurs ou groupes d’utilisateurs d’effectuer uniquement certaines actions dans un environnement spécifique.

Gestion des mises à jour et déploiements

Dans l’approche d’isolation des namespaces, les mises à jour et déploiements sont gérés au niveau du namespace. Aussi, il est possible de déployer et mettre à jour des applications dans différents environnements en changeant simplement le namespace cible. Cette approche simplifie grandement la gestion des déploiements, mais nécessite une attention particulière pour garantir que les mises à jour n’affectent pas négativement les autres environnements du même cluster. Comme pour l’approche des Node Pools, les pipelines CI/CD peuvent être utilisés pour automatiser le processus de déploiement.

Conclusion

La gestion des environnements applicatifs dans Kubernetes peut parfois sembler complexe et représente souvent un défi important pour les équipes de développement et d’exploitation. Chaque méthode d’isolation - que ce soit la séparation des clusters, l’isolation physique des Node Pools, ou l’utilisation des namespaces - possède ses propres avantages et inconvénients, et le choix doit être fait en fonction des besoins spécifiques de chaque organisation.

Il est indéniable que la séparation des clusters offre le niveau d’isolation le plus élevé, mais elle peut aussi entraîner des coûts plus élevés et une exploitation plus complexe. L’isolation des Node Pools offre un compromis attrayant entre l’isolation et le partage des ressources. De son côté, l’utilisation des namespaces est souvent la méthode la plus économique et la plus simple à gérer, bien que son niveau d’isolation soit généralement inférieur.

Il est important de comprendre qu’il n’y a pas de “bonne” ou de “mauvaise” façon d’isoler les environnements dans Kubernetes. Chaque organisation doit procéder à une évaluation approfondie de ses besoins, de ses capacités et de ses objectifs afin de choisir la méthode qui lui convient le mieux. Quelle que soit la méthode choisie, Kubernetes offre les outils et la flexibilité nécessaires pour créer et gérer efficacement des environnements isolés, favorisant ainsi l’atteinte des objectifs organisationnels.