Validatie van Kubernetes YAML volgens de beste praktijken en beleid

Opmerking vertaler.: Naarmate het aantal YAML-configuraties voor K8s-omgevingen toeneemt, wordt de behoefte aan geautomatiseerde verificatie ervan steeds belangrijker. De auteur van deze review heeft niet alleen bestaande oplossingen voor deze taak verzameld, maar heeft ook gekeken naar hoe ze werken aan de hand van een voorbeeld van een Deployment. Het is zeer informatief voor degenen die geïnteresseerd zijn in dit onderwerp.

Validatie van Kubernetes YAML volgens de beste praktijken en beleid

TL;DR: In dit artikel worden zes statische tools voor het controleren en evalueren van Kubernetes YAML-bestanden vergeleken op overeenkomst met best practices en vereisten.

Kubernetes-werkbelastingen worden doorgaans gedefinieerd in de vorm van YAML-documenten. Een van de problemen met YAML is de complexiteit van het definiëren van beperkingen of relaties tussen manifestbestanden.

Wat als we willen bevestigen dat alle afbeeldingen die in het cluster worden gedeployed, afkomstig zijn van een vertrouwde registry?

Hoe voorkomen we dat er Deployments naar het cluster worden gestuurd waarvoor geen PodDisruptionBudgets zijn ingesteld?

Integratie van statische tests stelt ons in staat om fouten en beleidsinbreuken al in de ontwikkelingsfase te identificeren. Dit verhoogt de garanties voor de juistheid en veiligheid van resource-definities en vergroot de kans dat productiewerkbelastingen de best practices volgen.

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

  • API-validators. Tools in deze categorie controleren het YAML-manifest op overeenstemming met de vereisten van de Kubernetes API-server.
  • Kant-en-klare testers. Tools in deze categorie komen met kant-en-klare tests voor beveiliging, naleving van best practices, enzovoort.
  • Aangepaste validators. Voorstellingen in deze categorie stellen gebruikers in staat om aangepaste tests te maken in verschillende talen, zoals Rego en Javascript.

In dit artikel beschrijven en vergelijken we zes verschillende tools:

  1. kubeval;
  2. kube-score;
  3. config-lint;
  4. copper;
  5. conftest;
  6. Polaris.

Laten we beginnen!

Verificatie van Deployments

Voordat we beginnen met het vergelijken van tools, laten we een basis creëren waarop we ze kunnen testen.

De onderstaande manifest bevat een aantal fouten en inconsistenties met de best practices: hoeveel kunt u 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 te vergelijken.

De bovenstaande manifest base-valid.yaml en andere manifesten uit dit artikel zijn te vinden in features..

De manifest beschrijft een webapplicatie die als primaire taak heeft om een bericht "Hello World" te antwoorden op poort 5678. Het kan worden ingezet met het volgende commando:

kubectl apply -f hello-world.yaml

En zo test je of het werkt:

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

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

1. Kubeval

Kubeval is gebaseerd op het idee dat elke interactie met Kubernetes gebeurt via zijn REST API. Met andere woorden, je kunt het API-schema gebruiken om te controleren of de gegeven YAML daarmee overeenkomt. Laten we een voorbeeld bekijken. Installatie-instructies voor kubeval zijn beschikbaar op de projectwebsite.

Op het moment van schrijven van het originele artikel was versie 0.15.0 beschikbaar. Na installatie laten we het de bovenstaande manifest 'voeden':

$ kubeval base-valid.yaml PASS - base-valid.yaml bevat een geldige Deployment (http-echo) PASS - base-valid.yaml bevat een geldige Service (http-echo)

Bij succes zal kubeval eindigen met exit-code 0. Je kunt dit als volgt controleren:

$ echo $?
0

Laten we nu kubeval proberen met een andere 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

Kun je het probleem met het blote oog zien? Laten we het uitvoeren:

