Valideer Kubernetes YAML op basis van best practices en beleid

Opmerking. vert.: Met het groeiende aantal YAML-configuraties voor K8s-omgevingen wordt de behoefte aan geautomatiseerde verificatie steeds urgenter. De auteur van deze recensie selecteerde niet alleen bestaande oplossingen voor deze taak, maar gebruikte Deployment ook als voorbeeld om te zien hoe ze werken. Het bleek zeer informatief voor degenen die geïnteresseerd zijn in dit onderwerp.

Valideer Kubernetes YAML op basis van best practices en beleid

TL; DR: dit artikel vergelijkt zes statische tools om Kubernetes YAML-bestanden te valideren en te evalueren op basis van best practices en vereisten.

Kubernetes-workloads worden doorgaans gedefinieerd in de vorm van YAML-documenten. Een van de problemen met YAML is de moeilijkheid bij het specificeren van beperkingen of relaties tussen manifestbestanden.

Wat als we ervoor moeten zorgen dat alle afbeeldingen die in het cluster worden geïmplementeerd, afkomstig zijn uit een vertrouwd register?

Hoe kan ik voorkomen dat implementaties die geen PodDisruptionBudgets hebben, naar het cluster worden verzonden?

Dankzij de integratie van statische tests kunt u fouten en beleidsschendingen in de ontwikkelingsfase identificeren. Dit vergroot de garantie dat resourcedefinities correct en veilig zijn, en maakt het waarschijnlijker dat productieworkloads de best practices zullen volgen.

Het statische YAML-bestandsinspectie-ecosysteem van Kubernetes kan worden onderverdeeld in de volgende categorieën:

  • API-validators. Tools in deze categorie controleren het YAML-manifest aan de vereisten van de Kubernetes API-server.
  • Klaar testers. Tools uit deze categorie worden geleverd met kant-en-klare tests voor beveiliging, naleving van best practices, enz.
  • Aangepaste validatoren. Met vertegenwoordigers van deze categorie kunt u aangepaste tests maken in verschillende talen, bijvoorbeeld Rego en Javascript.

In dit artikel beschrijven en vergelijken we zes verschillende tools:

  1. kubusval;
  2. kube-score;
  3. config-lint;
  4. koper;
  5. betwisten;
  6. polaris.

Nou, laten we beginnen!

Implementaties controleren

Voordat we tools gaan vergelijken, moeten we wat achtergrond creëren waarop we ze kunnen testen.

In onderstaand manifest staan ​​een aantal fouten en het niet naleven van best practices: hoeveel daarvan kun je vinden?

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)

We zullen deze YAML gebruiken om verschillende tools met elkaar te vergelijken.

Bovenstaand manifest base-valid.yaml en andere manifesten uit dit artikel zijn te vinden in Git-opslagplaatsen.

Het manifest beschrijft een webapplicatie waarvan de belangrijkste taak is om te reageren met een “Hello World”-bericht op poort 5678. Deze kan worden ingezet met het volgende commando:

kubectl apply -f hello-world.yaml

En dus - controleer het werk:

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

Ga nu naar http://localhost:8080 en bevestig dat de applicatie werkt. Maar volgt het de beste praktijken? Laten we het controleren.

1. Kubeval

In het hart kubusval Het idee is dat elke interactie met Kubernetes plaatsvindt via de REST API. Met andere woorden, u kunt een API-schema gebruiken om te controleren of een bepaalde YAML hieraan voldoet. Laten we eens kijken naar een voorbeeld.

Installatie instructies kubeval zijn beschikbaar op de projectwebsite.

Op het moment dat het originele artikel werd geschreven, was versie 0.15.0 beschikbaar.

Eenmaal geïnstalleerd, laten we het bovenstaande manifest invoeren:

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

Indien succesvol zal kubeval afsluiten met exitcode 0. U kunt dit als volgt controleren:

$ echo $?
0

Laten we kubeval nu proberen met een ander manifest:

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)

