Architecture de cluster mutualisée

Cette page explique le fonctionnement de l'architecture de cluster mutualisée cluster multi-tenancy sur Google Kubernetes Engine (GKE). Cela inclut les clusters partagés par différents utilisateurs au sein d'une même organisation, ainsi que les clusters partagés par des instances (par client) d'une application de type logiciel en tant que service (SaaS). L'architecture de cluster mutualisée offre une alternative à la gestion de plusieurs clusters à locataire unique.

Cette page présente également les fonctionnalités de Kubernetes et GKE permettant de gérer des clusters mutualisés.

Qu'est-ce que l'architecture mutualisée ?

Un cluster mutualisé est partagé par plusieurs utilisateurs et/ou charges de travail, communément appelés "locataires". Les opérateurs de clusters mutualisés doivent isoler les locataires les uns des autres afin de minimiser les dommages qu'un locataire peut causer au cluster et aux autres locataires, qu'il s'agisse d'un locataire malveillant ou d'un utilisateur dont les données ont été infectées. En outre, les ressources du cluster doivent être équitablement réparties entre les différents locataires.

Lorsque vous planifiez une architecture mutualisée, vous devez prendre en compte les couches d'isolation des ressources dans Kubernetes : cluster, espace de noms, nœud, pod et conteneur. Vous devez également évaluer les implications du partage de différents types de ressources entre locataires en termes de sécurité. Par exemple, le fait de planifier les pods de différents locataires sur un même nœud peut réduire le nombre de machines nécessaires dans le cluster. Par ailleurs, vous pouvez avoir besoin d'empêcher la colocation de certaines charges de travail. Par exemple, vous pouvez interdire l'exécution de code non approuvé provenant de l'extérieur de votre organisation sur le même nœud que des conteneurs qui traitent des informations sensibles.

Même si Kubernetes ne peut pas garantir une isolation parfaitement sécurisée entre les locataires, il offre des fonctionnalités qui peuvent suffire pour des cas d'utilisation spécifiques. Vous pouvez isoler chaque locataire (ainsi que ses ressources Kubernetes) dans son propre espace de noms. Vous pouvez ensuite utiliser des règles pour appliquer l'isolation du locataire. Les règles sont généralement définies au niveau de l'espace de noms. Elles peuvent être utilisées pour limiter l'accès aux API et l'utilisation des ressources, ainsi que pour restreindre les opérations que les conteneurs sont autorisés à effectuer.

Les locataires d'un cluster mutualisé partagent les éléments suivants :

L'exploitation d'un cluster mutualisé présente plusieurs avantages par rapport à l'exploitation de plusieurs clusters à locataire unique :

  • Coûts de gestion réduits
  • Fragmentation des ressources moins importante
  • Les nouveaux locataires n'ont pas besoin d'attendre la création d'un cluster dédié.

Cas d'utilisation de l'architecture mutualisée

Cette section explique comment configurer un cluster pour divers cas d'utilisation de type "architecture mutualisée".

Architecture mutualisée d'entreprise

En environnement d'entreprise, les locataires d'un cluster sont des équipes distinctes au sein de l'organisation. En règle générale, chaque locataire se voit attribuer un espace de noms spécifique. Les modèles d'architecture mutualisée alternatifs de type "un locataire par cluster" ou "un locataire par Google Cloud projet" sont plus difficiles à gérer. Le trafic réseau au sein d'un espace de nommage n'est soumis à aucune restriction. Le trafic réseau entre différents espaces de noms doit être explicitement autorisé. Ces stratégies peuvent être appliquées à l'aide de Kubernetes API Network Policy.

Trois rôles différents peuvent être attribués aux utilisateurs du cluster, en fonction des privilèges dont ils ont besoin :

Administrateur du cluster
Ce rôle est spécifique aux administrateurs de l'ensemble du cluster, qui gèrent tous les locataires. Les administrateurs du cluster peuvent créer, lire, mettre à jour ou supprimer n'importe quel objet de stratégie. Ils peuvent créer des espaces de noms et les attribuer à des administrateurs d'espaces de noms.
Administrateur de l'espace de noms
Ce rôle concerne les administrateurs qui ne gèrent que certains locataires spécifiques. Un administrateur d'espace de noms peut gérer les utilisateurs au sein de celui dont il a la charge.
Développeur
Les utilisateurs disposant de ce rôle peuvent créer, lire, mettre à jour ou supprimer des objets de l'espace de noms qui ne sont pas liés à une stratégie, tels que des pods, des tâches et des entrées. Les développeurs ne disposent de ces privilèges que pour les espaces de nommage auxquels ils ont accès.

Pour plus d'informations sur la configuration de clusters mutualisés, consultez la section Bonnes pratiques pour l'architecture mutualisée d'entreprise.

