Validearje Kubernetes YAML tsjin bêste praktiken en belied

Noat. transl.: Mei it tanimmend oantal YAML konfiguraasjes foar K8s omjouwings, de needsaak foar harren automatisearre ferifikaasje wurdt mear en mear driuwend. De skriuwer fan dizze resinsje selektearre net allinich besteande oplossingen foar dizze taak, mar brûkte ek Deployment as foarbyld om te sjen hoe't se wurkje. It die bliken tige ynformatyf te wêzen foar dyjingen dy't ynteressearre binne yn dit ûnderwerp.

Validearje Kubernetes YAML tsjin bêste praktiken en belied

TL; DR: Dit artikel fergeliket seis statyske ark om Kubernetes YAML-bestannen te falidearjen en te evaluearjen tsjin bêste praktiken en easken.

Kubernetes-workloads wurde typysk definieare yn 'e foarm fan YAML-dokuminten. Ien fan 'e problemen mei YAML is de muoite om beheiningen of relaasjes te spesifisearjen tusken manifeste bestannen.

Wat as wy moatte soargje dat alle ôfbyldings ynset op it kluster komme út in fertroude register?

Hoe kin ik foarkomme dat ynset dy't gjin PodDisruptionBudgets hawwe nei it kluster stjoerd?

Yntegraasje fan statyske testen kinne jo flaters en beliedsferoarings identifisearje yn 'e ûntwikkelingsstadium. Dit fergruttet de garânsje dat boarne definysjes binne korrekt en feilich, en makket it wierskynliker dat produksje workloads sille folgje bêste praktiken.

It ekosysteem foar statyske YAML-bestânynspeksje fan Kubernetes kin wurde ferdield yn de folgjende kategoryen:

  • API validators. Ark yn dizze kategory kontrolearje it YAML-manifest tsjin de easken fan 'e Kubernetes API-tsjinner.
  • Klear testers. Tools út dizze kategory komme mei klearmakke tests foar feiligens, neilibjen fan bêste praktiken, ensfh.
  • Oanpaste validators. Fertsjintwurdigers fan dizze kategory kinne jo meitsje oanpaste tests yn ferskate talen, Bygelyks, Rego en Javascript.

Yn dit artikel sille wy seis ferskillende ark beskriuwe en fergelykje:

  1. kubeval;
  2. kube-score;
  3. config-lint;
  4. koper;
  5. conftest;
  6. polaris.

No, lit ús begjinne!

Kontrolearje ynset

Foardat wy ark begjinne te fergelykjen, litte wy wat eftergrûn meitsje om se te testen.

It manifest hjirûnder befettet in oantal flaters en net-neilibjen fan bêste praktiken: hoefolle kinne jo fine?

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)

Wy sille dizze YAML brûke om ferskate ark te fergelykjen.

It boppesteande manifest base-valid.yaml en oare manifesten út dit artikel kinne fûn wurde yn Git repositories.

It manifest beskriuwt in webapplikaasje waans haadtaak is om te reagearjen mei in "Hello World" berjocht nei poarte 5678. It kin ynset wurde mei it folgjende kommando:

kubectl apply -f hello-world.yaml

En dus - kontrolearje it wurk:

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

No gean nei http://localhost:8080 en befêstigje dat de applikaasje wurket. Mar folget it bêste praktiken? Litte wy kontrolearje.

1. Kubeval

Oan 'e basis kubeval It idee is dat elke ynteraksje mei Kubernetes foarkomt fia syn REST API. Mei oare wurden, jo kinne in API-skema brûke om te kontrolearjen oft in opjûne YAML dêrmei oerienkomt. Litte wy nei in foarbyld sjen.

Ynstallaasje ynstruksjes kubeval binne beskikber op de projektwebside.

Op it momint fan it skriuwen fan it orizjinele artikel wie ferzje 0.15.0 beskikber.

Ienris ynstalleare, litte wy it it hjirboppe manifestearje:

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

As suksesfol, sil kubeval útgean mei útgongskoade 0. Jo kinne it as folgjend kontrolearje:

$ echo $?
0

