Valider Kubernetes YAML mot beste praksis og retningslinjer

Merk. overs.: Med det økende antallet YAML-konfigurasjoner for K8s-miljøer, blir behovet for deres automatiserte verifisering mer og mer presserende. Forfatteren av denne anmeldelsen valgte ikke bare eksisterende løsninger for denne oppgaven, men brukte også Deployment som et eksempel for å se hvordan de fungerer. Det viste seg å være veldig lærerikt for de som er interessert i dette temaet.

Valider Kubernetes YAML mot beste praksis og retningslinjer

TL; DR: Denne artikkelen sammenligner seks statiske verktøy for å validere og evaluere Kubernetes YAML-filer mot beste praksis og krav.

Kubernetes arbeidsbelastninger er vanligvis definert i form av YAML-dokumenter. Et av problemene med YAML er vanskeligheten med å spesifisere begrensninger eller forhold mellom manifestfiler.

Hva om vi må sørge for at alle bilder som er distribuert til klyngen kommer fra et klarert register?

Hvordan kan jeg forhindre at distribusjoner som ikke har PodDisruptionBudgets sendes til klyngen?

Integrasjon av statisk testing lar deg identifisere feil og policybrudd på utviklingsstadiet. Dette øker garantien for at ressursdefinisjoner er korrekte og sikre, og gjør det mer sannsynlig at produksjonsarbeidsmengder følger beste praksis.

Kubernetes statiske YAML-filinspeksjonsøkosystem kan deles inn i følgende kategorier:

  • API-validatorer. Verktøy i denne kategorien kontrollerer YAML-manifestet mot kravene til Kubernetes API-serveren.
  • Klare testere. Verktøy fra denne kategorien kommer med ferdige tester for sikkerhet, overholdelse av beste praksis, etc.
  • Egendefinerte validatorer. Representanter for denne kategorien lar deg lage tilpassede tester på forskjellige språk, for eksempel Rego og Javascript.

I denne artikkelen vil vi beskrive og sammenligne seks forskjellige verktøy:

  1. kubeval;
  2. kube-score;
  3. config-lint;
  4. kobber;
  5. konkurranse;
  6. polaris.

Vel, la oss komme i gang!

Sjekker distribusjoner

Før vi begynner å sammenligne verktøy, la oss lage litt bakgrunn for å teste dem.

Manifestet nedenfor inneholder en rekke feil og manglende overholdelse av beste praksis: hvor mange av dem kan du finne?

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)

Vi vil bruke denne YAML til å sammenligne forskjellige verktøy.

Manifestet ovenfor base-valid.yaml og andre manifester fra denne artikkelen finner du i Git repositories.

Manifestet beskriver en nettapplikasjon hvis hovedoppgave er å svare med en "Hello World"-melding til port 5678. Den kan distribueres med følgende kommando:

kubectl apply -f hello-world.yaml

Og så - sjekk arbeidet:

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

Gå nå til http://localhost:8080 og bekrefte at applikasjonen fungerer. Men følger den beste praksis? La oss sjekke.

1. Kubeval

I hjertet kubeval Tanken er at enhver interaksjon med Kubernetes skjer gjennom REST API. Med andre ord kan du bruke et API-skjema for å sjekke om en gitt YAML samsvarer med det. La oss se på et eksempel.

Installasjonsinstruksjoner kubeval er tilgjengelig på prosjektets nettside.

Da den opprinnelige artikkelen ble skrevet, var versjon 0.15.0 tilgjengelig.

Når den er installert, la oss gi den manifestet ovenfor:

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

Hvis det lykkes, vil kubeval avslutte med utgangskode 0. Du kan sjekke det på følgende måte:

$ echo $?
0

La oss nå prøve kubeval med et annet 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)

Kan du oppdage problemet med øyet? La oss lansere:

$ 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

Ressursen blir ikke verifisert.

Implementeringer som bruker API-versjonen apps/v1, må inkludere en velger som samsvarer med podens etikett. Manifestet ovenfor inkluderer ikke en velger, så kubeval rapporterte en feil og avsluttet med en kode som ikke er null.

Jeg lurer på hva som vil skje hvis jeg gjør det kubectl apply -f med dette manifestet?

Vel, la oss prøve:

$ 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

Dette er akkurat feilen som kubeval advarte om. Du kan fikse det ved å legge til en velger:

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)

Fordelen med verktøy som kubeval er at feil som disse kan fanges opp tidlig i distribusjonssyklusen.

I tillegg krever disse kontrollene ikke tilgang til klyngen, de kan utføres offline.

Som standard sjekker kubeval ressurser mot det nyeste Kubernetes API-skjemaet. Men i de fleste tilfeller må du kanskje sjekke mot en spesifikk Kubernetes-utgivelse. Dette kan gjøres ved hjelp av flagget --kubernetes-version:

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

Vær oppmerksom på at versjonen må spesifiseres i formatet Major.Minor.Patch.

For en liste over versjoner som verifisering støttes for, se JSON-skjema på GitHub, som kubeval bruker for validering. Hvis du trenger å kjøre kubeval offline, last ned skjemaene og spesifiser deres lokale plassering ved å bruke flagget --schema-location.

I tillegg til individuelle YAML-filer, kan kubeval også jobbe med kataloger og stdin.

I tillegg integreres Kubeval enkelt i CI-rørledningen. De som ønsker å kjøre tester før de sender manifester til klyngen, vil gjerne vite at kubeval støtter tre utdataformater:

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

Og hvilket som helst av formatene kan brukes til videre analysering av utdataene for å generere et sammendrag av resultatene av ønsket type.

En av ulempene med kubeval er at den for øyeblikket ikke kan se etter samsvar med Custom Resource Definitions (CRDs). Det er imidlertid mulig å konfigurere kubeval Ignorer dem.

Kubeval er et flott verktøy for å sjekke og evaluere ressurser; Det skal imidlertid understrekes at det å bestå testen ikke garanterer at ressursen er i samsvar med beste praksis.

For eksempel ved å bruke taggen latest i en beholder følger ikke beste praksis. Kubeval anser imidlertid ikke dette som en feil og rapporterer det ikke. Det vil si at verifiseringen av slik YAML vil fullføres uten advarsler.

Men hva om du vil evaluere YAML og identifisere brudd som taggen latest? Hvordan sjekker jeg en YAML-fil mot beste praksis?

2. Kube-score

Kube-score analyserer YAML-manifester og evaluerer dem mot innebygde tester. Disse testene er valgt basert på sikkerhetsretningslinjer og beste praksis, for eksempel:

  • Kjører beholderen ikke som root.
  • Tilgjengelighet av pod-helsesjekker.
  • Angi forespørsler og grenser for ressurser.

Basert på testresultatene gis tre resultater: OK, ADVARSEL и KRITISK.

Du kan prøve Kube-score online eller installere det lokalt.

Da den opprinnelige artikkelen ble skrevet, var den siste versjonen av kube-score 1.7.0.

La oss prøve det på manifestet vårt 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 består kubeval-tester, mens kube-score peker på følgende feil:

  • Beredskapskontroller er ikke konfigurert.
  • Det er ingen forespørsler eller begrensninger for CPU-ressurser og minne.
  • Pod-avbruddsbudsjetter er ikke spesifisert.
  • Det er ingen regler for separasjon (anti-affinitet) for å maksimere tilgjengeligheten.
  • Beholderen kjører som rot.

Dette er alle gyldige punkter om mangler som må løses for å gjøre distribusjonen mer effektiv og pålitelig.

Lag kube-score viser informasjon i lesbar form, inkludert alle type brudd ADVARSEL и KRITISK, som hjelper mye under utviklingen.

De som ønsker å bruke dette verktøyet i CI-rørledningen kan aktivere mer komprimert utgang ved å bruke flagget --output-format ci (i dette tilfellet vises også tester med resultatet 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

I likhet med kubeval, returnerer kube-score en utgangskode som ikke er null når det er en test som mislykkes KRITISK. Du kan også aktivere lignende behandling for ADVARSEL.

I tillegg er det mulig å sjekke ressurser for samsvar med forskjellige API-versjoner (som i kubeval). Imidlertid er denne informasjonen hardkodet i selve kube-poengsummen: du kan ikke velge en annen versjon av Kubernetes. Denne begrensningen kan være et stort problem hvis du har tenkt å oppgradere klyngen din eller hvis du har flere klynger med forskjellige versjoner av K8s.

Vær oppmerksom på det det er allerede et problem med et forslag om å realisere denne muligheten.

Mer informasjon om kube-score finner du på offisiell nettside.

Kube-score-tester er et flott verktøy for å implementere beste praksis, men hva om du trenger å gjøre endringer i testen eller legge til dine egne regler? Akk, dette kan ikke gjøres.

Kube-score kan ikke utvides: du kan ikke legge til retningslinjer eller justere dem.

Hvis du trenger å skrive egendefinerte tester for å bekrefte samsvar med selskapets retningslinjer, kan du bruke ett av følgende fire verktøy: config-lint, copper, conftest eller polaris.

3.Config-lint

Config-lint er et verktøy for å validere YAML, JSON, Terraform, CSV-konfigurasjonsfiler og Kubernetes-manifester.

Du kan installere den ved hjelp av bruksanvisning på prosjektets hjemmeside.

Den nåværende utgivelsen på tidspunktet for skriving av den originale artikkelen er 1.5.0.

Config-lint har ikke innebygde tester for å validere Kubernetes-manifester.

For å gjennomføre noen tester, må du lage passende regler. De er skrevet i YAML-filer kalt "regelsett" (regelsett), og har følgende struktur:

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

(rule.yaml)

La oss studere det nærmere:

  • Feltet type spesifiserer hvilken type konfigurasjon config-lint vil bruke. For K8s manifesterer dette er alltid Kubernetes.
  • I felt files I tillegg til selve filene kan du spesifisere en katalog.
  • Feltet rules beregnet for å sette brukertester.

La oss si at du vil sørge for at bilder i Deployment alltid lastes ned fra et pålitelig depot som my-company.com/myapp:1.0. En config-lint-regel som utfører en slik sjekk vil se slik ut:

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

Hver regel må ha følgende attributter:

  • id – unik identifikator for regelen;
  • severity - Kan være FEIL, ADVARSEL и IKKE_KOMPLIANT;
  • message — hvis en regel brytes, vises innholdet på denne linjen;
  • resource — hvilken type ressurs denne regelen gjelder for;
  • assertions — en liste over forhold som vil bli evaluert i forhold til denne ressursen.

I regelen ovenfor assertion rett every sjekker at alle beholdere er i distribusjon (key: spec.templates.spec.containers) bruk klarerte bilder (dvs. starter med my-company.com/).

Det komplette regelsettet ser slik ut:

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)

For å prøve ut testen, la oss lagre den som check_image_repo.yaml. La oss sjekke filen 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"
  }
]

Kontrollen mislyktes. La oss nå sjekke ut følgende manifest med riktig bildelager:

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)

Vi kjører den samme testen med manifestet ovenfor. Ingen problemer funnet:

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

Config-lint er et lovende rammeverk som lar deg lage dine egne tester for å validere Kubernetes YAML-manifester ved å bruke YAML DSL.

Men hva om du trenger mer kompleks logikk og tester? Er ikke YAML for begrenset til dette? Hva om du kunne lage tester i et fullstendig programmeringsspråk?

4. Kobber

Kobber V2 er et rammeverk for å validere manifester ved å bruke tilpassede tester (ligner på config-lint).

Den skiller seg imidlertid fra sistnevnte ved at den ikke bruker YAML for å beskrive tester. Tester kan skrives i JavaScript i stedet. Copper gir et bibliotek med flere grunnleggende verktøy, som hjelper deg med å lese informasjon om Kubernetes-objekter og rapportere feil.

Trinnene for å installere kobber finner du i offisiell dokumentasjon.

2.0.1 er den siste utgivelsen av dette verktøyet på tidspunktet for skriving av den originale artikkelen.

I likhet med config-lint har ikke Copper innebygde tester. La oss skrive en. La den sjekke at distribusjoner bruker containerbilder utelukkende fra pålitelige depoter som my-company.com.

Opprett en fil check_image_repo.js med følgende innhold:

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

Nå for å teste manifestet vårt base-valid.yaml, bruk kommandoen 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

Det er tydelig at du ved hjelp av kobber kan utføre mer komplekse tester - for eksempel sjekke domenenavn i Ingress-manifester eller avvise pods som kjører i privilegert modus.

