Bem. overs.: Med det stigende antal YAML-konfigurationer til K8s-miljøer bliver behovet for deres automatiserede kontrol stadig mere aktuelt. Forfatteren af denne gennemgang har ikke blot udvalgt eksisterende løsninger til denne opgave, men har også set på, hvordan de fungerer ved hjælp af et eksempel med Deployment. Det er blevet meget informativt for dem, der er interesseret i emnet.

TL;DR: Artiklen sammenligner seks statiske værktøjer til kontrol og evaluering af Kubernetes YAML-filer i forhold til bedste praksis og krav.
Kubernetes arbejdsbyrder defineres normalt i form af YAML-dokumenter. Et af problemerne med YAML er kompleksiteten i at angive begrænsninger eller relationer mellem manifestfiler.
Hvad hvis vi skal sikre os, at alle billeder, der implementeres i klusteret, kommer fra et betroet register?
Hvordan forhindrer man at sende Deployments til klusteret, for hvilke der ikke er angivet PodDisruptionBudgets?
Integration af statisk testning gør det muligt at opdage fejl og overtrædelser af politikker allerede i udviklingsfasen. Dette øger garantierne for korrekthed og sikkerhed i ressourcehenvisningerne og øger sandsynligheden for, at produktionsarbejdsbyrderne følger bedste praksis.
Økosystemet for statisk kontrol af Kubernetes YAML-filer kan opdeles i følgende kategorier:
- API-valideringsværktøjer. Værktøjer i denne kategori tjekker YAML-manifestet for overholdelse af kravene fra Kubernetes API-server.
- Færdige testværktøjer. Værktøjer fra denne kategori leveres med færdige tests for sikkerhed, overholdelse af bedste praksis osv.
- Tilpassede valideringsværktøjer. Repræsentanter i denne kategori tillader oprettelse af brugerdefinerede tests på forskellige sprog, såsom Rego og Javascript.
I denne artikel vil vi beskrive og sammenligne seks forskellige værktøjer:
- kubeval;
- kube-score;
- config-lint;
- copper;
- conftest;
- Polaris.
Lad os komme i gang!
Kontrol af Deployments
Før vi begynder at sammenligne værktøjerne, lad os oprette et fundament, som vi kan teste dem på.
Det følgende manifest indeholder en række fejl og overtrædelser af bedste praksis: hvor mange af dem kan du finde?
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 bruge denne YAML til at sammenligne forskellige værktøjer.
Manifestet ovenfor
base-valid.yamlog andre manifester fra denne artikel kan findes i .
Manifestet beskriver en webapplikation, hvis primære opgave er at svare med beskeden "Hello World" på port 5678. Det kan deployeres med følgende kommando:
kubectl apply -f hello-world.yamlOg sådan kan vi tjekke, om det virker:
kubectl port-forward svc/http-echo 8080:5678Gå nu til og bekræft, at applikationen fungerer. Men følger den bedste praksis? Lad os tjekke.
1. Kubeval
Grundlaget for er idéen om, at enhver interaktion med Kubernetes sker via dens REST API. Med andre ord kan vi bruge API-skemaet til at kontrollere, om den pågældende YAML overholder det. Lad os se et eksempel.
kubeval er tilgængelig på projektets hjemmeside.
På tidspunktet for skrivningen af den originale artikel var version 0.15.0 tilgængelig.
Efter installationen lad os "fodre" den med manifestet, der er angivet ovenfor:
$ kubeval base-valid.yaml
PASS - base-valid.yaml indeholder et gyldigt Deployment (http-echo)
PASS - base-valid.yaml indeholder en gyldig Service (http-echo)I tilfælde af succes afslutter kubeval med exit-kode 0. Vi kan tjekke det således:
$ echo $?
0Lad os nu prøve kubeval med et andet 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 se problemet ved første øjekast? Kør:
$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml indeholder et ugyldigt Deployment (http-echo) - selector: selector er påkrævet
PASS - kubeval-invalid.yaml indeholder en gyldig Service (http-echo)
# lad os tjekke exit-koden
$ echo $?
1Ressourcen består ikke.
Deployments, der bruger API-version apps/v1, skal inkludere en selector, der matcher pod'ets label. Manifestet ovenfor inkluderer ikke en selector, så kubeval gav en fejl og afsluttede med en ikke-nul kode.
Det er interessant at se, hvad der sker, hvis vi kører kubectl apply -f med dette manifest?
Nå, lad os 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=falseDet er præcist den fejl, som kubeval advarede om. Den kan rettes ved at tilføje en selector:
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 ved værktøjer som kubeval er, at sådanne fejl kan fanges tidligt i deploymentscyklussen.
Desuden kræver disse kontroller ikke adgang til klyngen: de kan udføres offline.
Som standard kontrollerer kubeval ressourcer mod den seneste schema for Kubernetes API. Dog kan det i mange tilfælde være nødvendigt at kontrollere mod en specifik version af Kubernetes. Dette kan gøres med flaget --kubernetes-version:
$ kubeval --kubernetes-version 1.16.1 base-valid.yamlBemærk, at versionen skal angives i formatet Major.Minor.Patch.
For at se listen over versioner, som validering understøtter, kan du henvise til , som kubeval bruger til validering. Hvis du skal køre kubeval offline, kan du downloade skemaerne og angive deres lokale placering med flaget --schema-location.
Udover enkeltstående YAML-filer kan kubeval også arbejde med mapper og stdin.
Derudover integreres Kubeval nemt i CI-pipelines. De, som ønsker at foretage tests, inden de sender manifester til klyngen, vil sætte pris på, at kubeval understøtter tre outputformater:
- Løst tekst;
- JSON;
- Test Anything Protocol (TAP).
Og ethvert af formaterne kan bruges til yderligere parsing af output for at danne en opsummering af resultaterne i den ønskede form.
En af ulemperne ved kubeval er, at det i øjeblikket ikke kan validere mod Custom Resource Definitions (CRDs). Men kubeval kan konfigureres til .
Kubeval er et fremragende værktøj til at validere og evaluere ressourcer; dog skal det understreges, at en vellykket test ikke garanterer, at ressourcen opfylder bedste praksis.
For eksempel brugen af tagget latest I containeren overholder ikke de bedste praksisser. Men kubeval betragter ikke dette som en fejl og giver ikke besked om det. Det vil sige, at kontrollen af sådan YAML afsluttes uden advarsler.
Men hvad hvis man skal vurdere YAML og identificere overtrædelser som tag latest? Как проверить YAML-файл на соответствие лучшим практикам?
2. Kube-score
analyserer YAML-manifestationer og vurderer dem ud fra indbyggede tests. Disse tests vælges baseret på sikkerhedsanbefalinger og bedste praksis, for eksempel:
- Køre containeren ikke som root.
- Tilstedeværelsen af sundhedstjek af pods.
- Angivelse af anmodninger og begrænsninger for ressourcer.
Efter testen gives der tre resultater: OK, ADVARSEL og KRITISK.
Kube-score kan prøves online eller installeres lokalt.
På tidspunktet for skrivningen af den originale artikel var den nyeste version af kube-score 1.7.0.
Lad os prøve det på vores manifest base-valid.yaml:
$ kube-score score base-valid.yaml
apps/v1/Deployment http-echo
[KRITISK] Containerbilledetag
· http-echo -> Billede med nyeste tag
Det anbefales at bruge et fast tag for at undgå utilsigtede opgraderinger
[KRITISK] Pod NetworkPolicy
· Pod'en har ikke en matchende netværkspolitik
Opret en NetworkPolicy, der retter sig mod denne pod
[KRITISK] Pod Probes
· Container mangler et readinessProbe
Et readinessProbe bør bruges til at angive, hvornår tjenesten er klar til at modtage trafik.
Uden det risikerer pod'en at modtage trafik, før den er startet. Det bruges også under
opdateringer og kan forebygge nedetid, hvis en ny version af applikationen fejler.
Mere information: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[KRITISK] Container Security Context
· http-echo -> Container har ikke konfigureret sikkerhedskontekst
Indstil securityContext for at køre containeren i en mere sikker kontekst.
[KRITISK] Containerressourcer
· http-echo -> CPU-grænsen er ikke sat
Ressourcegrænser anbefales for at undgå ressource DDOS. Sæt resources.limits.cpu
· http-echo -> Hukommelsesgrænsen er ikke sat
Ressourcegrænser anbefales for at undgå ressource DDOS. Sæt resources.limits.memory
· http-echo -> CPU-anmodningen er ikke sat
Resourceanmodninger anbefales for at sikre, at applikationen kan starte og køre uden
at fejle. Sæt resources.requests.cpu
· http-echo -> Hukommelsesanmodningen er ikke sat
Resourceanmodninger anbefales for at sikre, at applikationen kan starte og køre uden at fejle.
Sæt resources.requests.memory
[KRITISK] Deployment har PodDisruptionBudget
· Ingen matchende PodDisruptionBudget blev fundet
Det anbefales at definere et PodDisruptionBudget for at undgå uventet nedetid under Kubernetes
vedligeholdelsesoperationer, såsom når en node drænes.
[ADVARSEL] Deployment har host PodAntiAffinity
· Deployment har ikke en host podAntiAffinity sat
Det anbefales at sætte en podAntiAffinity, der forhindrer flere pods fra et deployment i
at blive planlagt på samme node. Dette øger tilgængeligheden, hvis noden bliver utilgængelig.YAML bestået tests fra kubeval, mens kube-score peger på følgende mangler:
- Ingen readiness checks er konfigureret.
- Manglende anmodninger og grænser for CPU- og hukommelsesressourcer.
- Ingen Pod disruption budgets er angivet.
- Manglende regler for anti-affinity (anti-affinity) for at maksimere tilgængeligheden.
- Containeren kører som root.
Alt dette er rimelige bemærkninger om mangler, som bør rettes for at gøre Deployment mere effektiv og pålidelig.
Kommandoen kube-score giver information på en letlæselig måde med inkluderede overtrædelser af typen ADVARSEL og KRITISK, hvilket hjælper meget under udviklingen.
De, der ønsker at bruge dette værktøj i CI-pipelinen, kan inkludere en mere kompakt output ved hjælp af flaget --output-format ci (i dette tilfælde vises også test med resultaterne 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-grænsen er ikke sat
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Hukommelsesgrænsen er ikke sat
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU-anmodningen er ikke sat
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Hukommelsesanmodningen er ikke sat
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Billede med den nyeste tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: Pod’en har ikke en matchende netværkspolitik
[CRITICAL] http-echo apps/v1/Deployment: Container mangler en readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Container har ikke konfigureret sikkerhedskontekst
[CRITICAL] http-echo apps/v1/Deployment: Ingen matchende PodDisruptionBudget blev fundet
[WARNING] http-echo apps/v1/Deployment: Deployment har ikke host podAntiAffinity sat
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/ServiceI lighed med kubeval returnerer kube-score en ikke-nul exitkode ved fejlslagne tests. KRITISK. Det er også muligt at inkludere lignende håndtering for ADVARSEL.
Derudover er der mulighed for at kontrollere ressourcer for overensstemmelse med forskellige API-versioner (ligesom i kubeval). Men denne information er 'hardcoded' i selve kube-score: det er ikke muligt at vælge en anden version af Kubernetes. En sådan begrænsning kan blive et stort problem, hvis du planlægger at opdatere dit cluster eller har flere clusters med forskellige versioner af K8s.
Bemærk venligst, at med et forslag om at implementere denne mulighed.
Læs mere om kube-score på .
Kube-scores tests er et fremragende værktøj til at implementere bedste praksis, men hvad hvis det er nødvendigt at ændre en test eller tilføje egne regler? Desværre er det ikke muligt.
Kube-score er ikke udvideligt: det er ikke muligt at tilføje eller tilpasse politikker.
Hvis der er behov for at skrive brugerdefinerede tests for overholdelsespolitikker, kan du bruge et af følgende fire værktøjer: config-lint, copper, conftest eller polaris.
3. Config-lint
Config-lint er et værktøj til validering af konfigurationsfiler i formaterne YAML, JSON, Terraform, CSV og Kubernetes-manifester.
Det kan installeres ved hjælp af på projektets hjemmeside.
Den nuværende version pr. tidspunktet for skrivningen af den originale artikel er 1.5.0.
Config-lint indeholder ikke indbyggede tests til kontrol af Kubernetes-manifester.
For at udføre tests skal der oprettes de relevante regler. De skrives i YAML-filer, kaldet "regelsæt" (rulesets), og har følgende struktur:
version: 1
description: Regler for Kubernetes-spec-filer
type: Kubernetes
files:
- "*.yaml"
rules:
# liste over regler(rule.yaml)
Lad os se nærmere på det:
- Felt
typeangiver, hvilken type konfiguration config-lint vil bruge. For K8s-manifester er det altidKubernetes. - I feltet
filesudover selve filerne kan du angive en mappe. - Felt
ruleser beregnet til at angive brugerdefinerede tests.
Antag, at du ønsker at sikre dig, at billeder i Deployment altid hentes fra et pålideligt repository som my-company.com/myapp:1.0. Reglen for config-lint, der udfører denne kontrol, vil se således ud:
- id: MY_DEPLOYMENT_IMAGE_TAG
severity: FAILURE
message: Deployment skal bruge et gyldigt billede-tag
resource: Deployment
assertions:
- every:
key: spec.template.spec.containers
expressions:
- key: image
op: starts-with
value: "my-company.com/"(rule-trusted-repo.yaml)
For hver regel skal følgende attributter angives:
id— en unik identifikator for reglen;severity— kan være FAILURE, ADVARSEL og NON_COMPLIANT;message— indholdet af denne linje vises, hvis reglen brydes;resource— typen af ressource, som denne regel gælder for;assertions— en liste over betingelser, der vil blive evalueret i forhold til denne ressource.
I reglen ovenfor assertion med navnet kontrollerer, at alle containere i Deployment ('key: spec.templates.spec.containers') bruger pålidelige billeder (dvs. som starter med my-company.com/).
Det fulde regelsæt ser således ud:
version: 1
description: Regler for Kubernetes spec-filer
type: Kubernetes
files:
- "*.yaml"
rules:
- id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
severity: FAILURE
message: Deployment skal bruge et gyldigt billedrepository
resource: Deployment
assertions:
- every:
key: spec.template.spec.containers
expressions:
- key: image
op: starts-with
value: "my-company.com/"(ruleset.yaml)
For at teste reglen, lad os gemme den som check_image_repo.yaml. Lad os køre kontrollen på filen base-valid.yaml:
$ config-lint -rules check_image_repo.yaml base-valid.yaml
[
{
"AssertionMessage": "Hver expression fejler: Og udtryk fejler: billedet starter ikke med 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 skal bruge et gyldigt billederepositorium",
"Status": "FAILURE"
}
]Kontrollen mislykkedes. Lad os nu teste den næste manifest med et korrekt billederepositorium:
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)
Kører den samme test med den foregående manifest. Ingen problemer opdaget:
$ config-lint -rules check_image_repo.yaml image-valid-mycompany.yaml
[]Config-lint er et lovende framework, der muliggør oprettelse af brugerdefinerede tests til validering af YAML-manifester til Kubernetes ved hjælp af YAML DSL.
Men hvad skal man gøre, hvis der kræves mere kompleks logik og tests? Er YAML's muligheder ikke for små til dette? Hvad hvis man kunne oprette tests i et fuldt programmeringssprog?
4. Copper
er et framework til validering af manifester ved hjælp af brugerdefinerede tests (som config-lint).
Men i modsætning til det sidste bruger det ikke YAML til at beskrive tests. I stedet kan tests oprettes i JavaScript. Copper stiller et bibliotek til rådighed med flere grundlæggende værktøjer, der hjælper med at indsamle oplysninger om Kubernetes-objekter og rapportere fejl.
Trin-for-trin vejledningen til installation af Copper kan findes i .
2.0.1 — den nyeste version af dette værktøj på tidspunktet for den originale artikel.
Ligesom config-lint har Copper ikke indbyggede tests. Lad os skrive en. Den skal kontrollere, at deployments kun bruger containerbilleder fra betroede repositorier som my-company.com.
Opret en fil check_image_repo.js med følgende indhold:
$$.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 + " er ikke fra my-company.com repo", 1)
}
});
}
});Nu, for at validere vores manifest base-valid.yaml, brug kommandoen copper validate:
$ copper validate --in=base-valid.yaml --validator=check_image_tag.js
Check no_company_repo mislykkedes med alvorlighed 1 på grund af, at billedet http-echo ikke er fra my-company.com repo
Validering mislykkedesDet er klart, at man med Copper kan udføre mere komplekse tests - for eksempel kontrollere domænenavne i Ingress-manifester eller afvise pods, der kører i privilegeret tilstand.
Copper har indbygget forskellige hjælpefunktioner:
DockerImagelæsser den specificerede inputfil og opretter et objekt med følgende attributter:name— navnet på billedet,tag— tag for billedet,registry— billedregister,registry_url— protokol (https://) og billedregister,fqin— den fulde placering af billedet.
- Funktion
findByNamehjælper med at finde en ressource efter den angivne type (kind) og navn (name) fra inputfilen. - Funktion
findByLabelshjælper med at finde en ressource efter den angivne type (kind) og etiketter (labels).
Du kan få et overblik over alle tilgængelige hjælpefunktioner .
Som standard indlæser den hele input-YAML-filen i variablen $$ og gør den tilgængelig for scripts (en velkendt metode for dem, der har erfaring med jQuery).
Den største fordel ved Copper er åbenlys: du behøver ikke at lære et specialiseret sprog, og du kan bruge forskellige muligheder fra JavaScript til at lave dine egne tests, såsom strengeinterpolering, funktioner osv.
Det skal også bemærkes, at den nuværende version af Copper arbejder med ES5-versionen af JavaScript-motoren og ikke med ES6.
Detaljer er tilgængelige på .
Men hvis du ikke er særlig glad for JavaScript og foretrækker et sprog, der er specielt beregnet til at lave forespørgsler og beskrive politikker, bør du kigge på conftest.
5. Conftest
Conftest er et framework til at verificere konfigurationsdata. Det er også velegnet til testning/validering af Kubernetes-manifester. Tests beskrives ved hjælp af et specialiseret forespørgselssprog .
Du kan installere conftest ved hjælp af , som angivet på projektets websted.
På tidspunktet for skrivningen af den oprindelige artikel var den senest tilgængelige version 0.18.2.
Som med config-lint og copper kommer conftest uden indbyggede tests. Lad os prøve det og skrive vores egen politik. Som i de tidligere eksempler vil vi kontrollere, om containerbillederne stammer fra en pålidelig kilde.
Opret en mappe conftest-checks, og i den — en fil med navnet check_image_registry.rego med følgende indhold:
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])
}Lad os nu teste base-valid.yaml gennem conftest:
$ conftest test --policy ./conftest-checks base-valid.yaml
FEJL - base-valid.yaml - billed 'hashicorp/http-echo' kommer ikke fra my-company.com repository
1 tests, 1 bestået, 0 advarsler, 1 fejlTesten mislykkedes som forventet, da billederne kommer fra en ubetroet kilde.
I Rego-filen definerer vi en blok deny. Dens sandhed betragtes som en overtrædelse. Hvis der er flere blokke, deny kontrollerer conftest dem uafhængigt af hinanden, og sandheden af nogen af blokke fortolkes som en overtrædelse.
Udover standard output understøtter conftest JSON, TAP og tabel-format — en ekstremt nyttig funktion, hvis man har brug for at integrere rapporter i den eksisterende CI-pipeline. Den ønskede format kan angives med flaget --output.
For at lette fejlretningen af politikker har conftest et flag --trace. Det viser en trace af, hvordan conftest parser de angivne politikfiler.
Conftest-politikker kan offentliggøres og deles i OCI-lagre (Open Container Initiative) som artefakter.
Kommandoer push og pull giver mulighed for at offentliggøre en artefakt eller hente en eksisterende artefakt fra et fjernt lager. Lad os prøve at offentliggøre den politik, vi har oprettet, i et lokalt Docker-lager ved hjælp af conftest push.
Start et lokalt Docker-lager:
$ docker run -it --rm -p 5000:5000 registryI et andet terminalvindue skal du gå til den tidligere oprettede mappe conftest-checks og køre følgende kommando:
$ conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latestHvis kommandoen var vellykket, vil du se en meddelelse af denne type:
2020/06/10 14:25:43 pushed bundle with digest: sha256:e9765f201364c1a8a182ca637bc88201db3417bacc091e7ef8211f6c2fd2609cOpret nu en midlertidig mappe, og kør kommandoen conftest pull. Det vil downloade det pakket, der blev oprettet af den tidligere kommando:
$ cd $(mktemp -d)
$ conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latestI den midlertidige mappe vil der komme en undermappe policy, som indeholder vores politikfil:
$ tree
.
└── policy
└── check_image_registry.regoTests kan udføres direkte fra repository:
$ conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
FEJL - base-valid.yaml - billed 'hashicorp/http-echo' kommer ikke fra my-company.com repository
2 tests, 1 bestået, 0 advarsler, 1 fejlDesværre understøttes DockerHub ikke endnu. Så betragt dig selv heldig, hvis du bruger (ACR) eller dit eget lager.
Artefaktformatet er det samme som for (OPA), hvilket gør det muligt at bruge conftest til at køre tests fra eksisterende OPA-pakker.
Mere om deling af politikker og andre funktioner i conftest kan findes på .
6. Polaris
Det sidste værktøj, vi skal tale om i denne artikel, er . (Vi har allerede oversat hans annoncering fra sidste år — ft. overs.)
Polaris kan installeres i en klynge eller bruges i kommandolinjetilstand. Som du allerede har gættet, tillader det statisk analyse af Kubernetes-manifester.
Når du arbejder i kommandolinjetilstand, er der indbyggede tests tilgængelige, der dækker områder som sikkerhed og bedste praksis (svarende til kube-score). Derudover kan du oprette dine egne tests (ligesom i config-lint, copper og conftest).
Med andre ord kombinerer Polaris fordelene fra begge typer værktøjer: med indbyggede og brugerdefinerede tests.
For at installere Polaris i kommandolinjetilstand, brug .
På tidspunktet for skrivning af denne artikel var version 1.0.3 tilgængelig.
Når installationen er afsluttet, kan du køre polaris på manifestet base-valid.yaml ved hjælp af følgende kommando:
$ polaris audit --audit-path base-valid.yamlDen vil returnere en JSON-streng med en detaljeret beskrivelse af de udførte tests og deres resultater. Outputtet vil have 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": [
/* lang liste */
]
}Den fulde output er tilgængelig .
Ligesom kube-score identificerer Polaris problemer i de områder, hvor manifestet ikke overholder bedste praksis:
- Sundhedstjek for pods mangler.
- Der er ikke angivet tags for containerbillederne.
- Containeren kører som root.
- Der er ikke specificeret requests og limits for hukommelse og CPU.
Hver test tildeles en kritikalitetsgrad afhængigt af dens resultater: warning eller danger. For at lære mere om de indbyggede tests, se .
Hvis du ikke har brug for detaljer, kan du angive flaget --format score. I dette tilfælde vil Polaris returnere et tal i området fra 1 til 100 — score (dvs. bedømmelse):
$ polaris audit --audit-path test-data/base-valid.yaml --format score
68Jo tættere bedømmelsen er på 100, jo højere er graden af overholdelse. Hvis du tjekker exit-koden for kommandoen polaris audit, vil du finde, at den er lig med 0.
At få polaris audit den til at afslutte med en ikke-nul kode kan gøres med to flags:
- Flaget
--set-exit-code-below-scoremodtager et tærskelværdi som et argument i intervallet 1-100. I dette tilfælde afsluttes kommandoen med exit-kode 4, hvis vurderingen ligger under tærsklen. Dette er meget praktisk, når du har en tærskelværdi (lad os sige 75), og du har brug for at få et alert, hvis vurderingen falder under. - Flaget
--set-exit-code-on-dangervil føre til, at kommandoen afsluttes med kode 3, hvis en af fare-testene mislykkes.
Lad os nu prøve at oprette en brugerdefineret test, der kontrollerer, om billedet tages fra et betroet lager. Brugerdefinerede tests angives i YAML-format, mens selve testen beskrives ved hjælp af JSON Schema.
Det følgende YAML-kodefragment beskriver en ny test, der kaldes checkImageRepo:
checkImageRepo:
successMessage: Billederegistret er gyldigt
failureMessage: Billederegistret er ikke gyldigt
category: Billeder
target: Container
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
image:
type: string
pattern: ^my-company.com/.+$Lad os tage et nærmere kig på det:
successMessage— denne linje vil blive udskrevet, hvis testen afsluttes med succes;failureMessage— denne besked vises ved fejl;category— angiver en af kategorierne:Billeder,Sundhedstjek,Sikkerhed,NetværkogRessourcer;target—- definerer, hvilken type objekt (spec) testen anvendes på. Mulige værdier:Container,PodellerController;- Selve testen angives i objektet
schemaved hjælp af JSON-schema. I denne test bruges nøgleordetpatterntil at sammenligne kildebilledet med det krævede.
For at køre den nævnte test skal du oprette følgende Polaris-konfiguration:
checks:
checkImageRepo: danger
customChecks:
checkImageRepo:
successMessage: Billederegistret er gyldigt
failureMessage: Billederegistret er ikke gyldigt
category: Billeder
target: Container
schema:
'$schema': http://json-schema.org/draft-07/schema
type: object
properties:
image:
type: string
pattern: ^my-company.com/.+$(polaris-conf.yaml)
Lad os se på filen:
- I feltet
checksangiver testene og deres kritikalitetsniveau. Da det er ønskeligt at få en advarsel, når billedet tages fra en usikker kilde, sætter vi her niveauetdanger. - Selve testen
checkImageRepoangives derefter i objektetcustomChecks.
Gem filen som custom_check.yaml. Nu kan du køre polaris audit med en YAML-manifest, der kræver kontrol.
Lad os teste vores manifest base-valid.yaml:
$ polaris audit --config custom_check.yaml --audit-path base-valid.yamlKommandoen polaris audit gennemførte kun den brugerdefinerede test, der blev angivet ovenfor, og den var ikke vellykket.
Hvis billedet rettes til my-company.com/http-echo:1.0, vil Polaris afsluttes med succes. Manifestet med ændringerne er allerede i , så du kan kontrollere den tidligere kommando på manifestet image-valid-mycompany.yaml.
Nu opstår spørgsmålet: hvordan kører man de indbyggede tests sammen med brugertilpassede? Det er nemt! Du skal blot tilføje identifikatorerne for de indbyggede tests til konfigurationsfilen. Resultatet vil se således ud:
checks:
cpuRequestsMissing: warning
cpuLimitsMissing: warning
# Andre indbyggede checks..
# ..
# brugerdefinerede checks
checkImageRepo: danger # !!!
customChecks:
checkImageRepo: # !!!
successMessage: Billederegistreringen er gyldig
failureMessage: Billederegistreringen er ikke gyldig
category: Billeder
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 fuld konfigurationsfil er tilgængelig .
Kontroller manifestet base-valid.yaml, ved at bruge indbyggede og brugerdefinerede tests, kan gøres med kommandoen:
$ polaris audit --config config_with_custom_check.yaml --audit-path base-valid.yamlPolaris supplerer de indbyggede tests med brugerdefinerede, og kombinerer således det bedste fra to verdener.
På den anden side kan det være en begrænsning, at man ikke kan bruge mere kraftfulde sprog som Rego eller JavaScript, hvilket kan hæmme oprettelsen af mere sofistikerede tests.
Yderligere information om Polaris er tilgængelig på .
CV
Selvom der findes mange værktøjer til at kontrollere og evaluere YAML-filer i Kubernetes, er det vigtigt at have en klar forståelse af, hvordan testene vil blive designet og udført.
For eksempel, hvis man ser på Kubernetes-manifester, der går gennem pipeline, kunne kubeval være det første skridt i en sådan pipeline. Det ville sikre, at objektdefinitionerne overholder Kubernetes API-schemas.
Når en sådan kontrol er færdig, kan man gå videre til mere sofistikerede tests, såsom overholdelse af standard bedste praksis og særlige politikker. Og her ville kube-score og Polaris være nyttige.
For dem med komplekse krav og behov for detaljeret at tilpasse tests, ville copper, config-lint og conftest være passende.
Conftest og config-lint bruger YAML til at definere brugerdefinerede tests, mens copper giver adgang til et fuldt programmeringssprog, hvilket gør det til et ganske attraktivt valg.
På den anden side, bør man bruge et af disse værktøjer og derved oprette alle tests manuelt, eller vælge Polaris og blot tilføje det, der er nødvendigt? Der er ikke et entydigt svar på dette spørgsmål.
Tabellen nedenfor indeholder en kort beskrivelse af hvert værktøj:
Værktøj
Formål
Ulemper
Brugertests
kubeval
Tjekker YAML-manifest for overensstemmelse med en bestemt version af API-schemaet
Understøtter ikke arbejde med CRD
Nej
kube-score
Analyserer YAML-manifest for overensstemmelse med bedste praksis
Det er ikke muligt at vælge sin egen version af Kubernetes API til at kontrollere ressourcer
Nej
copper
Generelt rammeværk til oprettelse af egne JavaScript-tests for YAML-manifest
Ingen indbyggede tests. Sparse dokumentation
Ja
config-lint
Generelt rammeværk til at skabe tests i et domænespecifikt sprog indlejret i YAML. Understøtter forskellige konfigurationsformater (f.eks. Terraform)
Ingen færdige tests. Indbyggede assertions og funktioner kan være utilstrækkelige
Ja
conftest
Rammeværk til at skabe egne tests i Rego (et specialiseret forespørgselssprog). Gør det muligt at dele politikker via OCI-bundter
Ingen indbyggede tests. Man skal lære Rego. Docker Hub understøttes ikke ved publicering af politikker
Ja
Polaris
Analyserer YAML-manifest for overensstemmelse med standard bedste praksis. Gør det muligt at lave egne tests med JSON Schema
Mulighederne for tests baseret på JSON Schema kan være utilstrækkelige
Ja
Da disse værktøjer ikke er afhængige af adgang til Kubernetes-klusteret, er de nemme at installere. De giver mulighed for at filtrere kildematerialer og giver hurtig feedback til forfattere af pull requests i projekter.
P.S. fra oversætteren
Læs også på vores blog:
- «»;
- «»;
- «».
Kilde: habr.com
