Valider Kubernetes YAML par rapport aux meilleures pratiques et politiques

Noter. trad.: Avec le nombre croissant de configurations YAML pour les environnements K8, le besoin de leur vérification automatisée devient de plus en plus urgent. L'auteur de cette revue a non seulement sélectionné les solutions existantes pour cette tùche, mais a également utilisé le déploiement comme exemple pour voir comment elles fonctionnent. Cela s'est avéré trÚs instructif pour ceux qui s'intéressent à ce sujet.

Valider Kubernetes YAML par rapport aux meilleures pratiques et politiques

TL; DR: Cet article compare six outils statiques pour valider et évaluer les fichiers YAML Kubernetes par rapport aux meilleures pratiques et exigences.

Les charges de travail Kubernetes sont généralement définies sous la forme de documents YAML. L'un des problÚmes de YAML est la difficulté de spécifier des contraintes ou des relations entre les fichiers manifestes.

Que se passe-t-il si nous devons nous assurer que toutes les images dĂ©ployĂ©es sur le cluster proviennent d'un registre approuvĂ© ?

Comment puis-je empĂȘcher les dĂ©ploiements qui n'ont pas de PodDisruptionBudgets d'ĂȘtre envoyĂ©s au cluster ?

L'intégration de tests statiques vous permet d'identifier les erreurs et les violations de politique au stade du développement. Cela augmente la garantie que les définitions de ressources sont correctes et sécurisées, et rend plus probable que les charges de travail de production suivront les meilleures pratiques.

L’écosystĂšme d’inspection de fichiers YAML statique Kubernetes peut ĂȘtre divisĂ© dans les catĂ©gories suivantes :

  • Validateurs d'API. Les outils de cette catĂ©gorie vĂ©rifient le manifeste YAML par rapport aux exigences du serveur API Kubernetes.
  • Testeurs prĂȘts. Les outils de cette catĂ©gorie sont accompagnĂ©s de tests prĂȘts Ă  l'emploi pour la sĂ©curitĂ©, le respect des bonnes pratiques, etc.
  • Validateurs personnalisĂ©s. Les reprĂ©sentants de cette catĂ©gorie vous permettent de crĂ©er des tests personnalisĂ©s dans diffĂ©rents langages, par exemple Rego et Javascript.

Dans cet article, nous allons dĂ©crire et comparer six outils diffĂ©rents :

  1. Kubeval;
  2. score kube ;
  3. config-lint ;
  4. cuivre;
  5. concours;
  6. polaris.

Eh bien, commençons !

Vérification des déploiements

Avant de commencer à comparer les outils, créons un contexte sur lequel les tester.

Le manifeste ci-dessous contient un certain nombre d’erreurs et de non-respect des bonnes pratiques : combien pouvez-vous en trouver ?

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: http-echo
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

(base-valid.yaml)

Nous utiliserons ce YAML pour comparer différents outils.

Le manifeste ci-dessus base-valid.yaml et d'autres manifestes de cet article peuvent ĂȘtre trouvĂ©s dans DĂ©pĂŽts Git.

Le manifeste dĂ©crit une application Web dont la tĂąche principale est de rĂ©pondre par un message « Hello World » sur le port 5678. Elle peut ĂȘtre dĂ©ployĂ©e avec la commande suivante :

kubectl apply -f hello-world.yaml

Et donc - vérifiez le travail :

kubectl port-forward svc/http-echo 8080:5678

Allez maintenant Ă  http://localhost:8080 et confirmez que l'application fonctionne. Mais suit-il les meilleures pratiques ? Allons vĂ©rifier.

1. Kubéval

Au cƓur Kubeval L'idĂ©e est que toute interaction avec Kubernetes se fait via son API REST. En d’autres termes, vous pouvez utiliser un schĂ©ma API pour vĂ©rifier si un YAML donnĂ© s’y conforme. Regardons un exemple.

Instructions d'installation kubeval sont disponibles sur le site Web du projet.

Au moment de la rédaction de l'article original, la version 0.15.0 était disponible.

Une fois installĂ©, alimentons-le avec le manifeste ci-dessus :

$ kubeval base-valid.yaml
PASS - base-valid.yaml contains a valid Deployment (http-echo)
PASS - base-valid.yaml contains a valid Service (http-echo)

En cas de succĂšs, Kubeval se terminera avec le code de sortie 0. Vous pouvez le vĂ©rifier comme suit :

$ echo $?
0

Essayons maintenant Kubeval avec un autre manifeste :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

(kubeval-invalid.yaml)

Pouvez-vous repĂ©rer le problĂšme Ă  l’oeil nu ? Lançons :

$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml contains an invalid Deployment (http-echo) - selector: selector is required
PASS - kubeval-invalid.yaml contains a valid Service (http-echo)

# ĐżŃ€ĐŸĐČĐ”Ń€ĐžĐŒ ĐșĐŸĐŽ ĐČĐŸĐ·ĐČрата
$ echo $?
1

La ressource n'est pas en cours de vérification.

Déploiements utilisant la version API apps/v1, doit inclure un sélecteur qui correspond à l'étiquette du pod. Le manifeste ci-dessus n'inclut pas le sélecteur, donc kubeval a signalé une erreur et s'est terminé avec un code différent de zéro.

Je me demande ce qui se passera si je le fais kubectl apply -f avec ce manifeste ?

Eh bien, essayons :

$ kubectl apply -f kubeval-invalid.yaml
error: error validating "kubeval-invalid.yaml": error validating data: ValidationError(Deployment.spec):
missing required field "selector" in io.k8s.api.apps.v1.DeploymentSpec; if you choose to ignore these errors,
turn validation off with --validate=false

C'est exactement l'erreur contre laquelle Kubeval a mis en garde. Vous pouvez rĂ©soudre ce problĂšme en ajoutant un sĂ©lecteur :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:          # !!!
    matchLabels:     # !!!
      app: http-echo # !!!
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
        image: hashicorp/http-echo
        args: ["-text", "hello-world"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: http-echo
spec:
  ports:
  - port: 5678
    protocol: TCP
    targetPort: 5678
  selector:
    app: http-echo

(base-valid.yaml)

L'avantage d'outils comme Kubeval est que de telles erreurs peuvent ĂȘtre dĂ©tectĂ©es dĂšs le dĂ©but du cycle de dĂ©ploiement.

De plus, ces vĂ©rifications ne nĂ©cessitent pas d'accĂšs au cluster ; elles peuvent ĂȘtre effectuĂ©es hors ligne.

Par dĂ©faut, Kubeval vĂ©rifie les ressources par rapport au dernier schĂ©ma de l'API Kubernetes. Cependant, dans la plupart des cas, vous devrez peut-ĂȘtre vĂ©rifier par rapport Ă  une version spĂ©cifique de Kubernetes. Cela peut ĂȘtre fait en utilisant le drapeau --kubernetes-version:

$ kubeval --kubernetes-version 1.16.1 base-valid.yaml

Veuillez noter que la version doit ĂȘtre spĂ©cifiĂ©e au format Major.Minor.Patch.

Pour une liste des versions pour lesquelles la vérification est prise en charge, veuillez vous référer à Schéma JSON sur GitHub, que Kubeval utilise pour la validation. Si vous devez exécuter Kubeval hors ligne, téléchargez les schémas et spécifiez leur emplacement local à l'aide du drapeau --schema-location.

En plus des fichiers YAML individuels, Kubeval peut également fonctionner avec des répertoires et stdin.

De plus, Kubeval s'intĂšgre facilement au pipeline CI. Ceux qui souhaitent exĂ©cuter des tests avant d'envoyer des manifestes au cluster seront heureux de savoir que Kubeval prend en charge trois formats de sortie :

  1. Texte brut ;
  2. JSON ;
  3. Testez tout le protocole (TAP).

Et n'importe lequel des formats peut ĂȘtre utilisĂ© pour une analyse plus approfondie de la sortie afin de gĂ©nĂ©rer un rĂ©sumĂ© des rĂ©sultats du type souhaitĂ©.

L'un des inconvénients de Kubeval est qu'il ne peut actuellement pas vérifier la conformité avec les définitions de ressources personnalisées (CRD). Cependant, il est possible de configurer Kubeval ignore les.

Kubeval est un excellent outil pour vĂ©rifier et Ă©valuer les ressources ; Il convient toutefois de souligner que la rĂ©ussite du test ne garantit pas que la ressource est conforme aux meilleures pratiques.

Par exemple, en utilisant la balise latest dans un conteneur ne suit pas les meilleures pratiques. Cependant, Kubeval ne considÚre pas cela comme une erreur et ne la signale pas. Autrement dit, la vérification de ce YAML se terminera sans avertissement.

Mais que se passe-t-il si vous souhaitez Ă©valuer YAML et identifier des violations comme la balise latest? Comment puis-je vĂ©rifier un fichier YAML par rapport aux meilleures pratiques ?

2. Score Kube

Score Kube analyse les manifestes YAML et les Ă©value par rapport aux tests intĂ©grĂ©s. Ces tests sont sĂ©lectionnĂ©s en fonction des directives de sĂ©curitĂ© et des meilleures pratiques, telles que :

  • ExĂ©cuter le conteneur pas en tant que root.
  • DisponibilitĂ© des contrĂŽles de santĂ© des pods.
  • DĂ©finition des demandes et des limites de ressources.

Sur la base des rĂ©sultats des tests, trois rĂ©sultats sont donnĂ©s : OK, ATTENTION Đž CRITIQUE.

Vous pouvez essayer Kube-score en ligne ou l'installer localement.

Au moment de la rédaction de l'article original, la derniÚre version de kube-score était la 1.7.0.

Essayons-le sur notre manifeste base-valid.yaml:

$ kube-score score base-valid.yaml

apps/v1/Deployment http-echo
[CRITICAL] Container Image Tag
  · http-echo -> Image with latest tag
      Using a fixed tag is recommended to avoid accidental upgrades
[CRITICAL] Pod NetworkPolicy
  · The pod does not have a matching network policy
      Create a NetworkPolicy that targets this pod
[CRITICAL] Pod Probes
  · Container is missing a readinessProbe
      A readinessProbe should be used to indicate when the service is ready to receive traffic.
      Without it, the Pod is risking to receive traffic before it has booted. It is also used during
      rollouts, and can prevent downtime if a new version of the application is failing.
      More information: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[CRITICAL] Container Security Context
  · http-echo -> Container has no configured security context
      Set securityContext to run the container in a more secure context.
[CRITICAL] Container Resources
  · http-echo -> CPU limit is not set
      Resource limits are recommended to avoid resource DDOS. Set resources.limits.cpu
  · http-echo -> Memory limit is not set
      Resource limits are recommended to avoid resource DDOS. Set resources.limits.memory
  · http-echo -> CPU request is not set
      Resource requests are recommended to make sure that the application can start and run without
      crashing. Set resources.requests.cpu
  · http-echo -> Memory request is not set
      Resource requests are recommended to make sure that the application can start and run without crashing.
      Set resources.requests.memory
[CRITICAL] Deployment has PodDisruptionBudget
  · No matching PodDisruptionBudget was found
      It is recommended to define a PodDisruptionBudget to avoid unexpected downtime during Kubernetes
      maintenance operations, such as when draining a node.
[WARNING] Deployment has host PodAntiAffinity
  · Deployment does not have a host podAntiAffinity set
      It is recommended to set a podAntiAffinity that stops multiple pods from a deployment from
      being scheduled on the same node. This increases availability in case the node becomes unavailable.

YAML rĂ©ussit les tests Kubeval, tandis que Kube-score pointe les dĂ©fauts suivants :

  • Les contrĂŽles de prĂ©paration ne sont pas configurĂ©s.
  • Il n'y a aucune demande ni limite pour les ressources CPU et la mĂ©moire.
  • Les budgets de perturbation des pods ne sont pas prĂ©cisĂ©s.
  • Il n'y a pas de rĂšgles de sĂ©paration (anti-affinitĂ©) pour maximiser la disponibilitĂ©.
  • Le conteneur s'exĂ©cute en tant que root.

Ce sont tous des points valables sur les lacunes qui doivent ĂȘtre corrigĂ©es pour rendre le dĂ©ploiement plus efficace et plus fiable.

Équipe kube-score affiche les informations sous une forme lisible par l'homme, y compris toutes les violations de type ATTENTION Đž CRITIQUE, ce qui aide beaucoup lors du dĂ©veloppement.

Ceux qui souhaitent utiliser cet outil dans le pipeline CI peuvent activer une sortie plus compressée à l'aide de l'indicateur --output-format ci (dans ce cas, les tests avec le résultat sont également affichés OK):

$ kube-score score base-valid.yaml --output-format ci

[OK] http-echo apps/v1/Deployment
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory limit is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory request is not set
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Image with latest tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: The pod does not have a matching network policy
[CRITICAL] http-echo apps/v1/Deployment: Container is missing a readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Container has no configured security context
[CRITICAL] http-echo apps/v1/Deployment: No matching PodDisruptionBudget was found
[WARNING] http-echo apps/v1/Deployment: Deployment does not have a host podAntiAffinity set
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service

Semblable à Kubeval, Kube-score renvoie un code de sortie différent de zéro lorsqu'un test échoue CRITIQUE. Vous pouvez également activer un traitement similaire pour ATTENTION.

De plus, il est possible de vĂ©rifier la conformitĂ© des ressources avec les diffĂ©rentes versions de l'API (comme dans Kubeval). Cependant, ces informations sont codĂ©es en dur dans le kube-score lui-mĂȘme : vous ne pouvez pas sĂ©lectionner une version diffĂ©rente de Kubernetes. Cette limitation peut constituer un gros problĂšme si vous avez l'intention de mettre Ă  niveau votre cluster ou si vous disposez de plusieurs clusters avec diffĂ©rentes versions de K8.

S'il vous plaßt noter que il y a déjà un problÚme avec une proposition pour réaliser cette opportunité.

Plus d’informations sur le score kube peuvent ĂȘtre trouvĂ©es sur le site officiel.

Les tests Kube-score sont un excellent outil pour mettre en Ɠuvre les meilleures pratiques, mais que se passe-t-il si vous devez apporter des modifications au test ou ajouter vos propres rĂšgles ? HĂ©las, cela ne peut pas ĂȘtre fait.

Kube-score n'est pas extensible : vous ne pouvez pas y ajouter de politiques ni les ajuster.

Si vous devez Ă©crire des tests personnalisĂ©s pour vĂ©rifier la conformitĂ© aux politiques de l'entreprise, vous pouvez utiliser l'un des quatre outils suivants : config-lint, copper, conftest ou polaris.

3.Config-lint

Config-lint est un outil de validation des fichiers de configuration YAML, JSON, Terraform, CSV et des manifestes Kubernetes.

Vous pouvez l'installer en utilisant instructions sur le site du projet.

La version actuelle au moment de la rédaction de l'article original est la 1.5.0.

Config-lint n'a pas de tests intégrés pour valider les manifestes Kubernetes.

Pour effectuer des tests, vous devez crĂ©er des rĂšgles appropriĂ©es. Ils sont Ă©crits dans des fichiers YAML appelĂ©s « ensembles de rĂšgles Â» (ensembles de rĂšgles), et ont la structure suivante :

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # ŃĐżĐžŃĐŸĐș праĐČОл

(rule.yaml)

Étudions-le de plus prùs :

  • Champ type spĂ©cifie le type de configuration que config-lint utilisera. Pour les manifestes K8, c'est toujours Kubernetes.
  • Dans l' files En plus des fichiers eux-mĂȘmes, vous pouvez spĂ©cifier un rĂ©pertoire.
  • Champ rules destinĂ© Ă  la mise en place de tests utilisateurs.

Supposons que vous souhaitiez vous assurer que les images du dĂ©ploiement sont toujours tĂ©lĂ©chargĂ©es Ă  partir d'un rĂ©fĂ©rentiel fiable tel que my-company.com/myapp:1.0. Une rĂšgle config-lint qui effectue une telle vĂ©rification ressemblerait Ă  ceci :

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment must use a valid image tag
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

(rule-trusted-repo.yaml)

Chaque rĂšgle doit avoir les attributs suivants :

  • id — identifiant unique de la rĂšgle ;
  • severity - peut ĂȘtre Analyse De DĂ©faillance, ATTENTION Đž NON_CONFORME;
  • message — si une rĂšgle est violĂ©e, le contenu de cette ligne est affichĂ© ;
  • resource — le type de ressource auquel cette rĂšgle s'applique ;
  • assertions — une liste de conditions qui seront Ă©valuĂ©es par rapport Ă  cette ressource.

Dans la rÚgle ci-dessus assertion intitulé every vérifie que tous les conteneurs sont en déploiement (key: spec.templates.spec.containers) utilisez des images fiables (c'est-à-dire commençant par my-company.com/).

L'ensemble de rĂšgles complet ressemble Ă  ceci :

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:

 - id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
    severity: FAILURE
    message: Deployment must use a valid image repository
    resource: Deployment
    assertions:
      - every:
          key: spec.template.spec.containers
          expressions:
            - key: image
              op: starts-with
              value: "my-company.com/"

(ruleset.yaml)

Pour tester le test, sauvegardons-le sous check_image_repo.yaml. Vérifions le fichier base-valid.yaml:

$ config-lint -rules check_image_repo.yaml base-valid.yaml

[
  {
  "AssertionMessage": "Every expression fails: And expression fails: image does not start with my-company.com/",
  "Category": "",
  "CreatedAt": "2020-06-04T01:29:25Z",
  "Filename": "test-data/base-valid.yaml",
  "LineNumber": 0,
  "ResourceID": "http-echo",
  "ResourceType": "Deployment",
  "RuleID": "DEPLOYMENT_IMAGE_REPOSITORY",
  "RuleMessage": "Deployment must use a valid image repository",
  "Status": "FAILURE"
  }
]

Le contrĂŽle a Ă©chouĂ©. Examinons maintenant le manifeste suivant avec le rĂ©fĂ©rentiel d'images correct :

apiVersion: apps/v1
kind: Deployment
metadata:
  name: http-echo
spec:
  replicas: 2
  selector:
    matchLabels:
      app: http-echo
  template:
    metadata:
      labels:
        app: http-echo
    spec:
      containers:
      - name: http-echo
         image: my-company.com/http-echo:1.0 # !!!
         args: ["-text", "hello-world"]
         ports:
         - containerPort: 5678

(image-valid-mycompany.yaml)

Nous effectuons le mĂȘme test avec le manifeste ci-dessus. Aucun problĂšme trouvĂ©:

$ config-lint -rules check_image_repo.yaml image-valid-mycompany.yaml
[]

Config-lint est un framework prometteur qui vous permet de créer vos propres tests pour valider les manifestes Kubernetes YAML à l'aide du YAML DSL.

Mais que se passe-t-il si vous avez besoin d’une logique et de tests plus complexes ? YAML n'est-il pas trop limitĂ© pour cela ? Et si vous pouviez crĂ©er des tests dans un langage de programmation complet ?

4. Cuivre

Cuivre V2 est un framework pour valider les manifestes à l'aide de tests personnalisés (similaire à config-lint).

Cependant, il diffĂšre de ce dernier dans la mesure oĂč il n’utilise pas YAML pour dĂ©crire les tests. Les tests peuvent ĂȘtre Ă©crits en JavaScript Ă  la place. Copper fournit une bibliothĂšque avec plusieurs outils de base, qui vous aident Ă  lire des informations sur les objets Kubernetes et Ă  signaler les erreurs.

Les étapes d'installation de Copper se trouvent dans documents officiels.

2.0.1 est la derniÚre version de cet utilitaire au moment de la rédaction de l'article original.

Comme config-lint, Copper n'a pas de tests intĂ©grĂ©s. Écrivons-en un. Laissez-le vĂ©rifier que les dĂ©ploiements utilisent des images de conteneurs exclusivement provenant de rĂ©fĂ©rentiels fiables tels que my-company.com.

Créer un fichier check_image_repo.js avec le contenu suivant :

$$.forEach(function($){
    if ($.kind === 'Deployment') {
        $.spec.template.spec.containers.forEach(function(container) {
            var image = new DockerImage(container.image);
            if (image.registry.lastIndexOf('my-company.com/') != 0) {
                errors.add_error('no_company_repo',"Image " + $.metadata.name + " is not from my-company.com repo", 1)
            }
        });
    }
});

Maintenant, testons notre manifeste base-valid.yaml, utilisez la commande copper validate:

$ copper validate --in=base-valid.yaml --validator=check_image_tag.js

Check no_company_repo failed with severity 1 due to Image http-echo is not from my-company.com repo
Validation failed

Il est clair qu'avec l'aide du cuivre, vous pouvez effectuer des tests plus complexes - par exemple, vérifier les noms de domaine dans les manifestes d'entrée ou rejeter les pods exécutés en mode privilégié.

Le cuivre intĂšgre diverses fonctions utilitaires :

  • DockerImage lit le fichier d'entrĂ©e spĂ©cifiĂ© et crĂ©e un objet avec les attributs suivants :
    • name - le nom de l'image,
    • tag - balise d'image,
    • registry - registre d'images,
    • registry_url - protocole (https://) et registre d'images,
    • fqin — localisation complĂšte de l'image.
  • Fonction findByName aide Ă  trouver une ressource par un type donnĂ© (kind) et le nom (name) Ă  partir du fichier d'entrĂ©e.
  • Fonction findByLabels aide Ă  trouver une ressource par un type spĂ©cifiĂ© (kind) et les Ă©tiquettes (labels).

Vous pouvez afficher toutes les fonctions de service disponibles ici.

Par défaut, il charge l'intégralité du fichier YAML d'entrée dans une variable $$ et le rend disponible pour les scripts (une technique familiÚre pour ceux qui ont une expérience jQuery).

Le principal avantage de Copper est évident : vous n'avez pas besoin de maßtriser un langage spécialisé et vous pouvez utiliser diverses fonctionnalités JavaScript pour créer vos propres tests, comme l'interpolation de chaßnes, les fonctions, etc.

Il convient également de noter que la version actuelle de Copper fonctionne avec la version ES5 du moteur JavaScript, et non avec ES6.

Détails disponibles sur le site officiel du projet.

Cependant, si vous n'aimez pas vraiment JavaScript et prĂ©fĂ©rez un langage spĂ©cialement conçu pour crĂ©er des requĂȘtes et dĂ©crire des politiques, vous devez faire attention au concours.

5.Contest

Conftest est un framework pour tester les donnĂ©es de configuration. Convient Ă©galement pour tester/vĂ©rifier les manifestes Kubernetes. Les tests sont dĂ©crits Ă  l'aide d'un langage de requĂȘte spĂ©cialisĂ© Rego.

Vous pouvez installer conftest en utilisant instructionsrépertoriés sur le site Internet du projet.

Au moment de la rédaction de l'article original, la derniÚre version disponible était la 0.18.2.

Semblable Ă  config-lint et copper, conftest est livrĂ© sans aucun test intĂ©grĂ©. Essayons-le et Ă©crivons notre propre politique. Comme dans les exemples prĂ©cĂ©dents, nous vĂ©rifierons si les images des conteneurs proviennent d’une source fiable.

Créer un répertoire conftest-checks, et dedans il y a un fichier nommé check_image_registry.rego avec le contenu suivant :

package main

deny[msg] {

  input.kind == "Deployment"
  image := input.spec.template.spec.containers[_].image
  not startswith(image, "my-company.com/")
  msg := sprintf("image '%v' doesn't come from my-company.com repository", [image])
}

Testons maintenant base-valid.yaml Ă  travers conftest:

$ conftest test --policy ./conftest-checks base-valid.yaml

FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
1 tests, 1 passed, 0 warnings, 1 failure

Comme on pouvait s’y attendre, le test a Ă©chouĂ© car les images provenaient d’une source non fiable.

Dans le fichier Rego nous définissons le bloc deny. Sa véracité est considérée comme une violation. Si bloque deny plusieurs, conftest les vérifie indépendamment les uns des autres, et la vérité de l'un des blocs est traitée comme une violation.

En plus de la sortie par dĂ©faut, conftest prend en charge les formats JSON, TAP et tableau - une fonctionnalitĂ© extrĂȘmement utile si vous devez intĂ©grer des rapports dans un pipeline CI existant. Vous pouvez dĂ©finir le format souhaitĂ© Ă  l'aide du drapeau --output.

Pour faciliter le débogage des politiques, conftest a un indicateur --trace. Il génÚre une trace de la façon dont conftest analyse les fichiers de stratégie spécifiés.

Les politiques du concours peuvent ĂȘtre publiĂ©es et partagĂ©es dans les registres OCI (Open Container Initiative) en tant qu'artefacts.

ĐšĐŸĐŒĐ°ĐœĐŽŃ‹ push Đž pull vous permettent de publier un artefact ou de rĂ©cupĂ©rer un artefact existant Ă  partir d'un registre distant. Essayons de publier la politique que nous avons créée dans le registre Docker local Ă  l'aide de conftest push.

DĂ©marrez votre registre Docker local :

$ docker run -it --rm -p 5000:5000 registry

Dans un autre terminal, accĂ©dez au rĂ©pertoire que vous avez créé prĂ©cĂ©demment conftest-checks et exĂ©cutez la commande suivante :

$ conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

Si la commande a rĂ©ussi, vous verrez un message comme celui-ci :

2020/06/10 14:25:43 pushed bundle with digest: sha256:e9765f201364c1a8a182ca637bc88201db3417bacc091e7ef8211f6c2fd2609c

CrĂ©ez maintenant un rĂ©pertoire temporaire et exĂ©cutez la commande dedans conftest pull. Il tĂ©lĂ©chargera le package créé par la commande prĂ©cĂ©dente :

$ cd $(mktemp -d)
$ conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

Un sous-rĂ©pertoire apparaĂźtra dans le rĂ©pertoire temporaire policycontenant notre fichier de politique :

$ tree
.
└── policy
  └── check_image_registry.rego

Les tests peuvent ĂȘtre exĂ©cutĂ©s directement depuis le rĂ©fĂ©rentiel :

$ conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
FAIL - base-valid.yaml - image 'hashicorp/http-echo' doesn't come from my-company.com repository
2 tests, 1 passed, 0 warnings, 1 failure

Malheureusement, DockerHub n'est pas encore pris en charge. Alors considérez-vous chanceux si vous utilisez Registre de conteneurs Azure (ACR) ou votre propre registre.

Le format de l'artefact est le mĂȘme que celui Ouvrir les packages de l'agent de stratĂ©gie (OPA), qui vous permet d'utiliser conftest pour exĂ©cuter des tests Ă  partir de packages OPA existants.

Vous pouvez en savoir plus sur le partage de politiques et d’autres fonctionnalitĂ©s de Confest sur le site officiel du projet.

6. Polaris

Le dernier outil qui sera abordé dans cet article est Polaris. (Son annonce de l'année derniÚre, nous déjà traduit - environ. traduction)

Polaris peut ĂȘtre installĂ© dans un cluster ou utilisĂ© en mode ligne de commande. Comme vous l'avez peut-ĂȘtre devinĂ©, il vous permet d'analyser statiquement les manifestes Kubernetes.

Lors de l'exécution en mode ligne de commande, des tests intégrés sont disponibles couvrant des domaines tels que la sécurité et les meilleures pratiques (similaires à kube-score). De plus, vous pouvez créer vos propres tests (comme dans config-lint, copper et conftest).

En d’autres termes, Polaris combine les avantages des deux catĂ©gories d’outils : avec des tests intĂ©grĂ©s et personnalisĂ©s.

Pour installer Polaris en mode ligne de commande, utilisez instructions sur le site Web du projet.

Au moment de la rédaction de l'article original, la version 1.0.3 est disponible.

Une fois l'installation terminée, vous pouvez exécuter Polaris sur le manifeste base-valid.yaml avec la commande suivante :

$ polaris audit --audit-path base-valid.yaml

Il affichera une chaĂźne au format JSON avec une description dĂ©taillĂ©e des tests effectuĂ©s et de leurs rĂ©sultats. La sortie aura la structure suivante :

{
  "PolarisOutputVersion": "1.0",
  "AuditTime": "0001-01-01T00:00:00Z",
  "SourceType": "Path",
  "SourceName": "test-data/base-valid.yaml",
  "DisplayName": "test-data/base-valid.yaml",
  "ClusterInfo": {
    "Version": "unknown",
    "Nodes": 0,
    "Pods": 2,
    "Namespaces": 0,
    "Controllers": 2
  },
  "Results": [
    /* ĐŽĐ»ĐžĐœĐœŃ‹Đč ŃĐżĐžŃĐŸĐș */
  ]
}

Sortie complĂšte disponible ici.

Comme Kube-score, Polaris identifie les problĂšmes dans les domaines oĂč le manifeste ne rĂ©pond pas aux meilleures pratiques :

  • Il n’y a aucun contrĂŽle de santĂ© pour les pods.
  • Les balises pour les images de conteneur ne sont pas spĂ©cifiĂ©es.
  • Le conteneur s'exĂ©cute en tant que root.
  • Les demandes et les limites de mĂ©moire et de CPU ne sont pas spĂ©cifiĂ©es.

Chaque test, en fonction de ses résultats, se voit attribuer un degré de criticité : avertissement ou danger. Pour en savoir plus sur les tests intégrés disponibles, veuillez vous référer à documentation.

Si les dĂ©tails ne sont pas nĂ©cessaires, vous pouvez spĂ©cifier le drapeau --format score. Dans ce cas, Polaris affichera un nombre allant de 1 Ă  100 - But (c'est-Ă -dire Ă©valuation) :

$ polaris audit --audit-path test-data/base-valid.yaml --format score
68

Plus le score est proche de 100, plus le degrĂ© d’accord est Ă©levĂ©. Si vous vĂ©rifiez le code de sortie de la commande polaris audit, il s'avĂšre qu'il est Ă©gal Ă  0.

Faire polaris audit Vous pouvez terminer le travail avec un code diffĂ©rent de zĂ©ro Ă  l'aide de deux indicateurs :

  • Drapeau --set-exit-code-below-score prend comme argument une valeur seuil comprise entre 1 et 100. Dans ce cas, la commande se terminera avec le code de sortie 4 si le score est infĂ©rieur au seuil. Ceci est trĂšs utile lorsque vous avez une certaine valeur seuil (disons 75) et que vous devez recevoir une alerte si le score descend en dessous.
  • Drapeau --set-exit-code-on-danger entraĂźnera l'Ă©chec de la commande avec le code 3 si l'un des tests de danger Ă©choue.

Essayons maintenant de crĂ©er un test personnalisĂ© qui vĂ©rifie si l'image provient d'un rĂ©fĂ©rentiel fiable. Les tests personnalisĂ©s sont spĂ©cifiĂ©s au format YAML et le test lui-mĂȘme est dĂ©crit Ă  l'aide du schĂ©ma JSON.

L'extrait de code YAML suivant décrit un nouveau test appelé checkImageRepo:

checkImageRepo:
  successMessage: Image registry is valid
  failureMessage: Image registry is not valid
  category: Images
  target: Container
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

Regardons-le de plus prĂšs :

  • successMessage — cette ligne sera imprimĂ©e si le test se termine avec succĂšs ;
  • failureMessage — ce message sera affichĂ© en cas d'Ă©chec ;
  • category — indique l'une des catĂ©gories : Images, Health Checks, Security, Networking Đž Resources;
  • target--- dĂ©termine quel type d'objet (spec) le test est appliquĂ©. Valeurs possibles: Container, Pod ou Controller;
  • Le test lui-mĂȘme est spĂ©cifiĂ© dans l'objet schema en utilisant le schĂ©ma JSON. Le mot clĂ© de ce test est pattern utilisĂ© pour comparer la source de l’image avec celle requise.

Pour exĂ©cuter le test ci-dessus, vous devez crĂ©er la configuration Polaris suivante :

checks:
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(polaris-conf.yaml)

Analysons le fichier :

  • Dans l' checks des tests et leur niveau de criticitĂ© sont prescrits. Puisqu'il est souhaitable de recevoir un avertissement lorsqu'une image provient d'une source non fiable, nous dĂ©finissons ici le niveau danger.
  • Le test lui-mĂȘme checkImageRepo puis inscrit dans l'objet customChecks.

Enregistrez le fichier sous custom_check.yaml. Maintenant tu peux courir polaris audit avec un manifeste YAML qui nécessite une vérification.

Testons notre manifeste base-valid.yaml:

$ polaris audit --config custom_check.yaml --audit-path base-valid.yaml

Équipe polaris audit a exĂ©cutĂ© uniquement le test utilisateur spĂ©cifiĂ© ci-dessus et il a Ă©chouĂ©.

Si vous corrigez l'image sur my-company.com/http-echo:1.0, Polaris se fermera avec succÚs. Le manifeste avec les changements est déjà disponible référentielsafin que vous puissiez vérifier la commande précédente sur le manifeste image-valid-mycompany.yaml.

Maintenant, la question se pose : comment exécuter des tests intégrés avec des tests personnalisés ? Facilement! Il vous suffit d'ajouter les identifiants de test intégrés au fichier de configuration. De ce fait, cela prendra la forme suivante :

checks:
  cpuRequestsMissing: warning
  cpuLimitsMissing: warning
  # Other inbuilt checks..
  # ..
  # custom checks
  checkImageRepo: danger # !!!
customChecks:
  checkImageRepo:        # !!!
    successMessage: Image registry is valid
    failureMessage: Image registry is not valid
    category: Images
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(config_with_custom_check.yaml)

Un exemple de fichier de configuration complet est disponible ici.

VĂ©rifier le manifeste base-valid.yamlĂ  l'aide de tests intĂ©grĂ©s et personnalisĂ©s, vous pouvez utiliser la commande :

$ polaris audit --config config_with_custom_check.yaml --audit-path base-valid.yaml

Polaris complÚte les tests intégrés par des tests personnalisés, combinant ainsi le meilleur des deux mondes.

En revanche, l’impossibilitĂ© d’utiliser des langages plus puissants comme Rego ou JavaScript peut ĂȘtre un facteur limitant empĂȘchant la crĂ©ation de tests plus sophistiquĂ©s.

Plus d’informations sur Polaris sont disponibles sur site du projet.

Résumé

Bien qu'il existe de nombreux outils disponibles pour inspecter et évaluer les fichiers YAML Kubernetes, il est important de bien comprendre comment les tests seront conçus et exécutés.

Par exemple, si vous prenez des manifestes Kubernetes passant par un pipeline, Kubeval pourrait ĂȘtre la premiĂšre Ă©tape d'un tel pipeline. Il surveillerait si les dĂ©finitions d'objets sont conformes au schĂ©ma de l'API Kubernetes.

Une fois cet examen terminé, on pourrait passer à des tests plus sophistiqués, tels que la conformité aux meilleures pratiques standard et aux politiques spécifiques. C'est là que Kube-score et Polaris seraient utiles.

Pour ceux qui ont des exigences complexes et ont besoin de personnaliser les tests en détail, copper, config-lint et conftest conviendraient..

Conftest et config-lint utilisent YAML pour définir des tests personnalisés, et Copper vous donne accÚs à un langage de programmation complet, ce qui en fait un choix assez attractif.

D'un autre cÎté, vaut-il la peine d'utiliser un de ces outils et donc de créer tous les tests manuellement, ou de préférer Polaris et d'y ajouter uniquement le nécessaire ? Il n'y a pas de réponse claire à cette question.

Le tableau ci-dessous fournit une brĂšve description de chaque outil :

Outil
But
Limites
Tests utilisateurs

Kubeval
Valide les manifestes YAML par rapport à une version spécifique du schéma API
Je ne peux pas travailler avec CRD
Non

score Kube
Analyse les manifestes YAML par rapport aux meilleures pratiques
Impossible de sélectionner la version de votre API Kubernetes pour vérifier les ressources
Non

capuchons de cuivre
Un cadre général pour créer des tests JavaScript personnalisés pour les manifestes YAML
Aucun test intégré. Mauvaise documentation
Oui

config-lint
Un cadre général pour créer des tests dans un langage spécifique à un domaine intégré dans YAML. Prend en charge divers formats de configuration (par exemple Terraform)
Il n’existe pas de tests prĂȘts Ă  l’emploi. Les assertions et fonctions intĂ©grĂ©es peuvent ne pas suffire
Oui

concours
Un framework pour crĂ©er vos propres tests Ă  l'aide de Rego (un langage de requĂȘte spĂ©cialisĂ©). Permet le partage de politiques via des bundles OCI
Aucun test intégré. Je dois apprendre Rego. Docker Hub n'est pas pris en charge lors de la publication de stratégies
Oui

Polaris
Examine les manifestes YAML par rapport aux meilleures pratiques standard. Vous permet de créer vos propres tests à l'aide du schéma JSON
Les capacitĂ©s de test basĂ©es sur le schĂ©ma JSON peuvent ne pas ĂȘtre suffisantes
Oui

Étant donnĂ© que ces outils ne dĂ©pendent pas de l’accĂšs au cluster Kubernetes, ils sont faciles Ă  installer. Ils vous permettent de filtrer les fichiers sources et de fournir un retour rapide aux auteurs des pull request dans les projets.

PS du traducteur

A lire aussi sur notre blog :

Source: habr.com

Achetez un hĂ©bergement fiable pour les sites avec protection DDoS, serveurs VPS VDS đŸ”„ Achetez un hĂ©bergement web fiable avec protection DDoS, serveurs VPS et VDS | ProHoster