($ kubeval kubeval-invalid.yaml WARN - kubeval-invalid.yaml bevat een ongeldige Deployment (http-echo) - selector: selector is vereist PASS - kubeval-invalid.yaml bevat een geldige Service (http-echo)# laten we de exit-code controleren $ echo $? 1)

De resource heeft de controle niet doorstaan.

Deployments die API-versie gebruiken

, moeten een selector bevatten die overeenkomt met de pod-label. De bovenstaande manifest bevat geen selector, daarom heeft kubeval een foutmelding gegeven en eindigde met een niet-nul exit-code.

Het is interessant om te zien wat er gebeurt als we apps/v1met deze manifest uitvoeren?

Laten we het proberen: kubectl apply -f Wat als we dat doen?

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 waar kubeval voor waarschuwde. U 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 zoals kubeval is dat dergelijke fouten vroeg in de implementatiecyclus kunnen worden afgehandeld.

Bovendien is er voor deze controles geen toegang tot de cluster nodig: ze kunnen offline worden uitgevoerd.

Standaard controleert kubeval bronnen op overeenstemming met het meest recente schema van de Kubernetes API. In de meeste gevallen wil je echter misschien controleren op de overeenstemming met een specifieke release van Kubernetes. Dit kan gedaan worden met de vlag --kubernetes-version:

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

Let op dat de versie moet worden opgegeven in het formaat Major.Minor.Patch.

Om de lijst van versies te bekijken waarvoor validatie wordt ondersteund, ga naar de JSON-schema op GitHub, dat kubeval gebruikt voor validatie. Als u kubeval offline wilt uitvoeren, download dan de schema's en geef hun lokale locatie op met de vlag --schema-location.

Naast afzonderlijke YAML-bestanden kan kubeval ook omgaan met mappen en stdin.

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

  1. Gewone tekst;
  2. JSON;
  3. Test Anything Protocol (TAP).

En elk van de formaten kan worden gebruikt voor verdere parsing van de uitvoer om een samenvatting van de resultaten in de gewenste vorm te genereren.

Een van de nadelen van kubeval is dat het momenteel geen overeenstemming kan controleren met Custom Resource Definitions (CRD's). Het is echter mogelijk om kubeval te negeren.

Kubeval is een uitstekende tool voor het controleren en evalueren van bronnen; echter, het moet benadrukt worden dat het succesvol doorstaan van de test niet garandeert dat de bron voldoet aan de beste praktijken.

Bijvoorbeeld, het gebruik van de tag latest in de container komt niet overeen met de beste praktijken. Echter, kubeval beschouwt dit niet als een fout en rapporteert dit niet. Dit betekent dat de controle van zo'n YAML eindigt zonder waarschuwingen.

Maar wat als het nodig is om de YAML te evalueren en tekortkomingen te identificeren, zoals de tag latest? Как проверить YAML-файл на соответствие лучшим практикам?

2. Kube-score

Kube-score analyseert YAML-manifesten en beoordeelt ze aan de hand van ingebouwde tests. Deze tests zijn geselecteerd op basis van beveiligingsadviezen en beste praktijken, zoals:

  • Het uitvoeren van een container niet als root.
  • Aanwezigheid van health checks voor pods.
  • Het instellen van resource requests en limits.

Na de test worden er drie resultaten gegeven: OK, WAARSCHUWING en CRITIEK.

Kube-score kan online worden geprobeerd of lokaal worden geïnstalleerd.

Op het moment van het schrijven van het oorspronkelijke artikel was de nieuwste versie van kube-score 1.7.0.

Laten we het testen op ons manifest base-valid.yaml:

$ kube-score score base-valid.yaml

apps/v1/Deployment http-echo
[CRITIEK] Container Image Tag
  · http-echo -> Afbeelding met de laatste tag
      Het gebruik van een vaste tag wordt aanbevolen om ongewenste upgrades te vermijden
[CRITIEK] Pod NetworkPolicy
  · De pod heeft geen bijpassend netwerkbeleid
      Maak een NetworkPolicy die deze pod richt
[CRITIEK] Pod Probes
  · Container mist een readinessProbe
      Een readinessProbe moet worden gebruikt om aan te geven wanneer de service klaar is om verkeer te ontvangen.
      Zonder deze, loopt de Pod het risico om verkeer te ontvangen voordat deze is opgestart. Het wordt ook gebruikt tijdens
      uitrol, en kan downtime voorkomen als een nieuwe versie van de applicatie faalt.
      Meer informatie: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[CRITIEK] Container Security Context
  · http-echo -> Container heeft geen geconfigureerde beveiligingscontext
      Stel securityContext in om de container in een veiligere context uit te voeren.
[CRITIEK] Container Resources
  · http-echo -> CPU-limit is niet ingesteld
      Resource-limieten worden aanbevolen om resource DDOS te vermijden. Stel resources.limits.cpu in
  · http-echo -> Geheugenlimiet is niet ingesteld
      Resource-limieten worden aanbevolen om resource DDOS te vermijden. Stel resources.limits.memory in
  · http-echo -> CPU-request is niet ingesteld
      Resource-requests worden aanbevolen om ervoor te zorgen dat de applicatie kan starten en draaien zonder
      te crashen. Stel resources.requests.cpu in
  · http-echo -> Geheugenrequest is niet ingesteld
      Resource-requests worden aanbevolen om ervoor te zorgen dat de applicatie kan starten en draaien zonder te crashen.
      Stel resources.requests.memory in
[CRITIEK] Deployment heeft PodDisruptionBudget
  · Geen bijpassend PodDisruptionBudget gevonden
      Het is aanbevolen om een PodDisruptionBudget te definiëren om onverwachte downtime tijdens Kubernetes
      onderhoudswerkzaamheden te vermijden, zoals wanneer een node wordt geleegd.
[WAARSCHUWING] Deployment heeft host PodAntiAffinity
  · Deployment heeft geen host podAntiAffinity ingesteld
      Het is aanbevolen om een podAntiAffinity in te stellen die voorkomt dat meerdere pods van een deployment
      op dezelfde node worden gepland. Dit verhoogt de beschikbaarheid in het geval dat de node onbeschikbaar wordt.

YAML doorstaat de controles van kubeval, terwijl kube-score op de volgende tekortkomingen wijst:

  • Er zijn geen readiness checks ingesteld.
  • Er zijn geen requests en limits voor CPU en geheugen.
  • Er zijn geen Pod disruption budgets ingesteld.
  • Er ontbreken anti-affinity regels. (anti-affinity) om de beschikbaarheid te maximaliseren.
  • De container draait als root.

Dit zijn allemaal redelijke opmerkingen over tekortkomingen die moeten worden aangepakt om de Deployment efficiënter en betrouwbaarder te maken.

Opdracht kube-score geeft informatie weer in een leesbaar formaat met alle type schendingen inbegrepen, WAARSCHUWING en CRITIEKwat erg helpt tijdens de ontwikkeling.

Degenen die dit hulpmiddel binnen de CI-pijplijn willen gebruiken, kunnen een compacter resultaat inschakelen met de vlag --output-format ci (in dit geval worden ook tests met resultaten 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-limiet is niet ingesteld
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Geheugenlimiet is niet ingesteld
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU-aanvraag is niet ingesteld
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Geheugenaanvraag is niet ingesteld
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Afbeelding met laatste tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: De pod heeft geen passende netwerkbeleid
[CRITICAL] http-echo apps/v1/Deployment: Container mist een readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Container heeft geen geconfigureerde beveiligingscontext
[CRITICAL] http-echo apps/v1/Deployment: Geen passende PodDisruptionBudget gevonden
[WARNING] http-echo apps/v1/Deployment: Deployment heeft geen host podAntiAffinity ingesteld
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service

Evenals kubeval retourneert kube-score een niet-nul uitgangscode bij een test die met een fout is beëindigd. CRITIEKOok kan dergelijke verwerking worden ingeschakeld voor WAARSCHUWING.

Daarnaast is er de mogelijkheid om bronnen te controleren op overeenstemming met verschillende API-versies (zoals in kubeval). Echter, deze informatie is 'hardcoded' in kube-score zelf: andere versies van Kubernetes kiezen kan niet. Deze beperking kan een groot probleem worden als je van plan bent om de cluster te upgraden of als je meerdere clusters met verschillende versies van K8s hebt.

Let op dat er is al een issue met de suggestie om deze mogelijkheid te implementeren.

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

De tests van kube-score zijn een uitstekend hulpmiddel voor het implementeren van best practices, maar wat als het nodig is om een test te wijzigen of je eigen regels toe te voegen? Helaas is dat niet mogelijk.

Kube-score is niet uitbreidbaar: je kunt geen beleidsregels toevoegen of aanpassen.

Als je eigen tests wilt schrijven voor controles op overeenstemming met bedrijfsbeleid, kun je een van de volgende vier tools gebruiken: config-lint, copper, conftest of polaris.

3. Config-lint

Config-lint is een hulpmiddel voor het valideren van configuratiebestanden in de formaten YAML, JSON, Terraform, CSV en Kubernetes-manifesten.

Je kunt het installeren via de instructies op de projectwebsite.

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

Config-lint bevat geen ingebouwde tests voor het controleren van Kubernetes-manifesten.

Voor het uitvoeren van tests moeten de bijbehorende regels worden aangemaakt. Deze worden vastgelegd in YAML-bestanden, die 'regelssets' worden genoemd (rulesets), en hebben de volgende structuur:

version: 1
description: Regels voor Kubernetes specificatiebestanden
type: Kubernetes
files:
  - "*.yaml"
rules:
   # lijst van regels

(rule.yaml)

Laten we het eens nader bekijken:

  • Veld type geeft aan welk type configuratie config-lint zal gebruiken. Voor K8s-manifesten is dat altijd Kubernetes.
  • In het veld files naast de bestanden zelf kan ook een map worden opgegeven.
  • Veld rules is bedoeld voor het specificeren van gebruikersspecifieke tests.

Stel dat je wilt controleren of de afbeeldingen in de Deployment altijd worden gedownload uit een vertrouwd repository, zoals my-company.com/myapp:1.0. De regel voor config-lint die deze controle uitvoert, zal er als volgt uitzien:

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment moet een geldige afbeeldings-tag gebruiken
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

(rule-trusted-repo.yaml)

Voor elke regel moeten de volgende attributen worden opgegeven:

  • id — een unieke identifier voor de regel;
  • severity — kan zijn FAILURE, WAARSCHUWING en NON_COMPLIANT;
  • bericht — wanneer de regel wordt overtreden, wordt de inhoud van deze regel weergegeven;
  • resource — het type bron waarop deze regel van toepassing is;
  • assertions — een lijst van voorwaarden die zullen worden beoordeeld met betrekking tot deze bron.

In de bovenstaande regel assertion StopMovementInTheNextTick every controleert of alle containers in de Deployment (key: spec.templates.spec.containers) vertrouwde afbeeldingen gebruiken (d.w.z., die beginnen met my-company.com/).

De volledige regelsset ziet er als volgt uit:

version: 1
description: Regels voor Kubernetes specificatiebestanden
type: Kubernetes
files:
  - "*.yaml"
rules:

 - id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
    severity: FAILURE
    message: Deployment moet een geldige afbeeldingsrepository gebruiken
    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 voeren, laten we het opslaan als check_image_repo.yaml. Laten we de controle op het bestand uitvoeren. base-valid.yaml:

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

[
  {
  "AssertionMessage": "Elke expressie faalt: En expressie faalt: afbeelding begint niet met 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": "De uitrol moet een geldige afbeeldingsrepository gebruiken",
  "Status": "FAILURE"
  }
]

De controle is mislukt. Laten we nu de volgende manifest met een geldige afbeeldingsrepository controleren:

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 framework waarmee je je eigen tests kunt maken voor het valideren van YAML-manifests van Kubernetes met behulp van YAML DSL.

Maar wat als er meer gecompliceerde logica en tests nodig zijn? Is de mogelijkheden van YAML daar niet te beperkt voor? Wat als we tests konden maken in een echte programmeertaal?

4. Copper

Copper V2 is een framework voor het valideren van manifests met behulp van aangepaste tests (vergelijkbaar met config-lint).

Het verschilt echter van de laatste omdat het geen YAML gebruikt voor het beschrijven van tests. In plaats daarvan kunnen tests worden gemaakt in JavaScript. Copper biedt een bibliotheek met enkele basisinstrumenten, die helpen bij het lezen van informatie over Kubernetes-objecten en het rapporteren van fouten.

De stappen om Copper te installeren vind je in de officiële documentatie.

2.0.1 - de meest recente release van deze tool op het moment van schrijven van het originele artikel.

Net als config-lint heeft Copper geen ingebouwde tests. Laten we er een schrijven. Laat het controleren of de deployments containers afbeeldingen uitsluitend van vertrouwde repositories zoals my-company.com.

Maak een bestand aan 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',"Afbeelding " + $.metadata.name + " is niet van de my-company.com repository", 1)
            }
        });
    }
});