Kunt u het probleem met het oog ontdekken? Laten we lanceren:

$ 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

De bron wordt niet geverifieerd.

Implementaties met behulp van de API-versie apps/v1, moet een selector bevatten die overeenkomt met het label van de pod. Het bovenstaande manifest bevat niet de selector, dus kubeval heeft een fout gerapporteerd en afgesloten met een code die niet nul is.

Ik vraag me af wat er zal gebeuren als ik dat doe kubectl apply -f met dit manifest?

Nou, laten we het proberen:

$ 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

Dit is precies de fout waarvoor Kubeval waarschuwde. Je kunt dit oplossen door een selector toe te voegen:

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)

Het voordeel van tools als kubeval is dat dit soort fouten al vroeg in de implementatiecyclus kunnen worden opgemerkt.

Bovendien hebben deze controles geen toegang tot het cluster nodig; ze kunnen offline worden uitgevoerd.

Standaard controleert Kubeval bronnen op basis van het nieuwste Kubernetes API-schema. In de meeste gevallen moet u echter mogelijk een specifieke Kubernetes-release controleren. Dit kan gedaan worden met behulp van de vlag --kubernetes-version:

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

Houd er rekening mee dat de versie in het formaat moet worden opgegeven Major.Minor.Patch.

Voor een lijst met versies waarvoor verificatie wordt ondersteund, raadpleegt u JSON-schema op GitHub, die kubeval gebruikt voor validatie. Als u kubeval offline moet uitvoeren, downloadt u de schema's en geeft u hun lokale locatie op met behulp van de vlag --schema-location.

Naast individuele YAML-bestanden kan kubeval ook werken met mappen en stdin.

Bovendien integreert Kubeval eenvoudig in de CI-pijplijn. Degenen die tests willen uitvoeren voordat ze manifesten naar het cluster sturen, zullen blij zijn te weten dat kubeval drie uitvoerformaten ondersteunt:

  1. Platte tekst;
  2. JSON;
  3. Test alles-protocol (TAP).

En elk van de formaten kan worden gebruikt voor het verder analyseren van de uitvoer om een ​​samenvatting van de resultaten van het gewenste type te genereren.

