Utiliser la bibliothèque de modèles de contraintes

Cette page vous explique comment définir les contraintes du service Policy Controller à l'aide des modèles de contraintes préexistants fournis par Google.

Cette page s'adresse aux administrateurs et opérateurs informatiques qui souhaitent s'assurer que toutes les ressources exécutées sur la plate-forme cloud répondent aux exigences de conformité organisationnelle en fournissant et en maintenant l'automatisation des audits ou des applications, et en utilisant des modèles de configuration déclarative. Pour en savoir plus sur les rôles courants et les exemples de tâches que nous citons dans le contenu Google Cloud, consultez la section Rôles utilisateur et tâches courantes de l'utilisateur dans GKE Enterprise.

Policy Controller vous permet d'appliquer des règles pour un cluster Kubernetes en définissant un ou plusieurs objets de contrainte. Une fois qu'une contrainte est installée, les requêtes adressées au serveur d'API sont vérifiées en fonction de la contrainte et sont rejetées si elles ne sont pas conformes. Les ressources non conformes préexistantes sont signalées au moment de l'audit.

Chaque contrainte s'accompagne d'un modèle de contrainte qui définit le schéma et la logique de la contrainte. Les modèles de contraintes peuvent provenir de Google, de tiers ou vous pouvez écrire les vôtres. Pour en savoir plus sur la création de modèles, consultez la page Écrire un modèle de contrainte.

Avant de commencer

Examiner la bibliothèque de modèles de contrainte

Lorsque vous définissez une contrainte, vous spécifiez le modèle de contrainte correspondant. Une bibliothèque de modèles de contraintes courants développés par Google est installée par défaut, et de nombreuses organisations n'ont pas besoin de créer de modèles de contraintes personnalisés directement dans Rego. Les modèles de contraintes fournis par Google ont le libellé configmanagement.gke.io/configmanagement.

Pour répertorier les contraintes, utilisez la commande suivante :

kubectl get constrainttemplates \
    -l="configmanagement.gke.io/configmanagement=config-management"

Pour décrire un modèle de contrainte et vérifier ses paramètres requis, utilisez la commande suivante :

kubectl describe constrainttemplate CONSTRAINT_TEMPLATE_NAME

Vous pouvez également afficher tous les modèles de contraintes dans la bibliothèque.

Définir une contrainte

Vous définissez une contrainte à l'aide d'un fichier YAML. Vous n'avez pas besoin de comprendre Rego, ni de savoir écrire dans ce langage. Au lieu de cela, vous utilisez une contrainte qui invoque un modèle de contrainte et lui fournit des paramètres spécifiques.

Si vous utilisez Config Sync avec un dépôt hiérarchique, nous vous recommandons de créer vos contraintes dans le répertoire cluster/.

Les contraintes comportent les champs suivants :

  • Le champ kind en minuscule correspond au nom d'un modèle de contrainte.
  • Le champ metadata.name correspond au nom de la contrainte.
  • Le champ match définit les objets auxquels la contrainte s'applique. Toutes les conditions spécifiées doivent être mises en correspondance avant qu'un objet soit soumis au champ d'application d'une contrainte. Les conditions match sont définies par les sous-champs suivants :
    • kinds sont les types de ressources auxquels la contrainte s'applique, déterminés par deux champs : apiGroups (liste de groupes d'API Kubernetes correspondants) et kinds (liste de types correspondants). "*" correspond à tout. Si au moins une entrée apiGroup et une entrée kind correspondent, la condition kinds est satisfaite.
    • scope accepte *, "Cluster" ou "Namespaced", qui déterminent si des ressources à l'échelle d'un cluster ou d'un espace de noms sont sélectionnées (la valeur par défaut est *).
    • namespaces est une liste de noms d'espaces de noms auxquels l'objet peut appartenir. L'objet doit appartenir au moins à l'un de ces espaces de noms. Les ressources d'espace de noms sont traitées comme si elles appartenaient à elles-mêmes.
    • excludedNamespaces est une liste d'espaces de noms auxquels l'objet ne peut pas appartenir.
    • labelSelector est un sélecteur de libellé Kubernetes que l'objet doit satisfaire.
    • namespaceSelector est un sélecteur de libellé sur l'espace de noms auquel appartient l'objet. Si l'espace de noms ne satisfait pas l'objet, il ne correspondra pas. Les ressources d'espace de noms sont traitées comme si elles appartenaient à elles-mêmes.
  • Le champ parameters définit les arguments de la contrainte, en fonction des attentes du modèle de contrainte.

La contrainte suivante, appelée ns-must-have-geo, appelle un modèle de contrainte appelé K8sRequiredLabels, qui est inclus dans la bibliothèque de modèles de contraintes fournie par Google. La contrainte définit les paramètres que le modèle de contrainte utilise pour évaluer si le libellé geo est défini sur une valeur pour les espaces de noms.

# ns-must-have-geo.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-geo
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - key: "geo"

Pour créer la contrainte, utilisez kubectl apply -f :

kubectl apply -f ns-must-have-geo.yaml

Auditer une contrainte