Nu, om onze manifest te controleren base-valid.yaml, gebruik het commando copper validate:

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

Check no_company_repo is mislukt met ernst 1 omdat Afbeelding http-echo niet van de my-company.com repository is
Validatie mislukt

Het is duidelijk dat je met Copper complexere tests kunt uitvoeren - bijvoorbeeld het controleren van domeinnamen in Ingress-manifesten of het afwijzen van pods die draaien in een verhoogde modus.

Copper bevat verschillende hulpfuncties:

  • DockerImage leest het opgegeven invoerbestand en maakt een object aan met de volgende attributen:
    • naam — naam van de afbeelding,
    • tag — tag van de afbeelding,
    • registry — register van afbeeldingen,
    • registry_url — protocol (https://) en register van afbeeldingen,
    • fqin — volledig pad naar de afbeelding.
  • Functie findByName helpt bij het vinden van een resource op basis van een bepaald type (soort) en naam (naam) uit het invoerbestand.
  • Functie findByLabels helpt bij het vinden van een resource op basis van het opgegeven type (soort) en labels (labels).

Je kunt alle beschikbare hulpfuncties bekijken hier.

Standaard laadt hij het volledige invoer-YAML-bestand in een variabele $$ en maakt deze toegankelijk voor scripts (een bekende methode voor degenen die ervaring hebben met jQuery).

Het belangrijkste voordeel van Copper is duidelijk: je hoeft geen gespecialiseerde taal te leren en kunt gebruikmaken van de verschillende mogelijkheden van JavaScript bij het maken van je eigen tests, zoals stringinterpolatie, functies, enz.

Het is ook vermeldenswaard dat de huidige versie van Copper werkt met de ES5-versie van de JavaScript-motor, en niet met ES6.

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

Als je echter niet zo van JavaScript houdt en de voorkeur geeft aan een taal die speciaal is ontworpen voor het maken van vraagstukken en het beschrijven van beleidsregels, moet je conftest overwegen.

5. Conftest

Conftest is een framework voor het valideren van configuratiegegevens. Het is ook geschikt voor het testen/valideren van Kubernetes-manifesten. Tests worden beschreven met behulp van een gespecialiseerde querytaal Rego.

Je kunt conftest installeren via de instructies, zoals aangegeven op de projectwebsite.

Op het moment van schrijven van het oorspronkelijke artikel was versie 0.18.2 de laatste beschikbare editie.

Net als bij config-lint en Copper heeft conftest geen ingebouwde tests. Laten we het eens proberen en ons eigen beleid schrijven. Net als in de voorgaande voorbeelden gaan we controleren of de containerafbeeldingen uit een betrouwbare bron komen.

Maak een map aan conftest-checks, en daarin 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' komt niet uit het my-company.com-register", [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' komt niet uit het my-company.com-register
1 tests, 1 geslaagd, 0 waarschuwingen, 1 mislukking

De test is zoals verwacht mislukt, omdat de afbeeldingen afkomstig zijn uit een niet-vertrouwde bron.

In het Rego-bestand definiëren we het blok deny. De waarheid ervan wordt beschouwd als een schending. Als er meerdere blokken zijn, controleert conftest ze onafhankelijk van elkaar, en de waarheid van elk van de blokken wordt geïnterpreteerd als een schending. deny Naast de standaard uitvoer ondersteunt conftest JSON, TAP en tabelvorm – een uiterst nuttige functie als je rapporten in een bestaand CI-pijplijn wilt integreren. Het vereiste formaat kan worden ingesteld met de vlag

--output Om het debuggen van beleidsregels in conftest te vergemakkelijken, is er een vlag.

--trace . Dit geeft een trace uit van hoe conftest de opgegeven beleidsbestanden parseert.Beleidsregels van conftest kunnen worden gepubliceerd en gedeeld in OCI-registers (Open Container Initiative) als artefacten.

sta de publicatie van een artefact toe of trek een bestaand artefact uit een externe register. Laten we proberen het beleid dat we hebben gemaakt, te publiceren naar een lokale Docker-register met behulp van

Teams push en pull conftest push Start een lokale Docker-register:.

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

Ga in een andere terminal naar de eerder gemaakte directory

$ conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latest conftest-checks en voer de volgende opdracht uit:

Als de opdracht succesvol is uitgevoerd, ziet u een bericht van het volgende type:

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

Maak nu een tijdelijke directory en voer daar de opdracht uit

conftest pull . Hiermee download je het pakket dat door de vorige opdracht is gemaakt:$ cd $(mktemp -d) $ conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

In de tijdelijke directory verschijnt een subdirectory

, die ons beleidsbestand bevat: policy$ 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' komt niet uit de my-company.com repository 2 tests, 1 passed, 0 warnings, 1 failure

Helaas wordt DockerHub momenteel niet ondersteund. Beschouw jezelf dus als gelukkig als je gebruik maakt van

Azure Container Registry (ACR) of je eigen register. Het artefactformaat is hetzelfde als dat van

pakketten van de Open Policy Agent (OPA), wat het mogelijk maakt om conftest te gebruiken voor het uitvoeren van tests uit bestaande OPA-pakketten. Meer over het delen van beleidsregels en andere functies van conftest is te vinden op

6. Polaris de officiële website van het project.

Het laatste hulpmiddel dat in dit artikel aan bod komt, is

(We hebben de aankondiging van vorig jaar al vertaald) Polaris. (Zijn aankondiging van vorig jaar hebben we al vertaald) — opmerking van de vertaler.)