Een van de nadelen van kubeval is dat het momenteel niet kan controleren op naleving van Custom Resource Definitions (CRD's). Het is echter mogelijk om kubeval te configureren negeer hun.

Kubeval is een geweldig hulpmiddel voor het controleren en evalueren van resources; Er moet echter worden benadrukt dat het behalen van de test geen garantie is dat het hulpmiddel voldoet aan de beste praktijken.

Door bijvoorbeeld de tag te gebruiken latest in een container volgt niet de beste praktijken. Kubeval beschouwt dit echter niet als een fout en rapporteert deze niet. Dat wil zeggen dat de verificatie van een dergelijke YAML zonder waarschuwingen wordt voltooid.

Maar wat als u YAML wilt evalueren en overtredingen zoals de tag wilt identificeren latest? Hoe controleer ik een YAML-bestand op basis van best practices?

2. Kube-score

Kube-score parseert YAML-manifesten en evalueert deze aan de hand van ingebouwde tests. Deze tests worden geselecteerd op basis van beveiligingsrichtlijnen en best practices, zoals:

  • De container niet als root uitvoeren.
  • Beschikbaarheid van pod-gezondheidscontroles.
  • Verzoeken en limieten voor resources instellen.

Op basis van de testresultaten worden drie resultaten gegeven: OK, WAARSCHUWING и KRITISCHE.

U kunt Kube-score online proberen of lokaal installeren.

Op het moment dat het originele artikel werd geschreven, was de nieuwste versie van kube-score 1.7.0.

Laten we het uitproberen op ons manifest 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 doorstaat kubeval-tests, terwijl kube-score op de volgende tekortkomingen wijst:

  • Er zijn geen gereedheidscontroles geconfigureerd.
  • Er zijn geen verzoeken of limieten voor CPU-bronnen en geheugen.
  • Budgetten voor podverstoring zijn niet gespecificeerd.
  • Er zijn geen scheidingsregels (anti-affiniteit) om de beschikbaarheid te maximaliseren.
  • De container wordt uitgevoerd als root.

Dit zijn allemaal geldige punten over tekortkomingen die moeten worden aangepakt om de implementatie efficiënter en betrouwbaarder te maken.

Team kube-score geeft informatie weer in een leesbare vorm, inclusief alle typeovertredingen WAARSCHUWING и KRITISCHE, wat veel helpt tijdens de ontwikkeling.

Degenen die deze tool binnen de CI-pijplijn willen gebruiken, kunnen meer gecomprimeerde uitvoer inschakelen met behulp van de vlag --output-format ci (in dit geval worden ook tests met het resultaat weergegeven 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

Net als bij kubeval retourneert kube-score een afsluitcode die niet nul is wanneer er een test is die mislukt KRITISCHE. U kunt ook een soortgelijke verwerking inschakelen voor WAARSCHUWING.

Daarnaast is het mogelijk om resources te controleren op compliance met verschillende API-versies (zoals in kubeval). Deze informatie is echter hardgecodeerd in de kube-score zelf: je kunt geen andere versie van Kubernetes selecteren. Deze beperking kan een groot probleem zijn als u van plan bent uw cluster te upgraden of als u meerdere clusters heeft met verschillende versies van K8s.

Houd er rekening mee dat er is al een probleem met een voorstel om deze kans te realiseren.

Meer informatie over kube-score is te vinden op de officiële website.

Kube-score-tests zijn een geweldig hulpmiddel voor het implementeren van best practices, maar wat als u wijzigingen in de test moet aanbrengen of uw eigen regels moet toevoegen? Helaas, dit kan niet worden gedaan.

Kube-score is niet uitbreidbaar: je kunt er geen beleid aan toevoegen of aanpassen.

Als u aangepaste tests moet schrijven om de naleving van het bedrijfsbeleid te verifiëren, kunt u een van de volgende vier tools gebruiken: config-lint, copper, conftest of polaris.

3.Config-lint

Config-lint is een tool voor het valideren van YAML-, JSON-, Terraform-, CSV-configuratiebestanden en Kubernetes-manifesten.

Je kunt het installeren met behulp van instructies op de projectwebsite.

De huidige release op het moment van schrijven van het originele artikel is 1.5.0.

Config-lint heeft geen ingebouwde tests voor het valideren van Kubernetes-manifesten.

Om tests uit te voeren, moet u passende regels opstellen. Ze zijn geschreven in YAML-bestanden genaamd "rulesets" (regelsets), en hebben de volgende structuur:

version: 1
description: Rules for Kubernetes spec files
type: Kubernetes
files:
  - "*.yaml"
rules:
   # список правил

(rule.yaml)

Laten we het nader bestuderen:

  • Veld type specificeert welk type configuratie config-lint zal gebruiken. Voor K8-manifesten is dit het geval altijd Kubernetes.
  • In het veld files Naast de bestanden zelf kunt u een directory opgeven.
  • Veld rules bedoeld voor het instellen van gebruikerstests.

Stel dat u er zeker van wilt zijn dat afbeeldingen in Deployment altijd worden gedownload vanuit een vertrouwde opslagplaats, zoals my-company.com/myapp:1.0. Een config-lint-regel die een dergelijke controle uitvoert, zou er als volgt uitzien:

- 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)

Elke regel moet de volgende kenmerken hebben:

  • id — unieke identificatiecode van de regel;
  • severity - Misschien MISLUKKING, WAARSCHUWING и NIET_COMPLIANT;
  • message — als een regel wordt overtreden, wordt de inhoud van deze regel weergegeven;
  • resource — het soort hulpbron waarop deze regel van toepassing is;
  • assertions — een lijst met voorwaarden die met betrekking tot deze hulpbron zullen worden geëvalueerd.

In de regel hierboven assertion gerechtigd every controleert of alle containers in implementatie zijn (key: spec.templates.spec.containers) gebruik vertrouwde afbeeldingen (d.w.z. beginnend met my-company.com/).

De volledige regelset ziet er als volgt uit:

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)