Architecture mutualisée d'un fournisseur SaaS

Les locataires d'un cluster mis à disposition par un fournisseur SaaS sont les instances (par client) de l'application, ainsi que le plan de contrôle du SaaS. Pour qu'elles puissent tirer parti des règles appliquées aux espaces de noms, les instances de l'application doivent être organisées dans leurs propres espaces de noms. Il en est de même pour les composants du plan de contrôle du SaaS. Les utilisateurs finaux ne peuvent pas interagir directement avec le plan de contrôle de Kubernetes. Au lieu de cela, ils doivent utiliser l'interface SaaS, laquelle interagit ensuite avec le plan de contrôle de Kubernetes.

Par exemple, une plate-forme de blogs peut très bien s'exécuter sur un cluster mutualisé. En pareil cas, les "locataires" sont les instances de blog de chaque client, ainsi que le plan de contrôle de la plate-forme. Tous ces éléments (plan de contrôle de la plate-forme d'une part, et chacun des blogs hébergés d'autre part) sont exécutés dans des espaces de noms distincts. Les clients peuvent créer et supprimer des blogs ou mettre à jour leur version du logiciel de gestion de blog via l'interface de la plate-forme, même s'ils ne disposent d'aucune visibilité sur le fonctionnement du cluster.

Application de la stratégie d'architecture mutualisée

GKE et Kubernetes intègrent plusieurs fonctionnalités permettant de gérer les clusters mutualisés. Les sections suivantes offrent un aperçu de ces fonctionnalités.

Contrôle des accès

GKE offre deux systèmes de contrôle d'accès : Identity and Access Management (IAM) et le contrôle des accès basé sur les rôles (RBAC). IAM est le système de contrôle des accès de Google Cloud's permettant de gérer l'authentification et les autorisations associées aux Google Cloud ressources. Vous utilisez IAM pour accorder aux utilisateurs l'accès aux ressources GKE et Kubernetes. RBAC est intégré à Kubernetes. Cet outil vous permet d'accorder des autorisations précises pour des ressources et des opérations spécifiques au sein de vos clusters.

Reportez-vous à la page Présentation du contrôle des accès pour plus d'informations sur ces options et pour savoir quand vous devez utiliser chacune d'entre elles.

Reportez-vous au Guide d'utilisation de RBAC et au Guide d'utilisation d'IAM pour apprendre à utiliser ces systèmes de contrôle des accès.

Vous pouvez utiliser des autorisations IAM et RBAC avec des espaces de noms pour limiter les interactions des utilisateurs avec les ressources du cluster sur Google Cloud console. Pour en savoir plus, consultez Activer l'accès et afficher les ressources de cluster par espace de noms.

Règles de réseau

Les règles de réseau définies au niveau du cluster vous permettent de contrôler la communication entre les pods de votre cluster. Ces règles permettent de spécifier les espaces de nommage, plages d'adresses IP et étiquettes avec lesquels un pod est autorisé à communiquer.

Reportez-vous au guide d'utilisation des règles de réseau pour découvrir comment activer l'application des règles de réseau sur GKE.

Suivez le tutoriel sur la règle de réseau pour apprendre à écrire des règles de réseau.

Quotas de ressources

Les quotas de ressources permettent de gérer la quantité de ressources utilisée par les objets dans un espace de noms. Vous pouvez définir des quotas en termes d'utilisation du processeur et de la mémoire, ou en termes de nombre d'objets. Les quotas de ressources vous permettent de vous assurer qu'aucun locataire n'utilise plus que la part des ressources du cluster qui lui est attribuée.

Reportez-vous à la documentation sur les quotas de ressources pour plus d'informations.

Contrôle des admissions de pods basé sur des règles

Pour empêcher que les pods qui ne respectent pas vos limites de sécurité s'exécutent dans votre cluster, vous pouvez utiliser un contrôleur d'admission. Les contrôleurs d'admission peuvent vérifier les spécifications des pods par rapport à des règles que vous définissez, et empêcher les pods qui ne respectent pas ces règles de s'exécuter dans votre cluster.

GKE est compatible avec les types de contrôle d'admission suivants :

Anti-affinité de pod

Vous pouvez utiliser l'anti-affinité de pod pour empêcher que les pods de différents locataires soient planifiés sur le même nœud. Les contraintes d'anti-affinité sont basées sur les étiquettes des pods. Par exemple, la spécification de pod présentée ci-dessous décrit un pod portant l'étiquette "team": "billing", ainsi qu'une règle d'anti-affinité qui empêche que le pod soit planifié sur le même nœud que d'autres pods ne portant pas cette étiquette.

apiVersion: v1
kind: Pod
metadata:
  name: bar
  labels:
    team: "billing"
spec:
  affinity:
    podAntiAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - topologyKey: "kubernetes.io/hostname"
        labelSelector:
          matchExpressions:
          - key: "team"
            operator: NotIn
            values: ["billing"]

L'inconvénient de cette technique est que des utilisateurs malveillants pourraient contourner la règle en appliquant l'étiquette team: billing à un pod quelconque. L'anti-affinité de pod seule ne permet pas d'appliquer de manière sécurisée une stratégie sur des clusters dont les locataires ne sont pas des "tiers de confiance".

Reportez-vous à la documentation relative à l'anti-affinité de pod pour plus d'informations.

Nœuds dédiés avec rejets et tolérances

Les rejets de nœuds sont un autre moyen de contrôler la planification des charges de travail. Vous pouvez utiliser des rejets de nœuds pour réserver l'utilisation des nœuds spécialisés à certains locataires. Par exemple, vous pouvez dédier des nœuds équipés de GPU à des locataires spécifiques dont les charges de travail nécessitent des GPU. Pour les clusters Autopilot, les tolérances de nœuds ne sont disponibles que pour la séparation des charges de travail. Les rejets sont ajoutés automatiquement par le provisionnement automatique des nœuds si nécessaire.

Pour dédier un pool de nœuds à un locataire particulier, appliquez un rejet avec effect: "NoSchedule" au pool de nœuds. Lorsque vous procédez ainsi, seuls les pods dont la tolérance correspond peuvent être planifiés sur les nœuds du pool de nœuds.

L'inconvénient de cette technique est que des utilisateurs malveillants peuvent ajouter une tolérance à leurs pods afin d'obtenir l'accès au pool de nœuds dédié. Les tolérances et rejets de nœuds seuls ne permettent pas d'appliquer de manière sécurisée une stratégie sur des clusters dont les locataires ne sont pas des "tiers de confiance".

Pour en savoir plus, consultez la section Rejets et tolérances de la documentation Kubernetes.

GKE Sandbox

GKE Sandbox offre un niveau de sécurité supplémentaire pour les clusters mutualisés en isolant les charges de travail non approuvées du noyau hôte sur les nœuds de votre cluster. GKE Sandbox utilise gVisor, une technologie de bac à sable de conteneur Open Source, pour fournir un noyau d'espace utilisateur distinct pour chaque pod.

GKE Sandbox est particulièrement utile pour les fournisseurs SaaS ou les organisations qui exécutent du code non approuvé, car il permet d'empêcher un locataire malveillant de s'échapper de son conteneur ou d'affecter le noyau hôte. Pour en savoir plus, consultez la page GKE Sandbox.

Partage d'accélérateurs tels que les GPU et les TPU

Le partage d'accélérateurs GPU ou TPU entre les pods comporte des risques supplémentaires. Les GPU et les TPU peuvent ou non fournir des protections contre l'accès partagé. Ces protections peuvent dépendre de la version du matériel, de la version du pilote et de la configuration du système d'exécution. Le tableau suivant présente différentes approches et les risques associés à chacune d'elles.

Les pods qui se font confiance peuvent décider d'accepter un large éventail de risques. Le tableau indique le niveau de risque pour chaque niveau d'isolation.

Architecture Surface d'attaque principale Récapitulatif de sécurité
Les pods sur le même nœud partagent directement un accélérateur, y compris le temps partagé des GPU et NVIDIA MPS. Mémoire GPU et état global Les pods sont vulnérables les uns aux autres et doivent se faire confiance.
Les pods sur le même nœud partagent directement un accélérateur et utilisent GKE Sandbox, y compris le temps partagé des GPU et NVIDIA MPS. Mémoire GPU et pilote hôte GKE Sandbox isole le noyau de la charge de travail du noyau hôte. Il ne fournit aucune séparation dans l'environnement GPU, qui reste partagé.
Les pods sur le même nœud disposent d'accélérateurs dédiés, y compris les MIG NVIDIA. Noyau hôte (via le pilote) Les pods peuvent toujours être compromis par des failles d'accélérateur ou de pilote qui permettent une escalade vers le noyau hôte.
Les pods sur le même nœud disposent d'accélérateurs dédiés, y compris les MIG NVIDIA, et utilisent GKE Sandbox. Interface du pilote hôte (nvproxy) GKE Sandbox isole le noyau, mais l'interface du pilote GPU hôte (nvproxy) reste une surface d'attaque partagée. Une exploitation du pilote peut permettre une échappatoire au noyau hôte. Des fuites de canal latéral entre les instances MIG sont également possibles.
Chaque pod s'exécute sur un nœud dédié, qui dispose d'accélérateurs dédiés. Limite de la VM / Hyperviseur Recommandé pour les charges de travail non approuvées. Toute compromission est limitée à une seule VM.

Étape suivante