Polaris kan in een cluster worden geïnstalleerd of in de opdrachtregelmodus worden gebruikt. Zoals je al waarschijnlijk hebt geraden, stelt het in staat om statisch de manifesten van Kubernetes te analyseren.

Bij gebruik van de opdrachtregelmodus zijn er ingebouwde tests beschikbaar die gebieden dekken zoals beveiliging en beste praktijken (vergelijkbaar met kube-score). Daarnaast kun je je eigen tests maken (zoals bij config-lint, copper en conftest).

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

Om Polaris in de opdrachtregelmodus te installeren, volg de instructies op de projectwebsite..

Op het moment van schrijven van het originele artikel is versie 1.0.3 beschikbaar.

Na de installatie kun je polaris uitvoeren op een manifest base-valid.yaml met behulp van de volgende opdracht:

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

Het zal een regel in JSON-indeling afdrukken met een gedetailleerde beschrijving van de uitgevoerde tests en hun resultaten. De output zal de volgende structuur hebben:

{
  "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": [
    /* lange lijst */
  ]
}

De volledige output is beschikbaar. hier.

Net als kube-score identificeert Polaris problemen in die gebieden waar het manifest niet voldoet aan de beste praktijken:

  • Er ontbreken gezondheidscontroles voor pods.
  • Er zijn geen tags voor containerafbeeldingen opgegeven.
  • De container draait als root.
  • Er zijn geen aanvragen en limieten voor geheugen en CPU opgegeven.