Litte wy no kubeval besykje mei in oar 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)

Kinne jo it probleem mei it each fine? Litte wy begjinne:

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

# проверим код возврата
$ echo $?
1

De boarne wurdt net ferifiearre.

Deployments mei help fan de API ferzje apps/v1, moat in selector befetsje dy't oerienkomt mei it label fan 'e pod. It manifest hjirboppe omfettet de selector net, dus kubeval rapportearre in flater en gie út mei in net-nul koade.

Ik freegje my ôf wat der barre sil as ik doch kubectl apply -f mei dit manifest?

No, litte wy besykje:

$ 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 krekt de flater wêrfoar kubeval warskôge. Jo kinne it reparearje troch in selector ta te foegjen:

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)

It foardiel fan ark lykas kubeval is dat flaters lykas dizze betiid yn 'e ynsetsyklus kinne wurde fongen.

Derneist hawwe dizze kontrôles gjin tagong ta it kluster nedich; se kinne offline wurde útfierd.

Standert kontroleart kubeval boarnen tsjin it lêste Kubernetes API-skema. Yn 'e measte gefallen moatte jo lykwols miskien kontrolearje tsjin in spesifike Kubernetes-release. Dit kin dien wurde mei de flagge --kubernetes-version:

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

Tink derom dat de ferzje moat wurde opjûn yn it formaat Major.Minor.Patch.

Foar in list mei ferzjes wêrfoar ferifikaasje wurdt stipe, nim dan ferwize nei JSON-skema op GitHub, dy't kubeval brûkt foar falidaasje. As jo ​​kubeval offline moatte útfiere, download dan de skema's en spesifisearje har lokale lokaasje mei de flagge --schema-location.

Neist yndividuele YAML-bestannen kin kubeval ek wurkje mei mappen en stdin.

Derneist yntegreart Kubeval maklik yn 'e CI-pipeline. Dejingen dy't tests wolle útfiere foardat se manifesten nei it kluster ferstjoere, sille bliid wêze om te witten dat kubeval trije útfierformaten stipet:

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

En elk fan 'e formaten kin brûkt wurde foar fierdere parsing fan' e útfier om in gearfetting fan 'e resultaten fan it winske type te generearjen.

Ien fan 'e neidielen fan kubeval is dat it op it stuit net kin kontrolearje op neilibjen fan Custom Resource Definitions (CRD's). It is lykwols mooglik om kubeval te konfigurearjen negearje harren.

Kubeval is in geweldich ark foar it kontrolearjen en evaluearjen fan boarnen; It moat lykwols beklamme wurde dat it trochjaan fan 'e test net garandearret dat de boarne foldocht oan bêste praktiken.

Bygelyks, mei help fan de tag latest yn in kontener folget gjin bêste praktiken. Kubeval beskôget dit lykwols net as in flater en rapportearret it net. Dat is, de ferifikaasje fan sa'n YAML sil foltôgje sûnder warskôgings.

Mar wat as jo YAML wolle evaluearje en oertredings identifisearje lykas de tag latest? Hoe kontrolearje ik in YAML-bestân tsjin bêste praktiken?

2. Kube-skoare

Kube-score parses YAML manifestearret en evaluearret se tsjin ynboude tests. Dizze tests wurde selektearre op basis fan feiligensrjochtlinen en bêste praktiken, lykas:

  • It útfieren fan de kontener net as root.
  • Beskikberens fan pod sûnenskontrôles.
  • It ynstellen fan fersiken en grinzen foar boarnen.

Op grûn fan de testresultaten wurde trije resultaten jûn: OK, WARSKÔGING и KRITYSK.

Jo kinne Kube-score online besykje of it lokaal ynstallearje.

Op it momint fan it skriuwen fan it orizjinele artikel wie de lêste ferzje fan kube-score 1.7.0.

Litte wy it besykje op ús manifest base-valid.yaml:

$ kube-score score base-valid.yaml

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