Om de test uit te proberen, slaan we hem op als check_image_repo.yaml. Laten we het bestand controleren 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"
  }
]

De controle is mislukt. Laten we nu eens kijken naar het volgende manifest met de juiste afbeeldingsrepository:

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)

We voeren dezelfde test uit met het bovenstaande manifest. Geen problemen gevonden:

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

Config-lint is een veelbelovend raamwerk waarmee u uw eigen tests kunt maken om Kubernetes YAML-manifesten te valideren met behulp van de YAML DSL.

Maar wat als u complexere logica en tests nodig heeft? Is YAML hiervoor niet te beperkt? Wat als u tests in een volledige programmeertaal zou kunnen maken?

4. Koper

Koper V2 is een raamwerk voor het valideren van manifesten met behulp van aangepaste tests (vergelijkbaar met config-lint).

Het verschilt echter van de laatste doordat het geen YAML gebruikt om tests te beschrijven. Tests kunnen in plaats daarvan in JavaScript worden geschreven. Copper biedt een bibliotheek met verschillende basishulpmiddelen, waarmee u informatie over Kubernetes-objecten kunt lezen en fouten kunt rapporteren.

De stappen voor het installeren van Copper zijn te vinden in officiële documentatie.

2.0.1 is de nieuwste versie van dit hulpprogramma op het moment dat het originele artikel werd geschreven.

Net als config-lint heeft Copper geen ingebouwde tests. Laten we er een schrijven. Laat het controleren of implementaties uitsluitend containerimages gebruiken van vertrouwde opslagplaatsen zoals my-company.com.

Maak een bestand check_image_repo.js met de volgende inhoud:

$$.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)
            }
        });
    }
});

Nu gaan we ons manifest testen base-valid.yaml, gebruik de opdracht 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

Het is duidelijk dat je met behulp van koper complexere tests kunt uitvoeren, bijvoorbeeld het controleren van domeinnamen in Ingress-manifesten of het afwijzen van pods die in de geprivilegieerde modus draaien.

In Koper zijn verschillende nutsfuncties ingebouwd:

  • DockerImage leest het opgegeven invoerbestand en maakt een object met de volgende attributen:
    • name - naam van de afbeelding,
    • tag - afbeeldingstag,
    • registry - beeldregistratie,
    • registry_url - protocollen (https://) en beeldregister,
    • fqin — volledige locatie van de afbeelding.
  • Functie findByName helpt bij het vinden van een hulpbron van een bepaald type (kind) en naam (name) uit het invoerbestand.
  • Functie findByLabels helpt bij het vinden van een bron van een opgegeven type (kind) en etiketten (labels).

U kunt alle beschikbare servicefuncties bekijken hier.

Standaard laadt het het volledige invoer-YAML-bestand in een variabele $$ en maakt het beschikbaar voor scripting (een bekende techniek voor mensen met jQuery-ervaring).

Het belangrijkste voordeel van Copper ligt voor de hand: u hoeft geen gespecialiseerde taal te beheersen en u kunt verschillende JavaScript-functies gebruiken om uw eigen tests te maken, zoals stringinterpolatie, functies, enz.

Er moet ook worden opgemerkt dat de huidige versie van Copper werkt met de ES5-versie van de JavaScript-engine, en niet met ES6.

Details beschikbaar op de officiële website van het project.

Als u echter niet echt van JavaScript houdt en de voorkeur geeft aan een taal die specifiek is ontworpen voor het maken van query's en het beschrijven van beleid, moet u aandacht besteden aan conftest.

5. Conftest

Conftest is een raamwerk voor het testen van configuratiegegevens. Ook geschikt voor het testen/verifiëren van Kubernetes-manifesten. Tests worden beschreven met behulp van een gespecialiseerde zoektaal Rego.

U kunt conftest installeren met behulp van instructiesvermeld op de projectwebsite.

Op het moment dat het originele artikel werd geschreven, was de nieuwste beschikbare versie 0.18.2.

Net als config-lint en koper wordt conftest geleverd zonder ingebouwde tests. Laten we het uitproberen en ons eigen beleid schrijven. Net als in eerdere voorbeelden zullen we controleren of de containerimages afkomstig zijn van een betrouwbare bron.

Maak een map conftest-checks, en daarin bevindt zich een bestand met de naam check_image_registry.rego met de volgende inhoud:

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])
}