Kobber har forskjellige verktøyfunksjoner innebygd:

  • DockerImage leser den angitte inndatafilen og lager et objekt med følgende attributter:
    • name - navnet på bildet,
    • tag - bildekode,
    • registry - bilderegister,
    • registry_url - protokoll (https://) og bilderegister,
    • fqin — fullstendig plassering av bildet.
  • Funksjon findByName hjelper til med å finne en ressurs etter en gitt type (kind) og navn (name) fra inndatafilen.
  • Funksjon findByLabels hjelper til med å finne en ressurs etter en spesifisert type (kind) og etiketter (labels).

Du kan se alle tilgjengelige tjenestefunksjoner her.

Som standard laster den inn hele YAML-inndatafilen til en variabel $$ og gjør det tilgjengelig for skripting (en kjent teknikk for de med jQuery-erfaring).

Hovedfordelen med Copper er åpenbar: du trenger ikke å mestre et spesialisert språk, og du kan bruke ulike JavaScript-funksjoner til å lage dine egne tester, for eksempel strenginterpolasjon, funksjoner, etc.

Det bør også bemerkes at den nåværende versjonen av Copper fungerer med ES5-versjonen av JavaScript-motoren, ikke ES6.

Detaljer tilgjengelig på prosjektets offisielle nettsted.

Men hvis du egentlig ikke liker JavaScript og foretrekker et språk som er spesielt utviklet for å lage spørringer og beskrive retningslinjer, bør du være oppmerksom på conftest.

5. Conftest

Conftest er et rammeverk for testing av konfigurasjonsdata. Også egnet for testing/verifisering av Kubernetes-manifester. Tester beskrives ved hjelp av et spesialisert spørrespråk kløft.

Du kan installere confetest ved å bruke bruksanvisningoppført på prosjektets hjemmeside.

På tidspunktet for skriving av den opprinnelige artikkelen, var den siste tilgjengelige versjonen 0.18.2.

I likhet med config-lint og kobber, kommer conftest uten noen innebygde tester. La oss prøve det ut og skrive vår egen policy. Som i tidligere eksempler vil vi sjekke om beholderbildene er hentet fra en pålitelig kilde.

Opprett en katalog conftest-checks, og i den er det en fil som heter check_image_registry.rego med følgende innhold:

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

La oss nå teste base-valid.yaml gjennom 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

Testen mislyktes forutsigbart fordi bildene kom fra en upålitelig kilde.

I Rego-filen definerer vi blokken deny. Dens sannhet anses som et brudd. Hvis blokkerer deny flere, confetest sjekker dem uavhengig av hverandre, og sannheten til noen av blokkene blir behandlet som et brudd.

I tillegg til standardutgangen, støtter conftest JSON, TAP og tabellformat – en ekstremt nyttig funksjon hvis du trenger å bygge inn rapporter i en eksisterende CI-pipeline. Du kan angi ønsket format ved hjelp av flagget --output.

For å gjøre det enklere å feilsøke retningslinjer, har conftest et flagg --trace. Den gir ut et spor av hvordan conftest analyserer de angitte policyfilene.

Konkurransepolicyer kan publiseres og deles i OCI-registre (Open Container Initiative) som artefakter.

kommandoer push и pull lar deg publisere en artefakt eller hente en eksisterende artefakt fra et eksternt register. La oss prøve å publisere policyen vi opprettet til det lokale Docker-registeret ved hjelp av conftest push.

Start ditt lokale Docker-register:

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

I en annen terminal går du til katalogen du opprettet tidligere conftest-checks og kjør følgende kommando:

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

Hvis kommandoen var vellykket, vil du se en melding som denne:

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

Opprett nå en midlertidig katalog og kjør kommandoen i den conftest pull. Det vil laste ned pakken opprettet av forrige kommando:

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

En underkatalog vil vises i den midlertidige katalogen policysom inneholder policyfilen vår:

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

Tester kan kjøres direkte fra depotet:

$ 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

Dessverre støttes ikke DockerHub ennå. Så betrakt deg selv som heldig hvis du bruker Azure Container Registry (ACR) eller ditt eget register.

Artefaktformatet er det samme som Åpne Policy Agent-pakker (OPA), som lar deg bruke confetest til å kjøre tester fra eksisterende OPA-pakker.

Du kan lære mer om deling av retningslinjer og andre funksjoner ved conftest på prosjektets offisielle nettsted.

6. Polaris

Det siste verktøyet som vil bli diskutert i denne artikkelen er Polaris. (Hans siste års kunngjøring vi allerede oversatt - ca. oversettelse)

Polaris kan installeres i en klynge eller brukes i kommandolinjemodus. Som du kanskje har gjettet, lar den deg statisk analysere Kubernetes-manifester.

Når du kjører i kommandolinjemodus, er innebygde tester tilgjengelige som dekker områder som sikkerhet og beste praksis (ligner på kube-score). I tillegg kan du lage dine egne tester (som i config-lint, copper og confest).

Med andre ord kombinerer Polaris fordelene med begge verktøykategoriene: med innebygde og tilpassede tester.

For å installere Polaris i kommandolinjemodus, bruk instruksjoner på prosjektets hjemmeside.

På tidspunktet for skriving av den originale artikkelen er versjon 1.0.3 tilgjengelig.

Når installasjonen er fullført, kan du kjøre polaris på manifestet base-valid.yaml med følgende kommando:

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

Den vil sende ut en streng i JSON-format med en detaljert beskrivelse av testene som er utført og resultatene deres. Utgangen vil ha følgende struktur:

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

Full utgang tilgjengelig her.

Som kube-score identifiserer Polaris problemer på områder der manifestet ikke oppfyller beste praksis:

  • Det er ingen helsesjekker for pods.
  • Tagger for beholderbilder er ikke spesifisert.
  • Beholderen kjører som rot.
  • Forespørsler og grenser for minne og CPU er ikke spesifisert.

Hver test, avhengig av resultatene, tildeles en grad av kritikalitet: advarsel eller fare. For å lære mer om de tilgjengelige innebygde testene, se dokumentasjon.

Hvis detaljer ikke er nødvendig, kan du spesifisere flagget --format score. I dette tilfellet vil Polaris sende ut et tall fra 1 til 100 − Resultat (dvs. vurdering):

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

Jo nærmere poengsummen er 100, jo høyere grad av samsvar. Hvis du sjekker utgangskoden til kommandoen polaris audit, viser det seg at den er lik 0.

Makt polaris audit Du kan avslutte arbeidet med kode som ikke er null ved å bruke to flagg:

  • flagg --set-exit-code-below-score tar som argument en terskelverdi i området 1-100. I dette tilfellet vil kommandoen avsluttes med utgangskode 4 hvis poengsummen er under terskelen. Dette er veldig nyttig når du har en viss terskelverdi (si 75) og du trenger å motta et varsel hvis poengsummen går under.
  • flagg --set-exit-code-on-danger vil føre til at kommandoen mislykkes med kode 3 hvis en av faretestene mislykkes.

La oss nå prøve å lage en egendefinert test som sjekker om bildet er hentet fra et klarert depot. Egendefinerte tester er spesifisert i YAML-format, og selve testen beskrives ved hjelp av JSON Schema.

Følgende YAML-kodebit beskriver en ny test kalt 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/.+$

La oss se nærmere på det:

  • successMessage — denne linjen vil bli skrevet ut hvis testen fullføres.
  • failureMessage — denne meldingen vil vises i tilfelle feil;
  • category — indikerer en av kategoriene: Images, Health Checks, Security, Networking и Resources;
  • target--- bestemmer hvilken type objekt (spec) test brukes. Mulige verdier: Container, Pod eller Controller;
  • Selve testen er spesifisert i objektet schema bruker JSON-skjema. Nøkkelordet i denne testen er pattern brukes til å sammenligne bildekilden med den nødvendige.

For å kjøre testen ovenfor, må du opprette følgende Polaris-konfigurasjon:

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)