YAML trochgiet kubeval-tests, wylst kube-score wiist op de folgjende gebreken:

  • Readiness kontrôles binne net konfigurearre.
  • D'r binne gjin oanfragen of grinzen foar CPU-boarnen en ûnthâld.
  • Pod disruption budzjetten binne net oantsjutte.
  • D'r binne gjin regels fan skieding (anti-affiniteit) om de beskikberens te maksimalisearjen.
  • De kontener rint as root.

Dit binne allegear jildige punten oer tekoarten dy't moatte wurde oanpakt om Deployment effisjinter en betrouber te meitsjen.

team kube-score toant ynformaasje yn minsklik lêsbere foarm ynklusyf alle type oertredings WARSKÔGING и KRITYSK, dy't in protte helpt by ûntwikkeling.

Dejingen dy't dit ark wolle brûke binnen de CI-pipeline kinne mear komprimearre útfier ynskeakelje mei de flagge --output-format ci (yn dit gefal wurde tests mei it resultaat ek werjûn 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

Fergelykber mei kubeval jout kube-score in net-nul útgongskoade werom as d'r in test is dy't mislearret KRITYSK. Jo kinne ek ynskeakelje ferlykbere ferwurking foar WARSKÔGING.

Derneist is it mooglik om boarnen te kontrolearjen foar konformiteit mei ferskate API-ferzjes (lykas yn kubeval). Dizze ynformaasje is lykwols hurdkodearre yn 'e kube-skoare sels: jo kinne gjin oare ferzje fan Kubernetes selektearje. Dizze beheining kin in grut probleem wêze as jo fan doel binne jo kluster te upgrade of as jo meardere klusters hawwe mei ferskate ferzjes fan K8's.

notysje dat der is al in kwestje mei in foarstel om dizze kâns te realisearjen.

Mear ynformaasje oer kube-score is te finen op offisjele webside.

Kube-score-tests binne in geweldich ark foar it ymplementearjen fan bêste praktiken, mar wat as jo wizigingen moatte oanmeitsje oan 'e test of jo eigen regels tafoegje? Och, dit kin net dien wurde.

Kube-score is net útwreidzjen: jo kinne der gjin belied oan tafoegje of oanpasse.

As jo ​​​​oanpaste tests moatte skriuwe om neilibjen fan bedriuwsbelied te kontrolearjen, kinne jo ien fan 'e folgjende fjouwer ark brûke: config-lint, koper, conftest, of polaris.

3.Config-lint

Config-lint is in ark foar it falidearjen fan YAML, JSON, Terraform, CSV-konfiguraasjebestannen en Kubernetes-manifesten.

Jo kinne it ynstallearje mei help fan ynstruksjes op de projektwebside.

De hjoeddeistige release op it stuit fan it skriuwen fan it orizjinele artikel is 1.5.0.

Config-lint hat gjin ynboude tests foar it validearjen fan Kubernetes-manifesten.

Om alle tests út te fieren, moatte jo passende regels meitsje. Se wurde skreaun yn YAML-bestannen neamd "regelsets" (regels), en hawwe de folgjende struktuer:

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

(rule.yaml)

Litte wy it neier studearje:

  • fjild type spesifisearret hokker type konfiguraasje config-lint sil brûke. Foar K8s manifestearret dit is altyd Kubernetes.
  • Yn fjild files Neist de bestannen sels kinne jo in map opjaan.
  • fjild rules bedoeld foar it ynstellen fan brûkerstests.

Litte wy sizze dat jo derfoar soargje wolle dat ôfbyldings yn Deployment altyd wurde downloade fan in fertroude repository lykas my-company.com/myapp:1.0. In config-lint-regel dy't sa'n kontrôle útfiert soe der sa útsjen:

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

(rule-trusted-repo.yaml)

Elke regel moat de folgjende attributen hawwe:

  • id - unike identifier fan 'e regel;
  • severity - Miskien MISLEARRING, WARSKÔGING и NON_COMPLIANT;
  • message - as in regel wurdt oertrêde, wurdt de ynhâld fan dizze rigel werjûn;
  • resource - it type boarne wêrop dizze regel jildt;
  • assertions - in list mei betingsten dy't sille wurde evaluearre yn relaasje ta dizze boarne.

Yn de regel hjirboppe assertion ûnder de namme every kontrolearret dat alle konteners yn ynset binne (key: spec.templates.spec.containers) brûke fertroude ôfbyldings (dus begjinnend mei my-company.com/).

De folsleine regelset sjocht der sa út:

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

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

(ruleset.yaml)

Om de test út te probearjen, litte wy it opslaan as check_image_repo.yaml. Litte wy in kontrôle útfiere op it bestân base-valid.yaml:

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

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

De kontrôle mislearre. Litte wy no it folgjende manifest besjogge mei it juste ôfbyldingsrepository:

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)

Wy rinne deselde test mei it boppesteande manifest. Gjin problemen fûn:

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

Config-lint is in kânsryk kader wêrmei jo jo eigen tests kinne meitsje om Kubernetes YAML-manifesten te falidearjen mei de YAML DSL.

Mar wat as jo mear komplekse logika en tests nedich binne? Is YAML hjir net te beheind foar? Wat as jo tests kinne oanmeitsje yn in folsleine programmeartaal?

4. Koper

Koper V2 is in ramt foar it falidearjen fan manifesten mei help fan oanpaste tests (lykas config-lint).

It ferskilt lykwols fan it lêste yn dat it YAML net brûkt om tests te beskriuwen. Tests kinne wurde skreaun yn JavaScript ynstee. Koper leveret in bibleteek mei ferskate basisark, dy't jo helpe om ynformaasje oer Kubernetes-objekten te lêzen en flaters te rapportearjen.

De stappen foar it ynstallearjen fan Koper kinne fûn wurde yn offisjele dokumintaasje.

2.0.1 is de lêste release fan dit hulpprogramma op it momint fan it skriuwen fan it orizjinele artikel.

Lykas config-lint hat Copper gjin ynboude tests. Litte wy ien skriuwe. Lit it kontrolearje dat ynset containerôfbyldings allinich brûke fan fertroude repositories lykas my-company.com.

Meitsje in triem check_image_repo.js mei de folgjende ynhâld:

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

No om ús manifest te testen base-valid.yaml, brûk it kommando 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

It is dúdlik dat jo mei help fan koper mear komplekse testen kinne útfiere - bygelyks domeinnammen kontrolearje yn Ingress-manifesten of pods ôfwize dy't yn befoarrjochte modus rinne.

Koper hat ferskate nutsfunksjes ynboud:

  • DockerImage lêst it oantsjutte ynfierbestân en makket in objekt mei de folgjende attributen:
    • name - namme fan 'e ôfbylding,
    • tag - ôfbylding tag,
    • registry - ôfbyldingsregister,
    • registry_url - protokol (https://) en ôfbyldingsregister,
    • fqin - folsleine lokaasje fan 'e ôfbylding.
  • function findByName helpt om in boarne te finen troch in bepaald type (kind) en namme (name) út it ynfierbestân.
  • function findByLabels helpt om in boarne te finen troch in spesifisearre type (kind) en labels (labels).

Jo kinne alle beskikbere tsjinstfunksjes besjen hjir.

Standert laadt it de hiele ynfier YAML-bestân yn in fariabele $$ en makket it beskikber foar skripting (in bekende technyk foar dyjingen mei jQuery ûnderfining).

It wichtichste foardiel fan Koper is fanselssprekkend: jo hoege gjin spesjalisearre taal te behearskjen en jo kinne ferskate JavaScript-funksjes brûke om jo eigen tests te meitsjen, lykas tekenrige ynterpolaasje, funksjes, ensfh.

It moat ek opmurken wurde dat de hjoeddeistige ferzje fan Koper wurket mei de ES5 ferzje fan 'e JavaScript-motor, net ES6.

Details beskikber by offisjele projektwebside.

As jo ​​​​lykwols net echt fan JavaScript hâlde en leaver in taal hawwe dy't spesifyk is ûntworpen foar it meitsjen fan fragen en it beskriuwen fan belied, moatte jo omtinken jaan oan confetest.

5. Conftest

Conftest is in ramt foar it testen fan konfiguraasjegegevens. Ek geskikt foar it testen / ferifiearjen fan Kubernetes-manifest. Tests wurde beskreaun mei in spesjalisearre query-taal Rego.

Jo kinne confetest ynstallearje mei ynstruksjesneamd op de projektwebside.

Op it momint fan it skriuwen fan it orizjinele artikel wie de lêste beskikbere ferzje 0.18.2.

Fergelykber mei config-lint en koper, komt conftest sûnder ynboude tests. Litte wy it besykje en ús eigen belied skriuwe. Lykas yn eardere foarbylden sille wy kontrolearje oft de kontenerôfbyldings binne nommen fan in betroubere boarne.

Meitsje in map conftest-checks, en dêryn is in triem mei de namme check_image_registry.rego mei de folgjende ynhâld:

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

No litte wy testen base-valid.yaml через conftest:

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

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

De test mislearre foarsisber omdat de ôfbyldings kamen fan in net-fertroude boarne.

Yn it Rego-bestân definiearje wy it blok deny. De wierheid wurdt beskôge as in oertrêding. As blokken deny ferskate, conftest kontrolearret se ûnôfhinklik fan elkoar, en de wierheid fan ien fan 'e blokken wurdt behannele as in oertrêding.

Njonken de standertútfier stipet conftest JSON, TAP en tabelformaat - in ekstreem nuttige funksje as jo rapporten moatte ynbêde yn in besteande CI-pipeline. Jo kinne it winske formaat ynstelle mei de flagge --output.

Om it makliker te meitsjen om belied te debuggen, hat conftest in flagge --trace. It jout in spoar út hoe't conftest de oantsjutte beliedsbestannen parseart.

Wedstriidbelied kin wurde publisearre en dield yn OCI (Open Container Initiative) registers as artefakten.

Kommando's push и pull kinne jo in artefakt publisearje of in besteande artefakt ophelje út in register op ôfstân. Litte wy besykje it belied dat wy makken te publisearjen nei it lokale Docker-register mei help fan conftest push.

Start jo lokale Docker-register:

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

Gean yn in oare terminal nei de map dy't jo earder makke hawwe conftest-checks en fier it folgjende kommando út:

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

As it kommando suksesfol wie, sille jo in berjocht sjen as dit:

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

Meitsje no in tydlike map en fier it kommando dêryn conftest pull. It sil it pakket downloade dat is makke troch it foarige kommando:

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

In submap sil ferskine yn 'e tydlike map policymei ús beliedsbestân:

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

Tests kinne direkt wurde útfierd fanút it repository:

$ 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

Spitigernôch wurdt DockerHub noch net stipe. Sa beskôgje dysels gelok as jo brûke Azure Container Registry (ACR) of jo eigen register.

Artefaktformaat is itselde as Iepenje Policy Agent-pakketten (OPA), wêrtroch jo confetest kinne brûke om tests út te fieren fan besteande OPA-pakketten.

Jo kinne mear leare oer dielen fan belied en oare funksjes fan conftest op offisjele projektwebside.

6. Polaris

It lêste ark dat sil wurde besprutsen yn dit artikel is Polaris. (Syn oankundiging fan ferline jier wy al oerset - ca. oersetting)

Polaris kin ynstalleare wurde yn in kluster of brûkt wurde yn kommandorigelmodus. Lykas jo miskien hawwe rieden, kinne jo Kubernetes-manifesten statysk analysearje.

By it útfieren fan 'e kommandorigelmodus binne ynboude tests beskikber foar gebieten lykas feiligens en bêste praktiken (lykas kube-score). Derneist kinne jo jo eigen tests oanmeitsje (lykas yn config-lint, koper en confetest).

Mei oare wurden, Polaris kombinearret de foardielen fan beide kategoryen ark: mei ynboude en oanpaste tests.

Om Polaris te ynstallearjen yn kommandorigelmodus, brûk ynstruksjes op 'e projektwebside.

Op it momint fan it skriuwen fan it orizjinele artikel is ferzje 1.0.3 beskikber.

As de ynstallaasje foltôge is, kinne jo polaris op it manifest útfiere base-valid.yaml mei it folgjende kommando:

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

It sil in tekenrige útfiere yn JSON-formaat mei in detaillearre beskriuwing fan 'e útfierde testen en har resultaten. De útfier sil de folgjende struktuer hawwe:

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

Folsleine útfier beskikber hjir.

Lykas kube-score identifisearret Polaris problemen yn gebieten wêr't it manifest net foldocht oan bêste praktiken:

  • D'r binne gjin sûnenskontrôles foar pods.
  • Tags foar kontenerôfbyldings binne net oantsjutte.
  • De kontener rint as root.
  • Fersiken en grinzen foar ûnthâld en CPU wurde net oantsjutte.

Elke test, ôfhinklik fan syn resultaten, wurdt tawiisd in graad fan krityk: warskôging of gefaar. Om mear te learen oer de beskikbere ynboude tests, ferwize asjebleaft nei dokumintaasje.

As details net nedich binne, kinne jo de flagge opjaan --format score. Yn dit gefal sil Polaris in nûmer útfiere fan 1 oant 100 - skoare (d.w.s. beoardieling):

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

Hoe tichter de skoare by 100 is, hoe heger de graad fan oerienkomst. As jo ​​​​de útgongskoade fan it kommando kontrolearje polaris audit, it docht bliken dat it gelyk is oan 0.

Krêft polaris audit Jo kinne wurk mei net-nul koade beëinigje mei twa flaggen:

  • Flag --set-exit-code-below-score nimt as argumint in drompelwearde yn it berik 1-100. Yn dit gefal sil it kommando útgean mei útgongskoade 4 as de skoare ûnder de drompel is. Dit is heul nuttich as jo in bepaalde drompelwearde hawwe (sizze 75) en jo moatte in warskôging krije as de skoare ûnder giet.
  • Flag --set-exit-code-on-danger sil feroarsaakje dat it kommando mislearret mei koade 3 as ien fan 'e gefaartests mislearret.

Litte wy no besykje in oanpaste test te meitsjen dy't kontrolearret oft de ôfbylding is nommen út in fertroude repository. Oanpaste tests wurde oantsjutte yn YAML-formaat, en de test sels wurdt beskreaun mei JSON Schema.

De folgjende YAML koade snippet beskriuwt in nije test neamd 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/.+$

Litte wy it neier besjen:

  • successMessage - dizze rigel wurdt printe as de test mei súkses foltôge;
  • failureMessage - dit berjocht sil werjûn wurde yn gefal fan mislearring;
  • category - jout ien fan 'e kategoryen oan: Images, Health Checks, Security, Networking и Resources;
  • target--- bepaalt hokker type objekt (spec) test wurdt tapast. Mooglike wearden: Container, Pod of Controller;
  • De test sels wurdt oantsjutte yn it objekt schema mei help fan JSON skema. It kaaiwurd yn dizze test is pattern brûkt om de ôfbyldingsboarne te fergelykjen mei de fereaske.

Om de boppesteande test út te fieren, moatte jo de folgjende Polaris-konfiguraasje oanmeitsje:

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)

Litte wy it bestân parse:

  • Yn fjild checks tests en har nivo fan kritykens wurde foarskreaun. Om't it winsklik is om in warskôging te ûntfangen as in ôfbylding is nommen fan in net-fertroude boarne, sette wy it nivo hjir yn danger.
  • De test sels checkImageRepo dan registrearre yn it objekt customChecks.

Bewarje de triem as custom_check.yaml. No kinne jo rinne polaris audit mei in YAML-manifest dat ferifikaasje fereasket.

Litte wy ús manifest testen base-valid.yaml:

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

team polaris audit rûn allinich de hjirboppe oantsjutte brûkerstest en it mislearre.

As jo ​​reparearje de ôfbylding oan my-company.com/http-echo:1.0, Polaris sil mei súkses ôfslute. It manifest mei de feroarings is al binnen repositoriessadat jo it foarige kommando op it manifest kinne kontrolearje image-valid-mycompany.yaml.

No komt de fraach op: hoe kinne jo ynboude tests útfiere tegearre mei oanpaste? Maklik! Jo moatte gewoan de ynboude testidentifiers tafoegje oan it konfiguraasjetriem. As gefolch sil it de folgjende foarm oannimme:

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)

In foarbyld fan in folslein konfiguraasjetriem is beskikber hjir.

Kontrolearje manifest base-valid.yamlmei ynboude en oanpaste tests kinne jo it kommando brûke:

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

Polaris komplementeart de ynboude tests mei oanpaste tests, en kombinearret dêrmei it bêste fan beide wrâlden.

Oan 'e oare kant kin it ûnfermogen om machtiger talen te brûken lykas Rego of JavaScript in beheinende faktor wêze dy't it meitsjen fan mear ferfine tests foarkomt.

Mear ynformaasje oer Polaris is beskikber op projekt webside.

Gearfetting

Wylst d'r in protte ark beskikber binne om Kubernetes YAML-bestannen te ynspektearjen en te evaluearjen, it is wichtich om in dúdlik begryp te hawwen fan hoe't de tests wurde ûntwurpen en útfierd.

Bygelyks, as jo Kubernetes-manifesten nimme dy't troch in pipeline geane, kin kubeval de earste stap wêze yn sa'n pipeline. It soe kontrolearje oft objektdefinysjes oerienkomme mei it Kubernetes API-skema.

Sadree't sa'n resinsje is foltôge, koe men oergean nei mear ferfine tests, lykas neilibjen fan standert best practices en spesifyk belied. Dit is wêr kube-score en Polaris soe komme fan pas.

Foar dyjingen dy't komplekse easken hawwe en tests yn detail moatte oanpasse, soene koper, konfiguraasje-lint en confetest geskikt wêze.

Conftest en config-lint brûke YAML om oanpaste tests te definiearjen, en koper jout jo tagong ta in folsleine programmeartaal, wêrtroch it in aardich oantreklike kar is.

Oan 'e oare kant, is it de muoite wurdich om ien fan dizze ark te brûken en dêrom alle tests mei de hân te meitsjen, of leaver Polaris en tafoegje allinich wat der nedich is? D'r is gjin dúdlik antwurd op dizze fraach.

De tabel hjirûnder jout in koarte beskriuwing fan elk ark:

Tool
Doel
Nijsberjochten
Meidogger tests

kubeval
Validearret YAML manifestearret tsjin in spesifike ferzje fan it API-skema
Kin net wurkje mei CRD
gjin

kube-score
Analyse YAML manifestearret tsjin bêste praktiken
Kin jo Kubernetes API-ferzje net selektearje om boarnen te kontrolearjen
gjin

koper
In algemien ramt foar it meitsjen fan oanpaste JavaScript-tests foar YAML-manifest
Gjin ynboude tests. Min dokumintaasje
dat

config-lint
In algemien ramt foar it meitsjen fan tests yn in domein-spesifike taal ynbêde yn YAML. Unterstützt ferskate konfiguraasjeformaten (bygelyks Terraform)
D'r binne gjin klearebare testen. Ynboude bewearingen en funksjes binne miskien net genôch
dat

wedstryd
In ramt foar it meitsjen fan jo eigen tests mei Rego (in spesjalisearre query-taal). Tastean dielen fan belied fia OCI bondels
Gjin ynboude tests. Ik moat Rego leare. Docker Hub wurdt net stipe by it publisearjen fan belied
dat

Polaris
Resinsjes YAML manifestearret tsjin standert best practices. Hjirmei kinne jo jo eigen tests meitsje mei JSON Schema
Testmooglikheden basearre op JSON Schema binne miskien net genôch
dat

Om't dizze ark net fertrouwe op tagong ta it Kubernetes-kluster, binne se maklik te ynstallearjen. Se kinne jo boarnebestannen filterje en rappe feedback leverje oan de auteurs fan pull-oanfragen yn projekten.

PS fan oersetter

Lês ek op ús blog:

Boarne: www.habr.com

Add a comment