Laten we nu testen base-valid.yaml door 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

De test mislukte voorspelbaar omdat de beelden afkomstig waren van een onbetrouwbare bron.

In het Rego-bestand definiëren we het blok deny. De waarheid ervan wordt als een overtreding beschouwd. Als blokken deny meerdere, conftest controleert ze onafhankelijk van elkaar, en de waarheid van een van de blokken wordt als een overtreding behandeld.

Naast de standaarduitvoer ondersteunt conftest JSON-, TAP- en tabelindeling - een uiterst nuttige functie als u rapporten moet insluiten in een bestaande CI-pijplijn. Met de vlag kunt u het gewenste formaat instellen --output.

Om het debuggen van beleid makkelijker te maken, heeft conftest een vlag --trace. Het geeft een spoor weer van hoe conftest de opgegeven beleidsbestanden parseert.

Het wedstrijdbeleid kan als artefacten worden gepubliceerd en gedeeld in OCI-registers (Open Container Initiative).

Команды push и pull kunt u een artefact publiceren of een bestaand artefact ophalen uit een extern register. Laten we proberen het beleid dat we hebben gemaakt te publiceren in het lokale Docker-register met behulp van conftest push.

Start uw lokale Docker-register:

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

Ga in een andere terminal naar de map die u eerder hebt gemaakt conftest-checks en voer het volgende commando uit:

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

Als de opdracht succesvol was, ziet u een bericht als dit:

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

Maak nu een tijdelijke map en voer de opdracht daarin uit conftest pull. Het zal het pakket downloaden dat met de vorige opdracht is gemaakt:

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

Er verschijnt een submap in de tijdelijke map policymet daarin ons beleidsbestand:

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

Tests kunnen rechtstreeks vanuit de repository worden uitgevoerd:

$ 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

Helaas wordt DockerHub nog niet ondersteund. Prijs jezelf dus gelukkig als je het gebruikt Azure-containerregister (ACR) of uw eigen register.

Het artefactformaat is hetzelfde als Open Policy Agent-pakketten (OPA), waarmee u conftest kunt gebruiken om tests uit te voeren vanuit bestaande OPA-pakketten.

U kunt meer leren over het delen van beleid en andere functies van conftest op de officiële website van het project.

6. Polaris

De laatste tool die in dit artikel wordt besproken is Polaris. (Zijn aankondiging van vorig jaar wij al vertaald - ca. vert.)

Polaris kan in een cluster worden geïnstalleerd of in de opdrachtregelmodus worden gebruikt. Zoals je misschien al geraden hebt, kun je Kubernetes-manifesten statisch analyseren.

Wanneer u in de opdrachtregelmodus draait, zijn er ingebouwde tests beschikbaar die betrekking hebben op gebieden zoals beveiliging en best practices (vergelijkbaar met kube-score). Daarnaast kunt u uw eigen tests maken (zoals in config-lint, copper en conftest).

Met andere woorden, Polaris combineert de voordelen van beide categorieën tools: met ingebouwde en aangepaste tests.

Gebruik om Polaris in de opdrachtregelmodus te installeren instructies op de projectwebsite.

Op het moment dat het originele artikel werd geschreven, is versie 1.0.3 beschikbaar.

Zodra de installatie is voltooid, kunt u Polaris op het manifest uitvoeren base-valid.yaml met het volgende commando:

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

Er wordt een string in JSON-formaat uitgevoerd met een gedetailleerde beschrijving van de uitgevoerde tests en hun resultaten. De uitvoer heeft de volgende structuur:

{
  "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": [
    /* длинный список */
  ]
}

Volledige output beschikbaar hier.

Net als kube-score identificeert Polaris problemen op gebieden waar het manifest niet voldoet aan de best practices:

  • Er zijn geen gezondheidscontroles voor peulen.
  • Tags voor containerinstallatiekopieën zijn niet opgegeven.
  • De container wordt uitgevoerd als root.
  • Verzoeken en limieten voor geheugen en CPU zijn niet gespecificeerd.

Aan elke test wordt, afhankelijk van de resultaten, een mate van kriticiteit toegekend: waarschuwing of gevaar. Voor meer informatie over de beschikbare ingebouwde tests, zie documentatie.

Als er geen details nodig zijn, kunt u de vlag opgeven --format score. In dit geval zal Polaris een getal uitvoeren tussen 1 en 100 − partituur (d.w.z. beoordeling):

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

Hoe dichter de score bij 100 ligt, hoe hoger de mate van overeenstemming. Als u de afsluitcode van de opdracht controleert polaris audit, het blijkt dat het gelijk is aan 0.

kracht polaris audit U kunt het werk met code die niet nul is, beëindigen met behulp van twee vlaggen:

  • vlag --set-exit-code-below-score neemt als argument een drempelwaarde in het bereik 1-100. In dit geval wordt het commando afgesloten met exitcode 4 als de score onder de drempel ligt. Dit is erg handig als je een bepaalde drempelwaarde hebt (bijvoorbeeld 75) en je een waarschuwing moet krijgen als de score daaronder komt.
  • vlag --set-exit-code-on-danger zal ervoor zorgen dat het commando mislukt met code 3 als een van de gevaartests mislukt.

Laten we nu proberen een aangepaste test te maken die controleert of de afbeelding uit een vertrouwde opslagplaats komt. Aangepaste tests worden gespecificeerd in YAML-indeling en de test zelf wordt beschreven met behulp van JSON Schema.

Het volgende YAML-codefragment beschrijft een nieuwe test genaamd 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/.+$

Laten we het eens nader bekijken:

  • successMessage — deze regel wordt afgedrukt als de test met succes is voltooid;
  • failureMessage — dit bericht wordt weergegeven in geval van een storing;
  • category — geeft een van de categorieën aan: Images, Health Checks, Security, Networking и Resources;
  • target--- bepaalt welk type object (spec)-test wordt toegepast. Mogelijke waarden: Container, Pod of Controller;
  • De test zelf wordt gespecificeerd in het object schema met behulp van JSON-schema. Het sleutelwoord in deze test is pattern gebruikt om de afbeeldingsbron te vergelijken met de vereiste bron.

Om de bovenstaande test uit te voeren, moet u de volgende Polaris-configuratie maken:

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)

Laten we het bestand parseren:

  • In het veld checks tests en hun mate van kriticiteit zijn voorgeschreven. Omdat het wenselijk is om een ​​waarschuwing te krijgen wanneer een afbeelding afkomstig is van een niet-vertrouwde bron, stellen we hier het niveau in danger.
  • De proef zelf checkImageRepo vervolgens geregistreerd in het object customChecks.

Sla het bestand op als custom_check.yaml. Nu kun je rennen polaris audit met een YAML-manifest waarvoor verificatie vereist is.

Laten we ons manifest testen base-valid.yaml:

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

Team polaris audit heeft alleen de hierboven gespecificeerde gebruikerstest uitgevoerd en deze is mislukt.

Als u de afbeelding corrigeert my-company.com/http-echo:1.0, Polaris zal met succes worden voltooid. Het manifest met de veranderingen is al binnen opslagplaatsenzodat u de vorige opdracht op het manifest kunt controleren image-valid-mycompany.yaml.