La oss analysere filen:

  • I felt checks tester og deres kritikalitetsnivå er foreskrevet. Siden det er ønskelig å motta en advarsel når et bilde er tatt fra en ikke-klarert kilde, setter vi nivået her danger.
  • Selve testen checkImageRepo deretter registrert i objektet customChecks.

Lagre filen som custom_check.yaml. Nå kan du løpe polaris audit med et YAML-manifest som krever bekreftelse.

La oss teste manifestet vårt base-valid.yaml:

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

Lag polaris audit kjørte kun brukertesten spesifisert ovenfor, og den mislyktes.

Hvis du fikser bildet til my-company.com/http-echo:1.0, vil Polaris fullføre. Manifestet med endringene er allerede inne depoterslik at du kan sjekke forrige kommando på manifestet image-valid-mycompany.yaml.

Nå oppstår spørsmålet: hvordan kjører man innebygde tester sammen med tilpassede? Enkelt! Du trenger bare å legge til de innebygde testidentifikatorene i konfigurasjonsfilen. Som et resultat vil den ha følgende form:

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)

Et eksempel på en komplett konfigurasjonsfil er tilgjengelig her.

Sjekk manifestet base-valid.yamlved å bruke innebygde og tilpassede tester, kan du bruke kommandoen:

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

Polaris kompletterer de innebygde testene med tilpassede tester, og kombinerer dermed det beste fra begge verdener.

På den annen side kan manglende evne til å bruke kraftigere språk som Rego eller JavaScript være en begrensende faktor som hindrer opprettelsen av mer sofistikerte tester.

Mer informasjon om Polaris er tilgjengelig på prosjektnettsted.

Oppsummering

Selv om det er mange tilgjengelige verktøy for å inspisere og evaluere Kubernetes YAML-filer, det er viktig å ha en klar forståelse av hvordan testene skal utformes og utføres.

For eksempel, hvis du tar Kubernetes-manifester som går gjennom en pipeline, kan kubeval være det første trinnet i en slik pipeline. Det vil overvåke om objektdefinisjoner samsvarer med Kubernetes API-skjema.

Når en slik gjennomgang er fullført, kan man gå videre til mer sofistikerte tester, for eksempel overholdelse av standard beste praksis og spesifikke retningslinjer. Det er her kube-score og Polaris vil komme godt med.

For de som har komplekse krav og trenger å tilpasse tester i detalj, vil kobber, config-lint og conftest være passende.

Conftest og config-lint bruker YAML til å definere tilpassede tester, og kobber gir deg tilgang til et fullstendig programmeringsspråk, noe som gjør det til et ganske attraktivt valg.

På den annen side, er det verdt å bruke et av disse verktøyene og derfor lage alle testene manuelt, eller foretrekker Polaris og bare legge til det som trengs? Det er ikke noe klart svar på dette spørsmålet.

Tabellen nedenfor gir en kort beskrivelse av hvert verktøy:

Tool
skjebne
Begrensninger
Brukertester

kubeval
Validerer YAML-manifester mot en spesifikk versjon av API-skjemaet
Kan ikke jobbe med CRD
Ikke

kube-score
Analyserer YAML-manifester mot beste praksis
Kan ikke velge Kubernetes API-versjonen for å sjekke ressurser
Ikke

kobber
Et generelt rammeverk for å lage tilpassede JavaScript-tester for YAML-manifester
Ingen innebygde tester. Dårlig dokumentasjon
Ja

config-lint
Et generelt rammeverk for å lage tester på et domenespesifikt språk innebygd i YAML. Støtter ulike konfigurasjonsformater (f.eks. Terraform)
Det finnes ingen ferdige tester. Innebygde påstander og funksjoner er kanskje ikke nok
Ja

konkurranse
Et rammeverk for å lage dine egne tester ved hjelp av Rego (et spesialisert spørrespråk). Tillater deling av retningslinjer via OCI-pakker
Ingen innebygde tester. Jeg må lære meg Rego. Docker Hub støttes ikke ved publisering av retningslinjer
Ja

Polaris
Anmeldelser YAML manifesterer seg mot standard beste praksis. Lar deg lage dine egne tester ved hjelp av JSON Schema
Testfunksjoner basert på JSON-skjema er kanskje ikke tilstrekkelige
Ja

Fordi disse verktøyene ikke er avhengige av tilgang til Kubernetes-klyngen, er de enkle å installere. De lar deg filtrere kildefiler og gi rask tilbakemelding til forfatterne av pull-forespørsler i prosjekter.

PS fra oversetter

Les også på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar