Validimi i YAML të Kubernetes për t'u përputhur me praktikat më të mira dhe politikat

Shën. përk.: Me rritjen e numrit të konfigurimeve YAML për ambientet K8s, bëhet gjithnjë e më e nevojshme verifikimi i tyre automatizuar. Autori i këtij shqyrtimi jo vetëm që ka përzgjedhur zgjidhje ekzistuese për këtë detyrë, por gjithashtu ka parë se si ato funksionojnë me një shembull të Deployment. Doli të jetë shumë informues për ata që janë të interesuar për këtë temë.

Validimi i YAML të Kubernetes për t'u përputhur me praktikat më të mira dhe politikat

TL;DR: Në artikullin e përmendet gjashtë mjete statike për kontrollin dhe vlerësimin e skedarëve YAML të Kubernetes në përputhje me praktikat më të mira dhe kërkesat.

Ngarkesat e punës në Kubernetes zakonisht përcaktohen në formën e dokumenteve YAML. Një nga problemet me YAML është vështirësia e vendosjes së kufizimeve ose marrëdhënieve ndërmjet skedareve të manifestit.

Çfarë ndodh nëse na duhen të sigurohemi që të gjitha imazhet që shpërndahen në klaster, vijnë nga një regjistër i besuar?

Si të parandalojmë dërgimin në klaster të Deployment-eve për të cilat nuk janë caktuar PodDisruptionBudgets?

Integrimi i testimit statik lejon identifikimin e gabimeve dhe shkeljeve të politikave që në fazën e zhvillimit. Kështu, rriten garancitë për saktësinë dhe sigurinë e definicionit të burimeve, dhe rritet probabiliteti që ngarkesat në prodhim të ndjekin praktikat më të mira.

Ekosistemi i kontrollit statik të skedarëve YAML të Kubernetes mund të ndahet në kategoritë vijuese:

  • Validuesit e API-ve. Veglat në këtë kategori verifikojnë manifestin YAML në përputhje me kërkesat e serverit të API-së Kubernetes.
  • Testerët e gatshëm. Veglat nga kjo kategori vijnë me teste të gatshme për sigurinë, përputhshmërinë me praktikat më të mira, etj.
  • Validuesit e përshtatur. Përfaqësuesit e kësaj kategorie lejojnë krijimin e testeve të personalizuara në gjuhë të ndryshme, të tilla si Rego dhe Javascript.

Në këtë artikull ne do të përshkruajmë dhe krahasojmë gjashtë vegla të ndryshme:

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

Mire, le të fillojmë!

Kontrolli i Deployment-ëve

Para se të fillojmë krahasimin e veglave, le të krijojmë një bazë të caktuar mbi të cilën do t'i testojmë.

Manifesti më poshtë përmban një sërë gabimesh dhe mospërputhjesh me praktikat më të mira: sa prej tyre do të jesh në gjendje t'i gjesh?

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)

Ne do të përdorim këtë YAML për të krahasuar mjete të ndryshme.

Manifesti i mësipërm base-valid.yaml dhe manifestet e tjera nga ky artikull mund të gjenden në Git-repositor të publikut.

Manifesti përshkruan një aplikacion web, detyra kryesore e të cilit është të kthejë mesazhin "Hello World" në portin 5678. Ai mund të vendoset me komandën e mëposhtme:

kubectl apply -f hello-world.yaml

Tani, kontrolloni funksionimin:

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

Tani shkoni në http://localhost:8080 dhe konfirmoni se aplikacioni po punon. Por a ndjek ai praktikat më të mira? Le të verifikojmë.

1. Kubeval

Në bazë të kubeval ka ka ideja se se konsideron se çdo ndërveprim me Kubernetes ndodh përmes API-të së tij REST. Në fjalë të tjera, mund të përdorni skemën e API-t për të verifikuar nëse ky YAML i përgjigjet asaj. Le të shohim një shembull.

Udhëzimet për instalimin kubeval janë në dispozicion në faqen e projektit.

Në momentin e shkrimit të artikullit origjinal, versioni 0.15.0 ishte në dispozicion.

Pas instalimit, le të "ndiqni" manifestin e mësipërm:

$ kubeval base-valid.yaml
PASS - base-valid.yaml përmban një Deployim të vlefshëm (http-echo)
PASS - base-valid.yaml përmban një Shërbim të vlefshëm (http-echo)

Në rast suksesi, kubeval do të përfundojë me kodin e daljes 0. Mund ta kontrolloni në këtë mënyrë:

$ echo $?
0

Tani le të provojmë kubeval me një manifest tjetër:

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)

A mund ta identifikoni problemin me sy? Po fillojmë:

$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml përmban një Deployim të pavlefshëm (http-echo) - selektori: selektori është i kërkuar
PASS - kubeval-invalid.yaml përmban një Shërbim të vlefshëm (http-echo)

# le të kontrollojmë kodin e kthimit
$ echo $?
1

Burimi nuk kalon verifikimin.

Deployment'ët që përdorin versionin e API apps/v1, duhet të përfshijnë një selektor që i përket etiketës së pod'it. Manifesti më sipër nuk përfshin selektor, kështu që kubeval raportoi një gabim dhe doli me një kod jo zero.

E çuditshme, çfarë do të ndodhte nëse ekzekutoni kubectl apply -f me këtë manifest?

Epo, le të provojmë:

$ kubectl apply -f kubeval-invalid.yaml
error: error validating "kubeval-invalid.yaml": error validating data: ValidationError(Deployment.spec):
mungon fusha e domosdoshme "selector" në io.k8s.api.apps.v1.DeploymentSpec; nëse zgjidhni të injoroni këto gabime,
ktheni verifikimin jashtë me --validate=false

Ishte pikërisht ajo gabim, për të cilin paralajmëroi kubeval. Mund ta rregulloni këtë duke shtuar selektorin:

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)

Përshtatshmëria e mjeteve si kubeval është se këto gabime mund të kapen në faza të hershme të ciklit të shpërndarjes.

Përveç kësaj, për këto kontrolle nuk kërkohet akses në klaster: ato mund të kryhen offline.

Është e parazgjedhur që kubeval të kontrollojë Burimet për përputhshmërinë me skemën më të fundit të API-së së Kubernetes. Megjithatë, në shumicën e rasteve mund të dëshironi të kontrolloni përputhshmërinë për një version specifik të Kubernetes. Këtë mund ta bëni me ndihmën e flamurit --kubernetes-version:

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

Vini re se versioni duhet të specifikohet në formatin Major.Minor.Patch.

Për të parë listën e versioneve për të cilat mbështetet kontrolli, referohuni te skema JSON në GitHub, e cila kubeval përdor për vlefshmërinë. Nëse duhet të ekzekutoni kubeval offline, shkarkoni skemat dhe specifikoni vendndodhjen lokale të tyre me ndihmën e flamurit --schema-location.

Përveç skedarëve të veçantë YAML, kubeval gjithashtu mund të punojë me direktori dhe stdin.

Për më tepër, Kubeval lehtë integrohet në pipeline CI. Ata që dëshirojnë të kryejnë teste para dërgimit të manifestimeve në klaster do të jenë të lumtur të dinë se kubeval mbështet tre formate dalëse:

  1. Teksti i zakonshëm;
  2. JSON;
  3. Test Anything Protocol (TAP).

Dhe çfarëdo formati mund të përdoret për parse të mëtejshëm të daljes për të formuar një përmbledhje të rezultateve në formatin e dëshiruar.

Një nga disavantazhet e kubeval është se aktualisht ai nuk mund të verifikojë përputhshmërinë me Custom Resource Definitions (CRD-të). Megjithatë, është e mundur të konfiguroni kubeval të injorojë ato.

Kubeval është një mjet i shkëlqyer për të verifikuar dhe vlerësuar burimet; megjithatë, duhet të theksohet se kalimi i suksesshëm i provimit nuk garanton që burimi përputhet me praktikat më të mira.

Për shembull, përdorimi i etiketës latest në kontejner nuk i përgjigjet praktikave më të mira. Megjithatë, kubeval nuk e konsideron këtë si një gabim dhe nuk e raporton atë. Kështu që verifikimi i tillë YAML përfundon pa paralajmërime.

Por çfarë nëse duhet të vlerësohet YAML dhe të identifikohen shkeljet si etiketën latest? Как проверить YAML-файл на соответствие лучшим практикам?

2. Kube-score

Kube-score analizon manifestet YAML dhe i vlerëson ato sipas testeve të brendshme. Këto teste zgjidhen mbi bazën e rekomandimeve për sigurinë dhe praktikat më të mira, për shembull:

  • Ekzekutimi i kontejnerit jo si root.
  • Prania e kontrolleve të shëndetit të pod’ëve.
  • Caktimi i kërkesave dhe limiteve për resurset.

Pas testit jepen tri rezultate: OK, WARNING dhe CRITICAL.

Kube-score mund të provohet në internet ose të instalohet lokalisht.

Në momentin e shkruarjes së artikullit origjinal, versioni më i fundit i kube-score ishte 1.7.0.

Le të provojmë atë në manifestin tonë base-valid.yaml:

$ kube-score score base-valid.yaml

apps/v1/Deployment http-echo
[KRITIKAL] Container Image Tag
  · http-echo -> Imazh me etiketën më të fundit
      Përdorimi i një etikete fikse është i rekomanduar për të shmangur përmirësimet e rastësishme
[KRITIKAL] Pod NetworkPolicy
  · Pod-i nuk ka një politikë rrjeti të përshtatshme
      Krijoni një Politike Rrjeti që synon këtë pod
[KRITIKAL] Pod Probes
  · Kontejneri po i mungon një readinessProbe
      Duhet të përdoret një readinessProbe për të treguar kur shërbimi është gati për të pranuar trafik.
      Pa të, Pod-i rrezikon të marrë trafik para se të jetë ngarkuar. Përdoret gjithashtu gjatë
      rrotullimeve dhe mund të parandalojë kohë të çregullt nëse një version i ri i aplikacionit dështon.
      Më shumë informacion: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[KRITIKAL] Container Security Context
  · http-echo -> Kontejneri nuk ka një kontekst të sigurisë të konfiguruar
      Cilësoni securityContext për të drejtuar kontejnerin në një kontekst më të sigurt.
[KRITIKAL] Container Resources
  · http-echo -> Kufiri i CPU-së nuk është vendosur
      Kufijtë e burimeve rekomandohen për të shmangur DDOS-in e burimeve. Cilësoni resources.limits.cpu
  · http-echo -> Kufiri i memories nuk është vendosur
      Kufijtë e burimeve rekomandohen për të shmangur DDOS-in e burimeve. Cilësoni resources.limits.memory
  · http-echo -> Kërkesa për CPU-në nuk është vendosur
      Kërkesat për burime janë të rekomanduara për të siguruar që aplikacioni mund të fillojë dhe të funksionojë pa
      u çarë. Cilësoni resources.requests.cpu
  · http-echo -> Kërkesa për memorien nuk është vendosur
      Kërkesat për burime janë të rekomanduara për të siguruar që aplikacioni mund të fillojë dhe të funksionojë pa
      u çarë. Cilësoni resources.requests.memory
[KRITIKAL] Deployment ka PodDisruptionBudget
  · Nuk u gjet asnjë PodDisruptionBudget i përshtatshëm
      Rekomandohet të përcaktoni një PodDisruptionBudget për të shmangur kohë të papritur të çregullt gjatë
      operacioneve të mirëmbajtjes në Kubernetes, si kur po ndërpritet një nod.
[KËRCËNIM] Deployment ka host PodAntiAffinity
  · Deployment-i nuk ka një podAntiAffinity të konfiguruar
      Rekomandohet të vendosni një podAntiAffinity që ndalon shumë pods nga një deployment të
      programohen në të njëjtin nod. Kjo rrit disponueshmërinë në rast se nodi bëhet jo i disponueshëm.

YAML kontrollohet nga kubeval, ndërsa kube-score tregon këto mangësi:

  • Kontrollimet e gatishmërisë nuk janë të konfiguruara.
  • Nuk ka request dhe limit të burimeve CPU dhe memorie.
  • Buxhetet për prishjen e Pod-eve nuk janë të caktuara.
  • Nuk ka rregulla për ndarje të veçantë. (anti-affinity) për maksimalizimin e disponueshmërisë.
  • Konteinieri ekzekutohet nën root.

Të gjitha këto janë vërejtje të arsyeshme për mangësitë që duhet të zgjidhen për të bërë Deployment më efikas dhe të besueshëm.

Ekipa kube-score jep informacion në një format të lehtë për t'u lexuar duke përfshirë të gjitha shkeljet e tipit WARNING dhe CRITICAL, e cila ndihmon shumë gjatë zhvillimit.

Ata që dëshirojnë të përdorin këtë instrument në një pipeline CI mund të përfshijnë një dalje më të shkurtër duke përdorur flamurin --output-format ci (në këtë rast, gjithashtu shfaqen testet me rezultate 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) Kufiri për CPU nuk është vendosur
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Kufiri për memorie nuk është vendosur
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Kërkesa për CPU nuk është vendosur
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Kërkesa për memorie nuk është vendosur
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Imazhi me etiketën më të fundit
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: Pod-i nuk ka një politikë rrjeti përkatëse
[CRITICAL] http-echo apps/v1/Deployment: Konteineri i mungon readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Konteineri nuk ka një kontekst sigurie të konfiguruar
[CRITICAL] http-echo apps/v1/Deployment: Nuk u gjet një PodDisruptionBudget përputhës
[WARNING] http-echo apps/v1/Deployment: Deployimi nuk ka një podAntiAffinity të vendosur
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service