Aan elke test wordt afhankelijk van de resultaten een kritischiteitsgraad toegekend: warning of danger. Voor meer informatie over de beschikbare ingebouwde tests, raadpleeg de documentatie.

Als de details niet nodig zijn, kun je de vlag opgeven --format score. In dat geval zal Polaris een getal in het bereik van 1 tot 100 afdrukken — score (dat wil zeggen: de 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 conformiteit. Als je de exit-code van de opdracht controleert polaris audit, blijkt dat deze gelijk is aan 0.

Om polaris audit de uitvoering met een niet-nul exit-code te beëindigen, kun je twee vlaggen gebruiken:

  • Vlag --set-exit-code-below-score neemt de drempelwaarde als argument in het bereik van 1-100. In dat geval zal de opdracht eindigen met exit-code 4 als de score onder de drempel ligt. Dit is erg handig wanneer je een bepaalde drempel hebt (bijvoorbeeld 75) en je een alert moet krijgen als de score onder dat niveau daalt.
  • Vlag --set-exit-code-on-danger gevolgt door een afsluiting van de teamcode 3, als een van de danger-tests mislukt.

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

Het volgende fragment van YAML-code beschrijft een nieuwe test genaamd checkImageRepo:

checkImageRepo:
  successMessage: Beeldregister is geldig
  failureMessage: Beeldregister is niet geldig
  category: Afbeeldingen
  target: Container
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

Laten we er eens nader naar kijken:

  • successMessage — deze regel wordt weergegeven als de test succesvol is;
  • failureMessage — dit bericht wordt getoond in het geval van een mislukking;
  • category — geeft een van de categorieën aan: Afbeeldingen, Gezondheidscontroles, Beveiliging, Netwerken en Bronnen;
  • target—- bepaalt op welk type object (spec) de test van toepassing is. Mogelijke waarden zijn: Container, Pod of Controller;
  • De test zelf wordt ingesteld in een object schema met behulp van JSON-schema. In deze test wordt het sleutelwoord pattern gebruikt om de bron van de afbeelding te vergelijken met het vereiste.

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

checks:
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Beeldregister is geldig
    failureMessage: Beeldregister is niet geldig
    category: Afbeeldingen
    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 analyseren:

  • In het veld checks geeft de tests en hun niveaus van kritiek aan. Aangezien het wenselijk is om een waarschuwing te ontvangen wanneer de afbeelding uit een onbetrouwbare bron wordt gehaald, stellen we hier het niveau in danger.
  • De test zelf checkImageRepo wordt vervolgens ingesteld in het object customChecks.

Bewaar het bestand als custom_check.yaml. U kunt nu een polaris audit uitvoeren met een YAML-manifest dat controle vereist.

Laten we ons manifest testen base-valid.yaml:

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

Opdracht polaris audit heeft alleen de hierboven gedefinieerde aangepaste test uitgevoerd, en deze was niet succesvol.

Als u de afbeelding wijzigt naar my-company.com/http-echo:1.0, zal Polaris succesvol afsluiten. Het manifest met de wijzigingen is al aanwezig in de repository, dus u kunt het vorige commando op het manifest controleren. image-valid-mycompany.yaml.

Nu rijst de vraag: hoe voer je ingebouwde tests samen met aangepaste tests uit? Dat is eenvoudig! U hoeft alleen de identificatoren van de ingebouwde tests aan het configuratiebestand toe te voegen. Het resultaat ziet er dan als volgt uit:

controles:
  cpuRequestsMissing: waarschuwing
  cpuLimitsMissing: waarschuwing
  # Andere ingebouwde controles..
  # ..
  # aangepaste controles
  checkImageRepo: gevaar # !!!
aangepasteControles:
  checkImageRepo:        # !!!
    successMessage: Afbeeldingsregister is geldig
    failureMessage: Afbeeldingsregister is ongeldig
    category: Afbeeldingen
    target: Container
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(config_met_aangepaste_controle.yaml)

Voorbeeld van een volledige configuratie is beschikbaar hier.

Controleer manifest base-valid.yaml, door gebruik te maken van ingebouwde en aangepaste tests kan worden gedaan met het commando:

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

Polaris voegt aangepaste tests toe aan de ingebouwde tests, en combineert zo het beste van twee werelden.

Aan de andere kant kan de onmogelijkheid om krachtigere talen zoals Rego of JavaScript te gebruiken een beperkende factor zijn die het creëren van meer geavanceerde tests voorkomt.

Extra informatie over Polaris is beschikbaar op de projectwebsite.

Samenvatting

Hoewel er veel tools zijn voor het controleren en evalueren van YAML-bestanden van Kubernetes, is het belangrijk om een duidelijk beeld te hebben van hoe tests worden ontworpen en uitgevoerd.

Bijvoorbeeld, als we kijken naar Kubernetes-manifesten die door de pipeline gaan, kan kubeval de eerste stap in zo'n pipeline zijn. Het zou controleren of de objectdefinities voldoen aan de Kubernetes API-schema.

Na het voltooien van een dergelijke controle kan worden overgegaan tot meer geavanceerde tests, zoals naleving van de standaard best practices en specifieke beleidsregels. En hier zouden kube-score en Polaris nuttig zijn.

Voor degenen met complexe vereisten en de noodzaak om tests gedetailleerd aan te passen, zouden copper, config-lint en conftest geschikt zijn..

Conftest en config-lint gebruiken YAML voor het definiëren van aangepaste tests, terwijl copper toegang biedt tot een volledige programmeertaal, wat het een vrij aantrekkelijke keuze maakt.

Aan de andere kant, is het de moeite waard om een van deze tools te gebruiken en dus alle tests handmatig te maken, of liever Polaris en alleen toe te voegen wat nodig is? Er is geen eenduidig antwoord op deze vraag..

De onderstaande tabel bevat een beknopte beschrijving van elke tool:

Hulpmiddel
Het doel
Nadelen
Aangepaste tests

Installatie-instructies voor
Controleert YAML-manifesten op overeenstemming met een specifieke versie van het API-schema
Kan niet werken met CRD
No

kube-score
Analyseert YAML-manifesten op naleving van best practices
Je kunt je eigen Kubernetes API-versie voor het controleren van hulpbronnen niet kiezen
No

copper
Algemene framework voor het creëren van eigen JavaScript-tests voor YAML-manifesten
Geen ingebouwde tests. Beperkte documentatie
Yes

config-lint
Algemeen framework voor het creëren van tests in een op objecten gebaseerde taal, ingebouwd in YAML. Ondersteunt verschillende configuratieformaten (bijvoorbeeld Terraform)
Geen kant-en-klare tests. Ingebouwde assertions en functies kunnen onvoldoende zijn
Yes

conftest
Framework voor het creëren van eigen tests in Rego (een gespecialiseerde query-taal). Maakt het mogelijk om beleid te delen via OCI-bundels
Geen ingebouwde tests. Je moet Rego leren. Docker Hub wordt niet ondersteund bij het publiceren van beleid
Yes

Polaris
Analyseert YAML-manifesten op overeenstemming met standaard beste praktijken. Maakt het mogelijk om eigen tests te creëren met behulp van JSON-schema
De mogelijkheden voor tests gebaseerd op JSON-schema kunnen onvoldoende zijn
Yes

Aangezien deze tools niet afhankelijk zijn van toegang tot de Kubernetes-cluster, zijn ze gemakkelijk te installeren. Ze kunnen bronbestanden filteren en bieden snelle feedback aan auteurs van pull requests in projecten.

P.S. van de vertaler

Lees ook op onze blog:

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster