Kubernetes YAML valideerimine parimate praktikate ja poliitikate suhtes

Märk. tõlge.: K8s-üsteemide YAML-konfiguratsioonide arvu suurenemisega kasvab vajadus nende automatiseeritud kontrollimise järele. Artikli autor on mitte ainult kogunud olemasolevaid lahendusi sellele probleemile, vaid vaadanud ka, kuidas need töötavad konkreetselt Deploymenti näitel. See on olnud väga informatiivne neile, keda see teema huvitab.

Kubernetes YAML valideerimine parimate praktikate ja poliitikate suhtes

TL;DR: Artikkel võrdleb kuut staatilist tööriista Kubernetes'i YAML-failide kontrollimiseks ja hindamiseks vastavuses parimate praktika ja nõuetega.

Kubernetes'e töökoormused määratakse tavaliselt YAML-dokumentidena. Üks YAML'i probleemidest on piirangute või suhete määramine manifesteerimisfailide vahel.

Mis juhtub, kui peame veenduma, et kõik klastrisse juurutatavad pildid tulevad usaldusväärsest registrist?

Kuidas vältida Deploymentide saatmist klastrisse, mille jaoks ei ole määratud PodDisruptionBudget'e?

Statilise testimise integreerimine võimaldab tuvastada vigu ja poliitikate rikkomisi arenduse varases staadiumis. Seega suurenevad ressursside määratlemise õiguse ja turvalisuse tagatised ning tõenäosus, et tootmiskoormused järgivad parimaid praktikaid.

Kubernetes YAML-failide staatilise kontrolli ökosüsteem jaguneb järgmistesse kategooriatesse:

  • API valideerijad. Selle kategooria tööriistad kontrollivad YAML-manifesti vastavust Kubernetes API-serveri nõuetele.
  • Valmis testijad. Selle kategooria tööriistad tulevad koos valmis testidega, mis kontrollivad turvalisust, vastavust parimatele praktikatele jne.
  • Kohandatud valideerijad. Selles kategoorias olevad tööriistad võimaldavad luua kohandatud teste erinevates keeltes, näiteks Rego ja Javascript.

Selles artiklis kirjeldame ja võrreldame kuut erinevat tööriista:

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

Noh, alustame!

Deploymentide kontrollimine

Enne kui hakkame tööriistu võrreldama, loome aluse, millel neid testida.

Allpool toodud manifest sisaldab mitmeid vigu ja parimate praktikate rikkumisi: kui palju neist leiate?

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)

Kasutame seda YAML-faili erinevate tööriistade võrdlemiseks.

Ülaltoodud manifest base-valid.yaml ja muud selles artiklis olevad manfestid on saadaval Git-repositooriumis.

Manifest kirjeldab veebirakendust, mille põhieesmärk on vastata sõnumiga „Hello World” pordile 5678. Seda saab juurutada järgmise käsuga:

kubectl apply -f hello-world.yaml

Ja nii saab kontrollida selle toimimist:

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

Nüüd minge aadressile http://localhost:8080 ja kinnitage, et rakendus töötab. Kuid kas see järgib parimaid praktikaid? Kontrollime.

1. Kubeval

Kubevali aluseks kubeval On see idee, et kõik suhtlemine Kubernetesega toimub läbi selle REST API. Teisisõnu, saab kasutada API skeemi, et kontrollida, kas antud YAML vastab sellele. Vaadakem näidet.

Installatsiooni juhised kubeval on saadaval projekti veebilehel.

Originaali kirjutamise ajal oli saadaval versioon 0.15.0.

Pärast installimist toome sisse eelpoolmainitud manifesti:

$ kubeval base-valid.yaml
PASS - base-valid.yaml sisaldab kehtivat Deployment'i (http-echo)
PASS - base-valid.yaml sisaldab kehtivat Service'i (http-echo)

Edu korral lõpetab kubeval töö exit-koodiga 0. Seda saab kontrollida järgmiselt:

$ echo $?
0

Proovime nüüd kubeval'i teise manifestiga:

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)

Kas suudate probleemile visuaalselt tähelepanu pöörata? Käivitame:

$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml sisaldab kehtetut Deployment'i (http-echo) - selector: selector on vajalik
PASS - kubeval-invalid.yaml sisaldab kehtivat Service'i (http-echo)

# kontrollime tagastatud koodi
$ echo $?
1

Ressurss ei läbi kontrolli.

Deployment'id, mis kasutavad API versiooni apps/v1, peavad sisaldama selektorit, mis vastab pod'i märgisele. Ülaltoodud manifest ei sisalda selektorit, seetõttu teatas kubeval veast ja lõpetas mitte nullkoodiga.

Huvitav, mis juhtub, kui käivitada kubectl apply -f selle manifestiga?

Nojah, proovime:

$ 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

Just see viga, mille eest kubeval hoiatab. Selle parandamiseks võib lisada selektori:

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)

Tööriistade, nagu kubeval, eelis on see, et taolist viga saab tuvastada varakult juurutamise tsüklis.

Lisaks ei ole nende kontrollide jaoks klastrisse ligipääs vajalik: neid saab teha offline.

Kubeval kontrollib vaikimisi ressursse vastavuses kõige uuema Kubernetes API skeemiga. Siiski võib enamikul juhtudel olla vajalik, et kontrollida vastavust konkreetse Kubernetes'i versiooniga. Selleks saab kasutada flagi --kubernetes-version:

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

Pange tähele, et versioon peab olema esitatud vormingus Major.Minor.Patch.

Üksikasjaliku versioonide nimekirja, mille jaoks kontroll on saadaval, leiate GitHubist JSON skeemist, mida kubeval kasutab valideerimiseks. Kui soovite käivitada kubeval offline, laadige skeemid alla ja märkige nende kohaliku asukoha flagi abil --schema-location.

Kubeval suudab töötada ka kaustade ja stdin-iga, lisaks individuaalsetele YAML-failidele.

Samuti integreerub Kubeval hõlpsasti CI-pipeline'i. Need, kes soovivad testida enne manifestide saatmist klastrisse, saavad rõõmuga teada, et kubeval toetab kolme väljundivormingut:

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

Ja igat vormingut saab kasutada väljundi edasise analüüsi jaoks, et koostada soovitud tulemuste kokkuvõte.

Üks kubevali puudustest on see, et ta ei oska hetkel kontrollida Custom Resource Definitions (CRD-de) vastavust. Kuid kubevali saab konfigureerida neid ignoreerima..

Kubeval on suurepärane tööriist ressursside kontrollimiseks ja hindamiseks; kuid tasub rõhutada, et testi edukas läbimine ei garantii, et ressurss järgib parimaid tavasid.

Näiteks mitte-juurüksuse märgi kasutamine latest konteineris ei vasta parimatele tavasid. Kuid kubeval ei pea seda veaks ega teata sellest. See tähendab, et selline YAML-i kontroll lõpeb ilma hoiatusteta.

Aga mis siis, kui on vaja hinnata YAML-i ja tuvastada rikkumisi, näiteks märki latest? Как проверить YAML-файл на соответствие лучшим практикам?

2. Kube-score

Kube-score analüüsib YAML-i manifeste ja hindab neid sisseehitatud testide põhjal. Need testid valitakse turvatoimingute ja parimate tavade soovituste alusel, näiteks:

  • Konteineri käitamine mitte juurüksusena.
  • Podi tervisekontrollide olemasolu.
  • Ressursside nõudmiste ja piirangute seadmine.

Testi tulemused on järgmised: OK, HOIATUS ja KRITILINE.

Kube-score'i saab proovida veebis või installida kohapeal.

Kuna originaali kirjutamise ajal oli kube-score'i uusim versioon 1.7.0.

Proovime seda meie manifeste. base-valid.yaml:

$ kube-score score base-valid.yaml

apps/v1/Deployment http-echo
[CRITICAL] Mahuti pilti silt
  · http-echo -> Pilt, mille silt on viimane
      Soovitatav on kasutada fikseeritud silti, et vältida juhuslikku uuendamist.
[CRITICAL] Pod NetworkPolicy
  · Podil ei ole vastavat võrgupoliitikat
      Looge NetworkPolicy, mis sihib seda podi.
[CRITICAL] Pod Probes
  · Mahuti puudub readinessProbe
      ReadinessProbe'i tuleks kasutada, et näidata, millal teenus on valmis liiklust vastu võtma.
      Ilma selleta riskib pod saada tähelepanu enne, kui see on käivitatud. Seda kasutatakse ka
      uuenduste ajal ning see võib vältida seisakut, kui rakenduse uus versioon ebaõnnestub.
      Lisainformatsioon: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[CRITICAL] Mahuti turvakonfiguratsioon
  · http-echo -> Mahutil puudub konfigureeritud turvakonfiguratsioon
      Määrake securityContext, et käivitada konteiner turvalisemas kontekstis.
[CRITICAL] Mahuti ressursid
  · http-echo -> CPU piirangut ei ole seadistatud
      Ressursipiirangud on soovitatavad, et vältida ressursi DDOSi. Määrake resources.limits.cpu
  · http-echo -> Mälu piirangut ei ole seadistatud
      Ressursipiirangud on soovitatavad, et vältida ressursi DDOSi. Määrake resources.limits.memory
  · http-echo -> CPU soovi ei ole seadistatud
      Ressursitaotlused on soovitatavad, et tagada rakenduse käivitamine ja töötamine ilma
      kokku kukkumiseta. Määrake resources.requests.cpu
  · http-echo -> Mälu soovi ei ole seadistatud
      Ressursitaotlused on soovitatavad, et tagada rakenduse käivitamine ja töötamine ilma kokku kukkumiseta.
      Määrake resources.requests.memory
[CRITICAL] Rakendusel on PodDisruptionBudget
  · Sobivat PodDisruptionBudgetit ei leitud
      Soovitatav on defineerida PodDisruptionBudget, et vältida ootamatuid seisakuid Kubernetes
      hooldustööde ajal, näiteks node'i tühjendamisel.
[WARNING] Rakendusel on host PodAntiAffinity
  · Rakendusel ei ole seadistatud host podAntiAffinity't
      Soovitatav on seada podAntiAffinity, mis takistab mitmete rakenduse podide ajakava samale node'ile. See suurendab kättesaadavust, kui node muutub kättesaamatuks.

YAML läbib kubevali kontrollid, samas kui kube-score toob välja järgmised puudused:

  • Valmiduse kontrolle ei ole seadistatud.
  • Puuduvad CPU ja mälu ressursidele määratud request’id ja limit’id.
  • Pod katkestamise eelarveid ei ole määratud.
  • Puuduvad eraldi olemasolu reeglid (anti-affinity) maksimaalse kättesaadavuse suurendamiseks.
  • Konteiner töötab root’i õigustes.

Kõik need on asjakohased märkused puudustest, mis tuleb kõrvaldada, et Deployment oleks tõhusam ja usaldusväärsem.

Meeskond kube-score esitab teavet loetavas vormis, sealhulgas kõik tüüpi rikkumised HOIATUS ja KRITILINE, mis aitab väga arendamise käigus.

Soovijad, kes soovivad seda tööriista kasutada CI-pipe'i osana, saavad kasutada kompaktselt väljastamist lipuga --output-format ci (siinjuures väljastatakse ka testid koos tulemusega OK):

$ kube-score score base-valid.yaml --output-format ci

[HEA] http-echo apps/v1/Deployment
[HEA] http-echo apps/v1/Deployment
[KRIT] http-echo apps/v1/Deployment: (http-echo) CPU piirang ei ole seadistatud
[KRIT] http-echo apps/v1/Deployment: (http-echo) Mälupiirang ei ole seadistatud
[KRIT] http-echo apps/v1/Deployment: (http-echo) CPU nõue ei ole seadistatud
[KRIT] http-echo apps/v1/Deployment: (http-echo) Mälunõue ei ole seadistatud
[KRIT] http-echo apps/v1/Deployment: (http-echo) Pilt, millel on uusim silt
[HEA] http-echo apps/v1/Deployment
[KRIT] http-echo apps/v1/Deployment: Podil ei ole sobivat veebipoliitikat
[KRIT] http-echo apps/v1/Deployment: konteineril puudub readinessProbe
[KRIT] http-echo apps/v1/Deployment: (http-echo) Kontaineril pole seadistatud turvekonteksti
[KRIT] http-echo apps/v1/Deployment: Sobivat PodDisruptionBudgetit ei leitud
[HOIATUS] http-echo apps/v1/Deployment: Juhtimine ei ole seadistatud
[HEA] http-echo v1/Service
[HEA] http-echo v1/Service
[HEA] http-echo v1/Service
[HEA] http-echo v1/Service

Nagu kubeval, tagastab kube-score nullist erineva väljakoodiga, kui leidub test, mis lõppes veaga KRITILINE. Samuti on võimalik aktiveerida sarnane töötlemine ka HOIATUS.

Lisaks on võimalik kontrollida ressursse vastavuses erinevate API versioonidega (nagu kubeval). Kuid see teave on 'hardcode'itud ise kube-score'i: teistsugust Kubernetes'i versiooni valida ei ole võimalik. Selline piirang võib osutuda suureks probleemiks, kui plaanite klastrit uuendada või kui teil on mitu klastrit erinevate K8s versioonidega.

Pange tähele, et on juba olemas issue ettevõtte pakkumisega seda võimalust rakendada.

Lisainfo kube-score kohta leiate ametlikul kodulehel.

Kube-score testid on suurepärane vahend parimate praktikate rakendamiseks, kuid mis siis, kui on vajalik testi muuta või lisada oma reegleid? Kahjuks ei ole seda võimalik teha.

Kube-score ei ole laiendatav: sellele ei saa lisada poliitikaid ega kohandada neid.

Kui on vajalik kirjutada kohandatud teste ettevõtte heakskiidetud poliitikate kontrollimiseks, saate kasutada mõnda järgmistest neljast tööriistast: config-lint, copper, conftest või polaris.

3. Config-lint

Config-lint on YAML, JSON, Terraform, CSV ja Kubernetes manifestide konfiguratsioonifailide valideerimise tööriist.

Selle saab paigaldada juhistega projekti veebilehelt.

Praegune väljaanne originaali kirjutamise hetkel — 1.5.0.

Config-lint ei sisalda sisse ehitatud teste Kubernetes manifestide kontrollimiseks.

Iga testi läbiviimiseks on vajalik luua vastavad reeglid. Need kirjutatakse YAML-failidesse, mida nimetatakse 'reeglistikeks' (rulesets), ja neil on järgmine struktuur:

version: 1
description: Reeglid Kubernetes spetsiifiliste failide jaoks
type: Kubernetes
files:
  - "*.yaml"
rules:
   # reeglite nimekiri

(rule.yaml)

Uurime seda lähemalt:

  • Väli type märgib, millist konfiguratsioonitüüpi config-lint kasutada. K8si manifestide jaoks on see alati Kubernetes.
  • Väljal files nende failide kõrval saab määrata ka kausta.
  • Väli rules on ette nähtud kasutaja testide määramiseks.

Oletame, et soovite veenduda, et Deployment'is olevad pildid laaditakse alati usaldusväärsest registrist, näiteks my-company.com/myapp:1.0. config-lint'i reegel, mis sellist kontrolli teostab, näeb välja järgmine:

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment peab kasutama kehtivat pildimärki
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

(rule-trusted-repo.yaml)

Iga reegel peab sisaldama järgmisi atribuute:

  • id — reegli unikaalne identifikaator;
  • severity — võib olla FAILURE, HOIATUS ja NON_COMPLIANT;
  • message — reegli rikkumise korral kuvatakse selle rea sisu;
  • resource — ressurssi tüüp, millele seda reeglit rakendatakse;
  • assertions — tingimuste loetelu, mida hinnatakse antud ressursi suhtes.

Ülaltoodud reeglites assertion nimetusega every kontrollib, et kõik konteinerid Deployment'is (key: spec.templates.spec.containers) kasutavad usaldusväärseid pilte (st, mis algavad my-company.com/).

Täielik reeglistik näeb välja järgmine:

versioon: 1
kirjeldus: Kubernetes'i spetsifikatsioonifailide reeglid
tüüp: Kubernetes
failid:
  - "*.yaml"
reeglid:

 - id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
    tõsidus: FAILURE
    sõnum: Deployment peab kasutama kehtivat pildirepositooriumi
    ressurss: Deployment
    väidete:
      - iga:
          võtme: spec.template.spec.containers
          väljendid:
            - võtme: image
              op: algab
              väärtus: "my-company.com/"

(ruleset.yaml)

Selle testi katsetamiseks salvestame selle nimega check_image_repo.yaml. Käivitame kontrolli faili üle base-valid.yaml:

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

[
  {
  "AssertionMessage": "Iga väide ebaõnnestub: ja väide ebaõnnestub: pilt ei alga my-company.com/-ga",
  "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 peab kasutama kehtivat pildirepositooriumi",
  "Status": "FAILURE"
  }
]

Kontroll ebaõnnestus. Nüüd kontrollime järgmist manifesti, millel on õige pildirepositoorium:

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äivitame sama testi eespool toodud manifestiga. Probleeme ei tuvastatud:

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

Config-lint — arene, mis võimaldab luua kohandatud teste Kubernetes YAML-manifestide kontrollimiseks YAML DSL-i abil.

Aga mida teha, kui on vajalik keerulisem loogika ja testid? Kas YAML võimalused ei ole selle jaoks liiga piiratud? Mis oleks, kui saaksime testid luua täisväärtuslikus programmeerimiskeeles?

4. Copper

Copper V2 — see on raamistik manustamisretseptide valideerimiseks kohandatud testide abil (sarnane config-lint’ile).

Kuid see erineb viimasest selle poolest, et ei kasuta testide kirjeldamiseks YAML-i. Selle asemel saab testid luua JavaScriptis. Copper pakub raamatukogu, mis sisaldab mitmeid põhivahendeid, mis aitavad lugeda teavet Kubernetes objektide kohta ja teatada vigadest.

Copperi installimiseks vajalikud sammud leiate ametlikus dokumentatsioonis.

2.0.1 — see on uusim versioon sellest utiliidist artikli kirjutamise ajal.

Nagu config-lint, ei oma ka Copper sisseehitatud teste. Kirjutame ühe. Las see kontrollib, et väljastused kasutavad konteinerit piltide jaoks ainult usaldusväärsetest hoidlatest nagu my-company.com.

Looge fail check_image_repo.js järgnevate sisu kujul:

$$.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üüd, et kontrollida meie manifesti base-valid.yaml, kasutage käsku 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

On selge, et copper võimaldab keerukamaid teste — näiteks kontrollida ingressi manifestides domeeninimesid või tagasi lükata pod'e, mis töötavad privileeritud režiimis.

Copperis on mitmeid utiliite:

  • DockerImage loeb määratud sisendfaili ja loob objekti järgmiste atribuutidega:
    • name — pildi nimi,
    • tag — pildi silt,
    • registry — pildiregister,
    • registry_url — protokoll (https://) ja pildiregister,
    • fqin — pildi täielik asukoht.
  • Function findByName aitab leida ressursi määratud tüübi (kind) ja nime (name) põhjal sisendfailist.
  • Function findByLabels aitab leida ressursi määratud tüübi (kind) ja markerite (labels).

Kõikide saadavalolevate utiliitide kohta saate lugeda siit.

Vaikimisi laadib see kogu sisendi YAML-faili muutujasse $$ ja muudab selle skriptidele kergesti kättesaadavaks (tuttav meetod neile, kellel on kogemusi jQuery-ga).

Copperi peamine eelis on selge: teil ei ole vaja õppida spetsiifilist keelt ja saate kasutada erinevaid JavaScripti võimalusi oma testide loomiseks, nagu stringide interpolatsioon, funktsioonid jne.

Samuti tasub mainida, et praegune Copperi versioon töötab JavaScripti mootoriga versioonis ES5, mitte ES6.

Üksikasjad on saadaval projekti ametlikul veebilehel.

Kuid kui te ei armasta JavaScripti ning eelistate keelt, mis on spetsiaalselt mõeldud päringute koostamiseks ja poliitikate kirjeldamiseks, peaksite vaatama conftest'i.

5. Conftest

Conftest on konfiguratsioonide verifitseerimise raamistik. Sobib ka Kubernetes'i manifestide testimiseks/valideerimiseks. Testid on kirjutatud spetsialiseeritud päringute keeles Rego.

Conftest'i saab installida juhistega, mis on toodud projekti veebilehel.

Kuna kirjutamise ajal oli originaalartikli kõige uuem versioon 0.18.2.

Sarnaselt config-lint-ile ja copper-ile, conftest ei tule koos ühegi sisseehitatud testiga. Proovime seda ja kirjutame oma poliitika. Nagu eelmistes näidetes, kontrollime, kas konteineripildid pärinevad usaldusväärsest allikast.

Looge kataloog conftest-checks, ja selles — fail nimega check_image_registry.rego järgnevate sisu kujul:

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

Nüüd katsetame base-valid.yaml kaudu 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

Test ebaõnnestus, kuna pildid pärinevad usaldusväärsest allikast.

Rego failis määrame ploki deny. Selle tõeväärtust käsitletakse rikkumisena. Kui plokke deny on mitu, kontrollib conftest neid ükshaaval ning ühe ploki tõeväärtus tõlgendatakse rikkumisena.

Lisaks vaikimisi väljundile toetab conftest JSON-i, TAP-i ja tabeliformaati — äärmiselt kasulik võimalus, kui on vaja integreerida aruanded olemasolevasse CI-pipeline'i. Soovitud formaati saab määrata lipuga --output.

Politikate hõlbustamiseks on conftestis lipp --trace. See väljastab jälgimise, kuidas conftest analüüsib esitatud poliitikafaile.

Conftesti poliitikaid saab avaldada ja nendega jagada OCI registrites (Open Container Initiative) artefaktidena.

Meeskonnad push ja pull võimaldavad artefakti avaldamist või olemasoleva artefakti väljavõtmist kaugregistrist. Proovime avaldada meie loodud poliitika kohaliku Docker registriga kasutades conftest push.

Käivitage kohalik Docker register:

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

Teises terminalis minge varem loodud katalooge conftest-checks ja tee järgmine käsk:

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

Kui käsk õnnestus, näete järgmise tüüpi sõnumit:

2020/06/10 14:25:43 pushitud pakett koos digestiga: sha256:e9765f201364c1a8a182ca637bc88201db3417bacc091e7ef8211f6c2fd2609c

Nüüd looge ajutine kataloog ja käivitage selles käsk conftest pull. See laadib alla paketi, mis loodi eelmise käsuga:

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

Ajutises kataloogis ilmub alamkataloog policy, sisaldades meie poliitikafaili:

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

Teste saab läbi viia otse hoidlast:

$ conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
EBA - base-valid.yaml - pilt 'hashicorp/http-echo' ei pärine tule my-company.com repositooriumist
2 testi, 1 läbis, 0 hoiatused, 1 ebaõnnestumine

Kahjuks ei toeta DockerHub praegu. Nii et võiks öelda, et olete õnnelik, kui kasutate Azure Container Registry (ACR) või oma registrit.

Artefakti formaat on sama mis Open Policy Agent (OPA) paketidel, mis võimaldab kasutada conftest'i olemasolevate OPA paketist testide käivitamiseks.

Rohkem poliitikate jagamisest ja conftest`i muudest omadustest saab lugeda projekti ametlikul veebilehel.

6. Polaris

Viimase tööriistana, millest juttu tuleb, on Polaris. (Me rääkisime selle eelmise aasta esitlemisest juba tõime tõlkeskommentaar tõlkijalt.)

Polaris võib paigaldada klastrisse või kasutada käsurežiimis. Nagu võite arvata, võimaldab see analüüsida Kubernetes'i manifeste.

Käsurežiimis on saadaval sisseehitatud testid, mis katavad selliseid valdkondi nagu turvalisus ja parimad praktikad (nagu kube-score). Lisaks saab luua oma teste (nagu config-lint, copper ja conftest).

Teisis sõnu, Polaris ühendab endas mõlema kategooria tööriistade eelised: nii sisseehitatud kui ka kasutajapõhised testid.

Polaris'i installimiseks käsurežiimis järgige projekti veebisaidi juhiseid.

Algse artikli kirjutamise ajal on saadaval versioon 1.0.3.

Pärast installimise lõpetamist saab polaris'e manifestiga käivitada base-valid.yaml järgmist käsku kasutades:

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

See genereerib JSON-formaadis rea, mis sisaldab üksikasjalikku teavet sooritatud testide ja nende tulemustega. Väljundil on järgmine struktuur:

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

Täielik väljund on saadaval siit.

Nagu kube-score, tuvastab ka Polaris probleemid valdkondades, kus manifest ei vasta parimatele praktikale:

  • Pod'ide tervisekontrollid puuduvad.
  • Konteineripiltide jaoks pole silte määratud.
  • Konteiner töötab root’i õigustes.
  • Mälu ja CPU nõuded ning limiidid pole määratud.

Iga testi puhul määratakse sõltuvalt selle tulemustest kriitilisuse tase: hoiatus või oht. Ette teada saada rohkem olemasolevate sisseehitatud testide kohta, võtke ühendust dokumentatsioonis.

Kui üksikasjad pole vajalikud, saate määrata lipu --format score. Sel juhul kuvab Polaris arvu vahemikus 1 kuni 100 — score (st. hinnang):

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

Mida lähemal on hinnang 100-le, seda kõrgem on vastavuse aste. Kui kontrollite käsku polaris audit, selgub, et see on võrdne 0.

Sundida polaris audit lõpetama mitte-nullkoodiga saab kasutada kaht lippu:

  • Lipp --set-exit-code-below-score võtab argumendiks piirdetähise vahemikus 1-100. Sel juhul lõpetab käsk exit-koodiga 4, kui skoor on madalam kui piirmäär. See on väga mugav, kui teil on mingi piirmäär (ütleme, 75) ja vajate hoiatust, kui skoor langeb alla selle.
  • Lipp --set-exit-code-on-danger tuleb käsk lõpetada koodiga 3, kui ükski danger-testidest ebaõnnestub.

Nüüd proovime luua kohandatud testi, mis kontrollib, kas pilt võetakse usaldusväärsest hoidlast. Kohandatud testid määratakse YAML formaadis ja test ise kirjeldatakse JSON Schema abil.

Järgmine YAML-i koodifragmendi kirjeldab uut testi, mida nimetatakse checkImageRepo:

checkImageRepo:
  successMessage: Pildi registri kontroll on kehtiv
  failureMessage: Pildi registri kontroll ei ole kehtiv
  category: Pildid
  target: Konteiner
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

Vaadakem sellele lähemalt:

  • successMessage — see rida kuvatakse, kui test õnnestub;
  • failureMessage — see sõnum kuvatakse ebaõnnestumise korral;
  • category — näitab ühte kategooriast: Pildid, Tervisekontrollid, Turvalisus, Võrgustik ja Ressursid;
  • target— määrab tüübi objekti (spec) millele test rakendub. Võimalikud väärtused: Konteiner, Pod või Kontroller;
  • Test ise määratakse objekti sees skeemaga JSON skeemi abil. Antud testis on võtmesõna pattern kasutatakse pildi allika võrdlemiseks nõutud.

Eelnimetatud testi käivitamiseks on vajalik järgmine Polaris konfiguratsioon:

checks:
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Pildi registri kontroll on kehtiv
    failureMessage: Pildi registri kontroll ei ole kehtiv
    category: Pildid
    target: Konteiner
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(polaris-conf.yaml)

Analüüsime faili:

  • Väljal checks määritellään testit ja niiden kriittisyystaso. Koska on suositeltavaa saada varoitus, kun kuva otetaan epäluotettavasta lähteestä, asetamme tälle tason oht.
  • Test ise checkImageRepo sitten määritellään objektissa customChecks.

Tallenna tiedosto nimellä custom_check.yaml. Nyt voit suorittaa polaris audit YAML-manifestilla, joka tarvitsee tarkistusta.

Testataan manifestimme base-valid.yaml:

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

Meeskond polaris audit suoritti vain ylle määritellyn käyttäjätestin, eikä se onnistunut.

Jos korjaat kuvan my-company.com/http-echo:1.0, Polaris päättyy onnistuneesti. Muokattu manifesti on jo olemassa repositoriis, joten voit tarkistaa edellisen komennon manifestista image-valid-mycompany.yaml.

Nyt kysymys kuuluu: miten käynnistää sisäänrakennetut testit yhdessä käyttäjätestien kanssa? Se on helppoa! Tarvitset vain lisätä sisäänrakennettujen testien tunnisteet konfiguraatiotiedostoon. Tällöin se saa seuraavan muodon:

kontrollid:
  cpuRequestsMissing: hoiatus
  cpuLimitsMissing: hoiatus
  # Teised sisseehitatud kontrollid..
  # ..
  # kohandatud kontrollid
  checkImageRepo: oht # !!!
kohandatudKontrollid:
  checkImageRepo:        # !!!
    successMessage: Piltide register on kehtiv
    failureMessage: Piltide register ei ole kehtiv
    category: Pildid
    target: Konteiner
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(config_with_custom_check.yaml)

Täieliku konfiguratsioonifaili näide on saadaval siit.

Kontrolli manifeesti base-valid.yaml, kasutades sisseehitatud ja kohandatud teste, saab teha käsuga:

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

Polaris täiendab sisseehitatud teste kohandatud testidega, ühendades seeläbi kahe maailma parimad küljed.

Teisest küljest võib võimetus kasutada tugevamaid keeli, nagu Rego või JavaScript, olla piirav tegur, mis takistab keerukamate testide loomist.

Lisainfot Polari kohta on saadaval projekti veebilehel.

Kokkuvõte

Kuigi on palju tööriistu Kubernetes YAML-failide kontrollimiseks ja hindamiseks, on oluline omada selget arusaama sellest, kuidas teste kavandatakse ja tehakse.

Näiteks, kui võtta Kubernetes'i manifeestid, mis läbivad torujuhe, võiks kubeval olla sellise torujuhtme esimene samm. Ta jälgiks, kas objektide määratlemine vastab Kubernetes API skeemile.

Pärast sellise kontrolli lõpetamist võiks edasi liikuda keerukamate testide juurde, nagu standardite järgimine ja spetsiifilised poliitikad. Siin tuleks kasuks kube-score ja Polaris.

Need, kellel on keerulised nõuded ja vajadus teste põhjalikult kohandada, võiksid valida copperi, config-linti ja conftesti..

Conftest ja config-lint kasutavad YAML-i kasutajate testide määratlemiseks, samas kui copper pakub juurdepääsu täisfunktsionaalsele programmeerimiskeelele, mis teeb selle üsna atraktiivseks valikuks.

Teisest küljest, kas tuleks kasutada ühte neist tööriistadest ja seega kirjutada kõik testid käsitsi, või valida Polaris ja lisada sinna ainult vajalikud osad? Sellele küsimusele pole üheselt vastust..

Allolev tabel sisaldab lühikest ülevaadet igast tööriistast:

Tööriista
Eesmärk
Puudused
Kasutajatestid

kubeval
Kontrollib YAML-manifestide vastavust konkreetse API skeemi versioonile.
Ei oska töötada CRD-dega.
Ei

kube-score
Analüüsib YAML-manifeste parimate tavade järgimise osas.
Ei saa valida oma Kubernetes API versiooni ressursside kontrollimiseks.
Ei

copper
YAML-manifestide jaoks kohandatud JavaScript-testide loomise üldine raamistik
Ei ole sisseehitatud teste. Piiratud dokumentatsioon
Jah

config-lint
YAML-ile integreeritud objektikeeltestide loomise üldine raamistik. Toetab erinevaid konfiguratsiooniformaate (nt Terraform)
Ei ole valmis teste. Sisseehitatud assertions ja funktsioonid võivad olla ebapiisavad
Jah

conftest
Rego (spetsialiseeritud päringute keel) abil oma testide loomise raamistik. Lubab jagada poliitikaid OCI pakettide kaudu
Ei ole sisseehitatud teste. Peab õppima Regot. Docker Hub ei toeta poliitikate avaldamist
Jah

Polaris
Analüüsib YAML-manifeste standardsete parimate praktikate järgimise osas. Lubab luua kohandatud teste JSON Schema abil
Testimise võimalused, mis põhinevad JSON Schemal, võivad olla ebapiisavad
Jah

Kuna need tööriistad ei sõltu Kubernetes'i klastri juurdepääsust, on nende paigaldamine lihtne. Need võimaldavad allikafaile filtreerida ja annavad pull request'ide autoritele kiire tagasiside.

P.S. tõlkija märkused

Lugege ka meie blogist:

Allikas: habr.com

Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid 🔥 Osta usaldusväärne veebihosting DDoS kaitsega, VPS VDS serverid | ProHoster