Nu rijst de vraag: hoe kunnen ingebouwde tests worden uitgevoerd samen met aangepaste tests? Gemakkelijk! U hoeft alleen maar de ingebouwde test-ID's aan het configuratiebestand toe te voegen. Als gevolg hiervan zal het de volgende vorm aannemen:

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)

Er is een voorbeeld van een compleet configuratiebestand beschikbaar hier.

Controleer het manifest base-valid.yamlmet ingebouwde en aangepaste tests kunt u de opdracht gebruiken:

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

Polaris vult de ingebouwde tests aan met op maat gemaakte tests en combineert daarmee het beste van twee werelden.

Aan de andere kant kan het onvermogen om krachtigere talen zoals Rego of JavaScript te gebruiken een beperkende factor zijn die het maken van meer geavanceerde tests verhindert.

Meer informatie over Polaris is beschikbaar op projectsite.

Beknopt

Hoewel er veel tools beschikbaar zijn om Kubernetes YAML-bestanden te inspecteren en evalueren, het is belangrijk om duidelijk te begrijpen hoe de tests zullen worden ontworpen en uitgevoerd.

Bijvoorbeeld Als je Kubernetes-manifesten door een pijplijn laat gaan, zou Kubeval de eerste stap in zo'n pijplijn kunnen zijn. Het zou controleren of objectdefinities voldoen aan het Kubernetes API-schema.

Zodra een dergelijke beoordeling is voltooid, kan men overgaan tot meer geavanceerde tests, zoals de naleving van standaard best practices en specifiek beleid. Dit is waar kube-score en Polaris van pas zouden komen.

Voor degenen die complexe vereisten hebben en tests tot in detail moeten aanpassen, zouden koper, config-lint en conftest geschikt zijn.

Conftest en config-lint gebruiken YAML om aangepaste tests te definiëren, en koper geeft je toegang tot een volledige programmeertaal, waardoor het een behoorlijk aantrekkelijke keuze is.

Aan de andere kant: is het de moeite waard om een ​​van deze tools te gebruiken en daarom alle tests handmatig te maken, of geeft u de voorkeur aan Polaris en voegt u alleen toe wat nodig is? Er is geen duidelijk antwoord op deze vraag.

De onderstaande tabel geeft een korte beschrijving van elk hulpmiddel:

Gereedschap
lot
Beperkingen
Gebruikerstests

kubusval
Valideert YAML-manifesten op basis van een specifieke versie van het API-schema
Kan niet werken met CRD
Geen

kubus-score
Analyseert YAML-manifesten op basis van best practices
Kan uw Kubernetes API-versie niet selecteren om bronnen te controleren
Geen

koper
Een algemeen raamwerk voor het maken van aangepaste JavaScript-tests voor YAML-manifesten
Geen ingebouwde tests. Slechte documentatie
Ja

config-lint
Een algemeen raamwerk voor het maken van tests in een domeinspecifieke taal ingebed in YAML. Ondersteunt verschillende configuratieformaten (bijv. Terraform)
Er zijn geen kant-en-klare tests. Ingebouwde beweringen en functies zijn mogelijk niet voldoende
Ja

betwist
Een raamwerk voor het maken van uw eigen tests met Rego (een gespecialiseerde querytaal). Maakt het delen van beleid via OCI-bundels mogelijk
Geen ingebouwde tests. Ik moet Rego leren. Docker Hub wordt niet ondersteund bij het publiceren van beleid
Ja

Polaris
Beoordeel YAML-manifesten op basis van standaard best practices. Hiermee kunt u uw eigen tests maken met behulp van JSON Schema
Testmogelijkheden op basis van JSON Schema zijn mogelijk niet voldoende
Ja

Omdat deze tools niet afhankelijk zijn van toegang tot het Kubernetes-cluster, zijn ze eenvoudig te installeren. Hiermee kunt u bronbestanden filteren en snelle feedback geven aan de auteurs van pull-aanvragen in projecten.

PS van vertaler

Lees ook op onze blog:

Bron: www.habr.com

Voeg een reactie