Si la contrainte est configurée et installée correctement, son champ status.byPod[].enforced est défini sur true, que la contrainte soit configurée pour appliquer ou pour auditer uniquement la contrainte.

Les contraintes sont appliquées par défaut et la violation d'une contrainte empêche une opération de cluster donnée. Vous pouvez définir le paramètre spec.enforcementAction d'une contrainte sur dryrun pour signaler les violations dans le champ status.violations sans empêcher l'opération.

Pour en savoir plus sur l'audit, consultez la page Effectuer un audit à l'aide de contraintes.

Mises en garde concernant la synchronisation de contraintes

Si vous synchronisez vos contraintes avec une source centralisée telle qu'un dépôt Git, avec Config Sync ou un autre outil de type GitOps, gardez à l'esprit les mises en garde suivantes lors de la synchronisation des contraintes.

Cohérence à terme

Vous pouvez effectuer un commit des contraintes sur une source de référence telle qu'un dépôt Git, et limiter leurs effets à l'aide de ClusterSelectors ou de NamespaceSelectors. Étant donné que la synchronisation est cohérente à terme, gardez à l'esprit les mises en garde suivantes :

  • Si une opération de cluster déclenche une contrainte dont le paramètre NamespaceSelector fait référence à un espace de noms qui n'a pas été synchronisé, la contrainte est appliquée et l'opération ne peut aboutir. En d'autres termes, un espace de noms manquant provoque une erreur "fails closed".
  • Si vous modifiez les libellés d'un espace de noms, le cache peut contenir des données obsolètes pendant une courte période.

Minimisez la nécessité de renommer un espace de noms ou de modifier ses libellés, et testez les contraintes qui affectent un espace de noms renommé ou dont le libellé a été modifié pour vous assurer que tout fonctionne comme prévu.

Configurer Policy Controller pour les contraintes référentielles

Avant de pouvoir activer les contraintes référentielles, vous devez créer une configuration qui indique à Policy Controller les types d'objets à surveiller, tels que les espaces de noms.

Enregistrez le fichier manifeste YAML suivant dans un fichier et appliquez-le avec kubectl. Le fichier manifeste configure Policy Controller pour surveiller les objets Namespace et Ingress. Créez une entrée avec group, version et kind sous spec.sync.syncOnly, avec les valeurs pour chaque type d'objet que vous souhaitez surveiller.

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: "extensions"
        version: "v1beta1"
        kind: "Ingress"

Activer des contraintes référentielles

Une contrainte référentielle fait référence à un autre objet dans sa définition. Par exemple, vous pouvez créer une contrainte nécessitant que les objets Ingress d'un cluster aient des noms d'hôte uniques. La contrainte est référentielle si son modèle de contrainte contient la chaîne data.inventory dans son Rego.

Les contraintes référentielles sont activées par défaut si vous installez Policy Controller à l'aide de la console Google Cloud. Si vous installez Policy Controller à l'aide de Google Cloud CLI, vous pouvez choisir d'activer ou non les contraintes référentielles lorsque vous installez Policy Controller. Les contraintes référentielles ne sont garanties que pour être cohérentes à terme, ce qui engendre certains risques :

  • Sur un serveur d'API surchargé, le contenu du cache de Policy Controller peut devenir obsolète, provoquant l'échec ("fail open") d'une contrainte référentielle, ce qui signifie que l'action d'application semble fonctionner alors que ce n'est pas le cas. Par exemple, vous pouvez créer des objets Ingress avec des noms d'hôte en double trop rapidement pour que le contrôleur d'admission soit en mesure de détecter les doublons.

  • L'ordre dans lequel les contraintes sont installées et l'ordre dans lequel le cache est mis à jour sont tous deux aléatoires.

Vous pouvez mettre à jour un cluster existant pour autoriser les contraintes référentielles.

Console

Pour désactiver les contraintes référentielles, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page Stratégie de GKE Enterprise sous la section Gestion de la stratégie.

    Accéder à la page "Règle"

  2. Sous l'onglet Paramètres, dans la table du cluster, sélectionnez Modifier dans la colonne Modifier la configuration.
  3. Développez le menu Modifier la configuration Policy Controller.
  4. Cochez la case Activer les modèles de contrainte qui font référence à des objets autres que l'objet actuellement évalué.
  5. Sélectionnez Enregistrer les modifications.

gcloud Policy Controller

Pour activer la compatibilité avec les contraintes référentielles, exécutez la commande suivante :

gcloud container fleet policycontroller update \
    --memberships=MEMBERSHIP_NAME \
    --referential-rules

Remplacez MEMBERSHIP_NAME par le nom d'appartenance du cluster enregistré sur lequel activer les règles référentielles. Vous pouvez spécifier plusieurs appartenances séparées par une virgule.

gcloud ConfigManagement

Pour activer la compatibilité avec les contraintes référentielles, définissez policyController.referentialRulesEnabled sur true dans votre fichier config-management.yaml :

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: true

Désactiver les contraintes référentielles

Lorsque vous désactivez les contraintes référentielles, tous les modèles qui utilisent des contraintes référentielles sont également supprimés du cluster, ainsi que toutes les contraintes qui utilisent ces modèles.