Si kubeval, kube-score kthen një kod dalës jo zero nëse ka një test që përfundon me gabim CRITICAL. Gjithashtu, mund të aktivizohet një trajtim i ngjashëm edhe për WARNING.

Për më tepër, ekziston mundësia e verifikimit të burimeve për përputhshmërinë me versione të ndryshme API (ashtu si në kubeval). Megjithatë, kjo informacion është 'hardcode'-uar në vetë kube-score: nuk mund të zgjidhni një version tjetër të Kubernetes. Një kufizim i tillë mund të bëhet një problem i madh, nëse keni ndërmend të përditësoni klastri ose keni disa klasterë me versione të ndryshme të K8s.

Merrni parasysh se ekziston tashmë një çështje për të propozuar implementimin e kësaj mundësie.

Më shumë rreth kube-score mund të mësoni në faqen zyrtare.

Testet kube-score janë një instrument i shkëlqyer për të zbatuar praktikat më të mira, por çfarë ndodh nëse duhet të bëni ndryshime në test ose të shtoni rregulla të personalizuara? Më vjen keq, kjo nuk është e mundur.

Kube-score nuk është i zgjerueshëm: nuk mund të shtoni politika ose t'i përshtatni ato.

Nëse duhet të shkruani teste të personalizuara për kontrollin e përputhshmërisë me politikat e pranuara në kompani, mund të përdorni një nga katër mjetet e mëposhtme: config-lint, copper, conftest ose polaris.

3. Config-lint

Config-lint është një mjet për validimin e skedarëve të konfigurimit në formatet YAML, JSON, Terraform, CSV dhe manifestet Kubernetes.

Mund ta instaloni me anë të udhëzimeve në faqen e projektit.

Përditësimi aktual në momentin e përgatitjes së artikujve origjinal është 1.5.0.

Config-lint nuk përmban teste të grumbulluara për kontrollin e manifestëve Kubernetes.

Për të kryer çfarëdo testi, është e nevojshme të krijoni rregulla përkatëse. Ato regjistrohen në skedarët YAML, të quajtur 'grupe rregullash' (rulesets), dhe kanë këtë strukturë:

version: 1
description: Rregullat për skedarët e specifikimit të Kubernetes
type: Kubernetes
files:
  - "*.yaml"
rules:
   # lista e rregullave

(rule.yaml)

Le të shqyrtojmë atë më në detaje:

  • Fusha type cakton se cilat lloje konfigurimi do të përdoret nga config-lint. Për manifestet K8s, kjo është përherë Kubernetes.
  • Në fushën files përveç vetë skedarëve, mund të specificoni një direktor.
  • Fusha rregulla i destinuar për caktimin e testeve të përdoruesve.

Supozoni se doni të siguroheni që imazhet në Deployment të ngarkohen gjithmonë nga një depo e besueshme si my-company.com/myapp:1.0. Rregulli për config-lint që kryen këtë kontroll do të duket si më poshtë:

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment duhet të përdorë një etiketë valide imazhi
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

(rule-trusted-repo.yaml)

Për çdo rregull duhet të specifikohen atributet e mëposhtme:

  • id — identifikues unik i rregullit;
  • severity — mund të jetë FAILURE, WARNING dhe NON_COMPLIANT;
  • message — kur shkelja e rregullit ndodh, përmbajtja e këtij rreshti shfaqet;
  • resource — tipi i burimit për të cilin aplikohet ky rregull;
  • assertions — lista e kushteve që do të vlerësohen për këtë burim.

Në rregullin e mësipërm assertion të quajtur every kontrollon që të gjithë kontainerët në Deployment (key: spec.templates.spec.containers) përdorin imazhe të besueshme (dmth, që fillojnë me my-company.com/).

Seti i plotë i rregullave duket si në vazhdim:

version: 1
description: Rregullat për skedarët spec të Kubernetes
type: Kubernetes
files:
  - "*.yaml"
rules:

 - id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
    severity: FAILURE
    message: Deployimi duhet të përdorë një depo të vlefshme të imazheve
    resource: Deployment
    assertions:
      - çdo:
          key: spec.template.spec.containers
          expressions:
            - key: image
              op: starts-with
              value: "my-company.com/"

(ruleset.yaml)

Për të provuar testin, le të ruajmë atë si check_image_repo.yaml. Të ekzekutojmë kontrollin mbi skedarin base-valid.yaml:

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

[
  {
  "AssertionMessage": "Çdo shprehje dështon: Dhe shprehja dështon: imazhi nuk fillon me 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": "Deployimi duhet të përdorë një depo të vlefshme të imazheve",
  "Status": "FAILURE"
  }
]

Kontrolli përfundoi pa sukses. Tani le të kontrollojmë manifestin e ardhshëm me depo të saktë imazhesh:

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)

Ne poštuam të njëjtin test me manifestin e lartpërmendur. Nuk u gjetën probleme:

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

Config-lint është një framework i avancuar që lejon krijimin e testeve të personalizuara për verifikimin e manifestëve YAML të Kubernetes duke përdorur YAML DSL.

Por çfarë të bëjmë nëse kërkohet logjikë dhe teste më komplekse? A nuk janë mundësitë e YAML shumë të vogla për këtë? Çfarë ndodh nëse do të ishte e mundur të krijoheshin teste në një gjuhë programimi të plotë?

4. Copper

Copper V2 është një framework për verifikimin e manifestëve me teste të personalizuara (analog me config-lint).

Megjithatë, nga i fundit, ai ndryshon sepse nuk përdor YAML për të përshkruar testet. Në vend të kësaj, testet mund të krijohen në JavaScript. Copper ofron një bibliotekë me disa mjete bazike, të cilat ndihmojnë në leximin e informacionit rreth objekteve Kubernetes dhe raportimin e gabimeve.

Sekuenca e hapave për të instaluar Copper mund të gjendet në dokumenti zyrtar.

2.0.1 — lëshimi më i ri i kësaj utilitare në momentin e shkrimit të artikullit origjinal.

As with config-lint, Copper does not have built-in tests. Let’s write one. It should check that deployments use container images exclusively from trusted repositories such as my-company.com.

Krijoni një skedar check_image_repo.js me përmbajtjen e mëposhtme:

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

Now, to check our manifest base-valid.yaml, use the command 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 clear that with copper, more complex tests can be conducted — for example, checking domain names in Ingress manifests or rejecting pods running in privileged mode.

Copper has various utility functions built-in:

  • DockerImage reads the specified input file and creates an object with the following attributes:
    • emri — image name,
    • tag — image tag,
    • registry — image registry,
    • registry_url — protocol (https://) and image registry,
    • fqin — fully qualified image location.
  • Funksioni findByName helps to find a resource by the specified type (kind) and name (emri) from the input file.
  • Funksioni findByLabels ndihmon në gjetjen e burimit sipas tipit të especificuar (kind) dhe etiketimeve (etiketat).

Me të gjitha funksionet e disponueshme mund të njiheni këtu.

Për default, ngarkon të gjithë skedarin YAML hyrës në një variabël $$ dhe e bën atë të disponueshme për skriptet (një metodë e njohur për ata që kanë përvojë me jQuery).

Avantazhi kryesor i Copper është evidente: nuk keni nevojë të mësoni një gjuhë të specializuar dhe mund të shfrytëzoni mundësi të ndryshme të JavaScript për të krijuar testet tuaja, si interpolimin e vargjeve, funksionet, etj.

Duhet të theksohet gjithashtu se versioni aktual i Copper punon me versionin ES5 të motorit JavaScript, dhe jo me ES6.

Të dhënat e plota janë të disponueshme në faqja zyrtare e projektit.

Megjithatë, nëse nuk e pëlqeni shumë JavaScript dhe preferoni një gjuhë të dedikuar për krijimin e kërkesave dhe përshkrimin e politikave, duhet të shihni conftest.

5. Conftest

Conftest është një kornizë për verifikimin e të dhënave të konfigurimit. E përshtatshme për testimin/verifikimin e manifestove Kubernetes. Testet përshkruhen me një gjuhë të specializuar kërkesash Rego.

Conftest mund të instaloni me udhëzimeve, të dhënat që gjenden në faqen e projektit.

Në momentin e shkruarjes së artikullit origjinal, versioni më i fundit i disponueshëm ishte 0.18.2.

Në mënyrë të ngjashme me config-lint dhe copper, conftest vjen pa asnjë test të integruar. Le të provojmë atë dhe të shkruajmë politikën tonë. Si në shembujt e mëparshëm, ne do të kontrollojmë nëse imazhet e kontejnerëve vijnë nga një burim të besueshëm.

Krijoni një drejtorinë conftest-checks, dhe brenda saj — një skedar me emrin check_image_registry.rego me përmbajtjen e mëposhtme:

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

Tani le të testojmë base-valid.yaml përmes 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

Testi dështoi siç pritej, pasi imazhet vijnë nga një burim të patregueshëm.

Në skedarin Rego ne caktojmë bllokun deny. Vlerësimi i tij konsiderohet si një shkelje. Nëse ka disa blloqe, conftest i kontrollon ato në mënyrë të pavarur, dhe vlerësimi i çdo blloku interpretohet si një shkelje. deny disa, conftest i kontrollon ato në mënyrë të pavarur, dhe vërtetësia e ndonjë prej blloqeve interpretohet si një shkelje.

Përveç formatit të parazgjedhur, conftest mbështet JSON, TAP dhe formatin tabelar — një veçori jashtëzakonisht e dobishme nëse duhet të integrohet raportet në një pipeline ekzistues CI. Formati i dëshiruar mund të caktohet me flagun --output.

Për lehtësimin e debagimit të politikave, conftest ka një flag --trace. Ai shfaq gjurmimin e asaj si conftest analizojnë skedarët e politikave të caktuar.

Politikat e conftest mund të publikohen dhe të ndahen në regjistrat OCI (Open Container Initiative) si artefakte.

Ekipet push dhe pull lejojnë publikimin e një artefakti ose nxjerrjen e një artefakti ekzistues nga një regjistër të largët. Le të provojmë të publikojmë politikën që krijuam në një regjistër lokal Docker duke përdorur conftest push.

Startoni regjistrin lokal Docker:

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

Në një terminal tjetër, kaloni në direktorine që keni krijuar më parë conftest-checks dhe ekzekutoni komandën e mëposhtme:

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

Nëse komanda kaloi me sukses, do të shihni një mesazh të këtij lloji:

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

Tani krijoni një direktor të përkohshëm dhe ekzekutoni në të komandën conftest pull. Kjo do ta shkarkojë paketën në të krijuar nga komandën e mëparshme:

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

Në direktorinë e përkohshme do të shfaqet një nënfolder policy, që përmban skedarin tonë të politikës:

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

Testet mund të ekzekutohen direkt nga ruajtja:

$ conftest test --update 127.0.0.1:5000/amitsaha/opa-bundle-example:latest base-valid.yaml
..
DËMTIM - base-valid.yaml - imazhi 'hashicorp/http-echo' nuk vjen nga depoja my-company.com
2 teste, 1 kaluar, 0 paralajmërime, 1 dështim

Fatkeqësisht, DockerHub aktualisht nuk mbështetet. Prandaj, konsideroni se keni fat nëse përdorni Azure Container Registry (ACR) ose regjistrin tuaj personal.

Formati i artefakteve është i njëjtë me atë të paketave Open Policy Agent (OPA), që lejon përdorimin e conftest për të ekzekutuar teste nga paketat ekzistuese OPA.

Më shumë mbi ndarjen e politikave dhe karakteristika të tjera të conftest mund të mësoni në faqja zyrtare e projektit.

6. Polaris

Në lidhje me mjetin e fundit që do të diskutojmë në këtë artikull, është Polaris. (Ne e përkthyer njoftimin e tij të vitit të kaluar që kemi përkthyershën. transl.)

Polaris mund të instalohet në klasër ose të përdoret në modalitetin e linjës së komandave. Siç e keni kuptuar, ai lejon analizimin statik të manifestimeve Kubernetes.

Kur punoni në mënyrën e komandës, janë të disponueshme teste të integruara që mbulojnë fusha si siguria dhe praktikat më të mira (ngjashëm me kube-score). Për më tepër, është e mundur të krijoni teste të personalizuara (si në config-lint, copper dhe conftest).

Me fjalë të tjera, Polaris kombinon përfitimet e të dy kategorive të mjeteve: me teste të integruara dhe të personalizuara.

Për të instaluar Polaris në mënyrën e komandës, përdorni instruksionet në faqen e projektit..

Në momentin e shkruarjes së artikullit origjinal, versioni 1.0.3 është i disponueshëm.

Pas përfundimit të instalimit, mund të zhvilloni polaris në manifestin base-valid.yaml duke përdorur komandën e mëposhtme:

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

Ajo do të japë një varg në formatin JSON me një përshkrim të detajuar të testeve të kryera dhe rezultateve të tyre. Dalja do të ketë këtë 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": [
    /* lista e gjatë */
  ]
}

Dalja e plotë është e disponueshme këtu.

Si kube-score, Polaris identifikon probleme në ato fusha ku manifesti nuk përputhet me praktikat më të mira:

  • Nuk ka verifikime për shëndetin e pod’ëve.
  • Nuk janë përcaktuar etiketat për imazhet e konteinerëve.
  • Konteinieri ekzekutohet nën root.
  • Nuk janë përcaktuar kërkesat dhe kufizimet për memorien dhe CPU.

Çdo test i caktohet një gradë kriticizmi varësisht nga rezultatet e tij: warning ose danger. Për të mësuar më shumë rreth testeve të integruara, kontaktoni dokumentacion.

Nëse detajet nuk janë të nevojshme, mund të përcaktoni flamurin --format score. Në këtë rast, Polaris do të shfaqë një numër në intervalin nga 1 deri në 100 — score (dmth. vlerësim):

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

Sa më afër të jetë vlerësimi 100, aq më i lartë është niveli i përputhshmërisë. Nëse kontrolloni exit-kodin e komandës polaris audit, do të rezultojë se ai është 0.

Të detyroni polaris audit të përfundojë me kod jo zero mund të bëhet me dy flamuj:

  • Flamuri --set-exit-code-below-score pranon si argument një vlerë prag në intervalin 1-100. Në këtë rast, komanda do të përfundojë me kodin e exit 4, nëse vlerësimi është më i ulët se pragu. Kjo është shumë e përshtatshme, kur keni një vlerë prag (thoni, 75), dhe duhet të merrni një alert nëse vlerësimi bie nën këtë.
  • Flamuri --set-exit-code-on-danger do të çojë në përfundimin e komandës me kodin 3, nëse një nga testet e rrezikut dështon.

Tani, le të provojmë të krijojmë një test personalizuar, i cili kontrollon nëse imazhi merret nga një depo e besueshme. Testet e personalizuara përcaktohen në formatin YAML, dhe vetë testi përshkruhet me anë të JSON Schema.

Fragmenti i mëposhtëm i kodit YAML përshkruan një test të ri, të quajtur checkImageRepo:

checkImageRepo:
  successMessage: Regjistri i imazheve është valid
  failureMessage: Regjistri i imazheve nuk është valid
  category: Imazhe
  target: Kontejner
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

Le të hedhim një vështrim më të afërt:

  • successMessage — kjo varg do të shfaqet nëse prova përfundon me sukses;
  • failureMessage — kjo mesazh do të shfaqet në rast të dështimit;
  • category — tregon një nga kategoritë: Imazhe, Kontrolli i Shëndetit, Siguria, Rrjetëzimi dhe Burimet;
  • target—- përcakton se për cfarë lloji objekti (spec) aplikohet testi. Vlerat e mundshme: Konteineri, Pod ose Controller;
  • Testi i vetë përcaktohet në objektin schema me anë të JSON schema. Në këtë test, kërkesa pattern përdoret për të krahasuar burimin e imazhit me atë të kërkuar.

Për të ekzekutuar testin e mësipërm, është e nevojshme të krijoni konfigurimin e mëposhtëm të Polaris:

kontrollon:
  kontrolloImageRepo: rrezik
kontrolleTëPersonalizuara:
  kontrolloImageRepo:
    mesazhiSuksesit: Regjistri i imazheve është i vlefshëm
    mesazhiDështimi: Regjistri i imazheve nuk është i vlefshëm
    kategoria: Imazhe
    objekti: Konteineri
    skema:
      '$schema': http://json-schema.org/draft-07/schema
      lloji: objekti
      pronat:
        imazhi:
          lloji: string
          model: ^my-company.com/.+$

(polaris-conf.yaml)

Le të analizojmë skedarin:

  • Në fushën kontrollon përshkruhen testet dhe niveli i rëndësisë së tyre. Duke qenë se është e preferueshme të merrni një paralajmërim kur imazhi merret nga një burim i pasigurt, vendosim këtu nivelin danger.
  • Testi vete checkImageRepo më pas përshkruhet në objektin kontrolleTëPersonalizuara.

Ruani skedarin si custom_check.yaml. Tani mund të ekzekutoni polaris audit me manifestin YAML që kërkon verifikim.

Le ta testojmë manifestin tonë base-valid.yaml:

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

Ekipa polaris audit ka përfunduar vetëm testin e personalizuar të dhënë më sipër dhe ai nuk kishte sukses.

Nëse e korrigjoni imazhin në my-company.com/http-echo:1.0, Polaris do të përfundojë me sukses. Manifesti me ndryshimet tashmë është në repozitorit, kështu që mund të kontrolloni komandën e mëparshme në manifest. image-valid-mycompany.yaml.

Tani lind pyetja: si të ekzekutoni testet e integruara së bashku me ato të personalizuara? Lehtë! Thjesht duhet të shtoni identifikuesit e testeve të integruara në skedarin e konfigurimit. Si rezultat, ai do të marrë pamjen e mëposhtme:

kontrollon:
  cpuRequestsMissing: paralajmërim
  cpuLimitsMissing: paralajmërim
  # Kontrollime të tjera të ndërtuara..
  # ..
  # kontrollimet e personalizuara
  checkImageRepo: rrezik # !!!
kontrollimetPersonalizuara:
  checkImageRepo:        # !!!
    successMessage: Regjistri i imazheve është valid
    failureMessage: Regjistri i imazheve nuk është valid
    category: Imazhe
    target: Kontejner
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(config_with_custom_check.yaml)

Një shembull i plotë i skedarit të konfigurimit është në dispozicion këtu.

Kontrolloni manifestin base-valid.yaml, duke përdorur testet e ndërtuara dhe ato të personalizuara, mund të bëhet me komandën:

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

Polaris e plotëson testet e ndërtuara me ato të personalizuara, duke kombinuar kështu më të mirat nga të dyja botët.

Nga ana tjetër, mosmundësia për të përdorur gjuhë më të fuqishme, si Rego ose JavaScript, mund të bëhet një faktor kufizues që pengon krijimin e testeve më të sofistikuara.

Informacione të mëtejshme mbi Polaris janë në dispozicion në faqja e projektit.

Curriculum Vitae

Megjithëse ekzistojnë shumë mjete për kontrollin dhe vlerësimin e skedarëve YAML të Kubernetes, është e rëndësishme të kesh një kuptim të qartë se si do të projektohen dhe realizohen testet.

Për shembull, nëse merrni manifestet e Kubernetes që kalojnë nëpër pipeline, kubeval mund të jetë hapi i parë në një pipeline të tillë. Ai do të ndjekë nëse përkufizimet e objekteve përputhen me skemën API Kubernetes.

Pasi të përfundojë një kontroll i tillë, mund të kaloni në teste më të avancuara, si përputhshmëria me praktikat më të mira standarde dhe politikat e veçanta. Këtu do të ishin të dobishme kube-score dhe Polaris.

Ata që kanë kërkesa komplekse dhe kanë nevojë për të konfiguruar detajisht testet do të përfitojnë nga copper, config-lint dhe conftest..

Conftest dhe config-lint përdorin YAML për të caktuar testet e personalizuara, ndërsa copper ofron qasje në një gjuhë programimi të plotë, duke e bërë atë një zgjedhje mjaft tërheqëse.

Nga ana tjetër, a është e vlefshme të përdoret një nga këto mjete dhe, për pasojë, të krijoni të gjitha testet manualisht, apo të preferoni Polaris, dhe të shtoni vetëm ato që nevojiten? Nuk ka një përgjigje të qartë për këtë pyetje..

Tabele e mëposhtme përmban një përshkrim të shkurtër të çdo instrumenti:

Instrument
Qëllimi
Disavantazhet
Testet e personalizuara

kubeval
Kontrollon manifestet YAML për përputhshmërinë me një version të caktuar të skemës API.
Nuk e mbështet punën me CRD.
Jo

kube-score
Analizon manifestet YAML për përputhshmërinë me praktikat më të mira.
Nuk mund të zgjidhni versionin tuaj të API Kubernetes për verifikimin e burimeve.
Jo

copper
Kornizë e përgjithshme për krijimin e testeve të vetë-ndërtuara JavaScript për manifestet YAML
Nuk ka teste të integruara. Dokumentacion i varfër
Po

config-lint
Kornizë e përgjithshme për krijimin e testeve në një gjuhë orientuar nga subjektet që është e integruar në YAML. Mbështet formate të ndryshme konfiguracionesh (p.sh., Terraform)
Nuk ka teste të gatshme. Ashtë mundur që asertionet dhe funksionet e integruara të jenë të pamjaftueshme
Po

conftest
Kornizë për krijimin e testeve të veta në Rego (një gjuhë kërkese e specializuar). Lejon ndarjen e politikave përmes paketave OCI
Nuk ka teste të integruara. Duhet të mësoni Rego. Docker Hub nuk mbështetet për publikimin e politikave
Po

Polaris
Analizon manifestet YAML për përputhje me praktikat më të mira standarde. Lejon krijimin e testeve të personalizuara duke përdorur JSON Schema
Aftësitë e testeve të bazuara në JSON Schema mund të mos jenë të mjaftueshme
Po

Duke qenë se këto mjete nuk varen nga qasja në klasterin Kubernetes, ato janë të lehta për t'u instaluar. Ato lejojnë filtrimin e skedarëve burimorë dhe ofrojnë reagim të shpejtë autorëve të kërkesave për ndryshime në projekte.

P.S. nga përkthyesi

Lexoni gjithashtu në blogun tonë:

Burimi: habr.com

Bli një hosting të besueshëm për faqet me mbrojtje DDoS, VPS VDS serverë 🔥 Bli një hosting të besueshëm për faqet me mbrojtje DDoS, VPS VDS serverë | ProHoster