Console

Les contraintes référentielles sont activées par défaut lorsque vous installez Policy Controller avec la console Google Cloud. Pour désactiver les contraintes référentielles, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page Stratégie de GKE Enterprise sous la section Gestion de la stratégie.

    Accéder à la page "Règle"

  2. Sous l'onglet Paramètres, dans la table du cluster, sélectionnez Modifier dans la colonne Modifier la configuration.
  3. Développez le menu Modifier la configuration Policy Controller.
  4. Décochez la case Activer les modèles de contrainte qui font référence à des objets autres que celui en cours d'évaluation.
  5. Sélectionnez Enregistrer les modifications.

gcloud Policy Controller

Pour désactiver la compatibilité avec les contraintes référentielles, exécutez la commande suivante :

gcloud container fleet policycontroller update \
    --memberships=MEMBERSHIP_NAME \
    --no-referential-rules

Remplacez MEMBERSHIP_NAME par le nom d'appartenance du cluster enregistré sur lequel activer les règles référentielles. Vous pouvez spécifier plusieurs appartenances séparées par une virgule.

gcloud ConfigManagement

Pour désactiver les contraintes référentielles sur un cluster, définissez policyController.referentialRulesEnabled sur false dans votre fichier config-management.yaml :

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: false

Répertorier toutes les contraintes

Pour répertorier toutes les contraintes installées sur un cluster, exécutez la commande suivante :

kubectl get constraint

Vous pouvez également consulter un aperçu des contraintes appliquées dans la console Google Cloud. Pour en savoir plus, consultez la page Métriques de Policy Controller.

Supprimer une contrainte

Pour rechercher toutes les contraintes qui utilisent un modèle de contrainte, exécutez la commande suivante pour répertorier tous les objets ayant le même paramètre kind que le champ metadata.name du modèle de contrainte :

kubectl get CONSTRAINT_TEMPLATE_NAME

Pour supprimer une contrainte, spécifiez ses paramètres kind et name :

kubectl delete CONSTRAINT_TEMPLATE_NAME CONSTRAINT_NAME

Lorsque vous supprimez une contrainte, elle cesse d'être appliquée dès que le serveur d'API la marque comme supprimée.

Supprimer tous les modèles de contraintes

Console

Pour désactiver la bibliothèque de modèles de contrainte, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page Stratégie de GKE Enterprise sous la section Gestion de la stratégie.

    Accéder à la page "Règle"

  2. Sous l'onglet Paramètres, dans la table du cluster, sélectionnez Modifier dans la colonne Modifier la configuration.
  3. Dans le menu Ajouter/Modifier des groupes de règles, désactivez la bibliothèque de modèles et tous les groupes de règles .
  4. Sélectionnez Enregistrer les modifications.

gcloud Policy Controller

Pour désactiver la bibliothèque de modèles de contrainte, exécutez la commande suivante :

gcloud container fleet policycontroller content templates disable \
    --memberships=MEMBERSHIP_NAME

Remplacez MEMBERSHIP_NAME par le nom d'appartenance du cluster enregistré pour désactiver la bibliothèque de modèles de contraintes. Vous pouvez spécifier plusieurs appartenances séparées par une virgule.

gcloud ConfigManagement

Définissez spec.policyController.templateLibraryInstalled sur false. Cela empêche Policy Controller de réinstaller automatiquement la bibliothèque.

Pour supprimer tous les modèles de contraintes et toutes les contraintes, exécutez la commande suivante :

kubectl delete constrainttemplate --all

Restaurer la bibliothèque de modèles de contrainte

Console

Pour activer la bibliothèque de modèles de contrainte, procédez comme suit :

  1. Dans la console Google Cloud, accédez à la page Stratégie de GKE Enterprise sous la section Gestion de la stratégie.

    Accéder à la page "Règle"

  2. Sous l'onglet Paramètres, dans la table du cluster, sélectionnez Modifier dans la colonne Modifier la configuration.
  3. Dans le menu Ajouter/Modifier des groupes de règles, activez la bibliothèque de modèles sur . Vous pouvez également activer tout ou partie des groupes de règles.
  4. Sélectionnez Enregistrer les modifications.

gcloud Policy Controller

Pour restaurer la bibliothèque de modèles de contraintes, exécutez la commande suivante :

gcloud container fleet policycontroller content templates enable \
    --memberships=MEMBERSHIP_NAME

Remplacez MEMBERSHIP_NAME par le nom d'appartenance du cluster enregistré sur lequel activer la bibliothèque de modèles de contraintes. Vous pouvez spécifier plusieurs appartenances séparées par une virgule.

gcloud ConfigManagement

Si vous avez désactivé la bibliothèque de modèles de contrainte ou désinstallé tous les modèles de contrainte, vous pouvez la restaurer en définissant spec.policyController.templateLibraryInstalled sur true dans la configuration de Policy Controller.

Pour redémarrer le pod de l'opérateur, utilisez la commande suivante :

kubectl delete pod -n config-management-system -l k8s-app=config-management-operator

Étapes suivantes