Vërtetoni Kubernetes YAML kundër praktikave dhe politikave më të mira

Shënim. përkth.: Me numrin në rritje të konfigurimeve YAML për mjediset K8s, nevoja për verifikimin e tyre të automatizuar bëhet gjithnjë e më urgjente. Autori i këtij rishikimi jo vetëm përzgjodhi zgjidhjet ekzistuese për këtë detyrë, por gjithashtu përdori Deployment si shembull për të parë se si funksionojnë ato. Doli të ishte shumë informuese për ata që janë të interesuar në këtë temë.

Vërtetoni Kubernetes YAML kundër praktikave dhe politikave më të mira

TL; DR: Ky artikull krahason gjashtë mjete statike për të vërtetuar dhe vlerësuar skedarët Kubernetes YAML kundrejt praktikave dhe kërkesave më të mira.

Ngarkesat e punës Kubernetes zakonisht përcaktohen në formën e dokumenteve YAML. Një nga problemet me YAML është vështirësia e specifikimit të kufizimeve ose marrëdhënieve midis skedarëve të manifestit.

Po sikur të na duhet të sigurohemi që të gjitha imazhet e vendosura në grup vijnë nga një regjistër i besuar?

Si mund të parandaloj dërgimin e vendosjeve që nuk kanë PodDisruptionBudgets në grup?

Integrimi i testimit statik ju lejon të identifikoni gabimet dhe shkeljet e politikave në fazën e zhvillimit. Kjo rrit garancinë që përkufizimet e burimeve janë të sakta dhe të sigurta dhe e bën më të mundshëm që ngarkesat e punës të prodhimit të ndjekin praktikat më të mira.

Ekosistemi i inspektimit të skedarëve statik YAML Kubernetes mund të ndahet në kategoritë e mëposhtme:

  • Vlerësuesit API. Mjetet në këtë kategori kontrollojnë manifestin YAML kundrejt kërkesave të serverit Kubernetes API.
  • Testues të gatshëm. Mjetet nga kjo kategori vijnë me teste të gatshme për sigurinë, përputhshmërinë me praktikat më të mira etj.
  • Vlerësues të personalizuar. Përfaqësuesit e kësaj kategorie ju lejojnë të krijoni teste me porosi në gjuhë të ndryshme, për shembull, Rego dhe Javascript.

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

  1. kubeval;
  2. kube-score;
  3. konfigurim-lint;
  4. bakri;
  5. kontest;
  6. Polaris

Epo, le të fillojmë!

Kontrollimi i vendosjeve

Përpara se të fillojmë të krahasojmë mjetet, le të krijojmë një sfond mbi të cilin do t'i testojmë ato.

Manifesti më poshtë përmban një sërë gabimesh dhe mospërputhje me praktikat më të mira: sa prej tyre mund të gjeni?

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 ta përdorim këtë YAML për të krahasuar mjete të ndryshme.

Manifesti i mësipërm base-valid.yaml dhe manifeste të tjera nga ky artikull mund të gjenden në Depot Git.

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

kubectl apply -f hello-world.yaml

Dhe kështu - kontrolloni punën:

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

Tani shkoni te http://localhost:8080 dhe konfirmoni që aplikacioni po funksionon. Por a ndjek praktikat më të mira? Le të kontrollojmë.

1. Kubeval

Në zemër kubeval Ideja është që çdo ndërveprim me Kubernetes ndodh përmes API-së së tij REST. Me fjalë të tjera, ju mund të përdorni një skemë API për të kontrolluar nëse një YAML e dhënë përputhet me të. Le të shohim një shembull.

udhezime Instalimi kubeval janë në dispozicion në faqen e internetit të projektit.

Në kohën e shkrimit të artikullit origjinal, versioni 0.15.0 ishte i disponueshëm.

Pasi të instalohet, le ta ushqejmë manifestin e mësipërm:

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

Nëse ka sukses, kubeval do të dalë me kodin e daljes 0. Mund ta kontrolloni si më poshtë:

$ echo $?
0

Le të provojmë tani 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 dalloni problemin me sy? Le të nisim:

$ 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

Burimi nuk po verifikohet.

Vendosjet duke përdorur versionin API apps/v1, duhet të përfshijë një përzgjedhës që përputhet me etiketën e pod. Manifesti i mësipërm nuk përfshin përzgjedhësin, kështu që kubeval raportoi një gabim dhe doli me një kod jo zero.

Pyes veten se çfarë do të ndodhë nëse e bëj kubectl apply -f me këtë manifestim?

Epo, le të provojmë:

$ 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

Ky është pikërisht gabimi për të cilin paralajmëroi Kubeval. Mund ta rregulloni duke shtuar një përzgjedhës:

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ërfitimi i mjeteve si kubeval është se gabimet si këto mund të kapen herët në ciklin e vendosjes.

Përveç kësaj, këto kontrolle nuk kërkojnë qasje në grup; ato mund të kryhen jashtë linje.

Si parazgjedhje, kubeval kontrollon burimet kundrejt skemës më të fundit të Kubernetes API. Sidoqoftë, në shumicën e rasteve mund t'ju duhet të kontrolloni kundër një versioni specifik të Kubernetes. Kjo mund të bëhet duke përdorur flamurin --kubernetes-version:

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

Ju lutemi vini re se versioni duhet të specifikohet në format Major.Minor.Patch.

Për një listë të versioneve për të cilat mbështetet verifikimi, ju lutemi referojuni Skema JSON në GitHub, të cilin kubeval e përdor për vërtetim. Nëse keni nevojë të ekzekutoni kubeval jashtë linje, shkarkoni skemat dhe specifikoni vendndodhjen e tyre lokale duke përdorur flamurin --schema-location.

Përveç skedarëve individualë YAML, kubeval mund të punojë edhe me drejtoritë dhe stdin.

Për më tepër, Kubeval integrohet lehtësisht në tubacionin CI. Ata që dëshirojnë të kryejnë teste përpara se të dërgojnë manifeste në grup, do të jenë të kënaqur të dinë se kubeval mbështet tre formate dalëse:

  1. Teksti i thjeshtë;
  2. JSON;
  3. Testoni Protokollin e Çdo gjëje (TAP).

Dhe cilido nga formatet mund të përdoret për analizimin e mëtejshëm të prodhimit për të gjeneruar një përmbledhje të rezultateve të llojit të dëshiruar.

Një nga të metat e kubeval është se aktualisht nuk mund të kontrollojë përputhshmërinë me Përkufizimet e Burimeve të Përshtatshme (CRD). Sidoqoftë, është e mundur të konfiguroni kubeval injorojini ato.

Kubeval është një mjet i shkëlqyeshëm për kontrollimin dhe vlerësimin e burimeve; Megjithatë, duhet theksuar se kalimi i testit nuk garanton që burimi përputhet me praktikat më të mira.

Për shembull, duke përdorur etiketën latest në një enë nuk ndjek praktikat më të mira. Megjithatë, kubeval nuk e konsideron këtë si një gabim dhe nuk e raporton atë. Kjo do të thotë, verifikimi i një YAML të tillë do të përfundojë pa paralajmërime.

Por çfarë nëse doni të vlerësoni YAML dhe të identifikoni shkelje si etiketa latest? Si mund të kontrolloj një skedar YAML kundrejt praktikave më të mira?

2. Kube-rezultati

Kube-rezultati analizon YAML manifestimet dhe i vlerëson ato kundrejt testeve të integruara. Këto teste zgjidhen bazuar në udhëzimet e sigurisë dhe praktikat më të mira, të tilla si:

  • Drejtimi i enës jo si rrënjë.
  • Disponueshmëria e kontrolleve shëndetësore të pod.
  • Vendosja e kërkesave dhe kufijve për burimet.

Bazuar në rezultatet e testit, jepen tre rezultate: OK, KUJDES и KRITIKE.

Mund të provoni Kube-score në internet ose ta instaloni atë në nivel lokal.

Në kohën e shkrimit të artikullit origjinal, versioni i fundit i kube-score ishte 1.7.0.

Le ta provojmë në manifestin tonë 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 kalon testet kubeval, ndërsa kube-score tregon të metat e mëposhtme:

  • Kontrollet e gatishmërisë nuk janë konfiguruar.
  • Nuk ka kërkesa ose kufizime për burimet dhe memorien e CPU-së.
  • Buxhetet e ndërprerjeve të pod nuk janë të specifikuara.
  • Nuk ka rregulla të ndarjes (anti-afiniteti) për të maksimizuar disponueshmërinë.
  • Enë funksionon si rrënjë.

Të gjitha këto janë pika të vlefshme për mangësitë që duhen adresuar për ta bërë vendosjen më efikase dhe të besueshme.

Ekip kube-score shfaq informacion në formë të lexueshme nga njeriu duke përfshirë të gjitha shkeljet e tipit KUJDES и KRITIKE, e cila ndihmon shumë gjatë zhvillimit.

Ata që dëshirojnë të përdorin këtë mjet brenda tubacionit CI mund të mundësojnë dalje më të ngjeshur duke përdorur flamurin --output-format ci (në këtë rast shfaqen edhe testet me rezultatin 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

Ngjashëm me kubeval, kube-score kthen një kod daljeje jo zero kur ka një provë që dështon KRITIKE. Ju gjithashtu mund të aktivizoni përpunim të ngjashëm për KUJDES.

Përveç kësaj, është e mundur të kontrolloni burimet për pajtueshmërinë me versione të ndryshme API (si në kubeval). Sidoqoftë, ky informacion është i koduar në vetë rezultatin kube: nuk mund të zgjidhni një version tjetër të Kubernetes. Ky kufizim mund të jetë një problem i madh nëse keni ndërmend të përmirësoni grupin tuaj ose nëse keni grupe të shumta me versione të ndryshme të K8.

Vini re se tashmë ka një problem me një propozim për të realizuar këtë mundësi.

Më shumë informacion rreth kube-score mund të gjeni në faqen zyrtare të internetit.

Testet e rezultateve Kube janë një mjet i shkëlqyeshëm për zbatimin e praktikave më të mira, por çfarë nëse duhet të bëni ndryshime në test ose të shtoni rregullat tuaja? Mjerisht, kjo nuk mund të bëhet.

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

Nëse keni nevojë të shkruani teste të personalizuara për të verifikuar përputhjen me politikat e kompanisë, mund të përdorni një nga katër mjetet e mëposhtme: config-lint, bakër, conftest ose polaris.

3.Config-lint

Config-lint është një mjet për vërtetimin e skedarëve të konfigurimit YAML, JSON, Terraform, CSV dhe manifesteve Kubernetes.

Mund ta instaloni duke përdorur udhëzimet në faqen e internetit të projektit.

Publikimi aktual që nga koha e shkrimit të artikullit origjinal është 1.5.0.

Config-lint nuk ka teste të integruara për vërtetimin e manifesteve të Kubernetes.

Për të kryer ndonjë test, duhet të krijoni rregulla të përshtatshme. Ato janë të shkruara në skedarët YAML të quajtur "rregullat" (rregullat), dhe kanë strukturën e mëposhtme:

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

(rule.yaml)

Le ta studiojmë më nga afër:

  • Fushë type specifikon se çfarë lloj konfigurimi do të përdorë config-lint. Për manifestimet K8s kjo është gjithmonë Kubernetes.
  • Në terren files Përveç vetë skedarëve, mund të specifikoni një drejtori.
  • Fushë rules të destinuara për vendosjen e testeve të përdoruesit.

Le të themi se dëshironi të siguroheni që imazhet në Deployment shkarkohen gjithmonë nga një depo e besuar si p.sh. my-company.com/myapp:1.0. Një rregull config-lint që kryen një kontroll të tillë do të duket kështu:

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

Çdo rregull duhet të ketë atributet e mëposhtme:

  • id — identifikues unik i rregullit;
  • severity - Ndoshta Dështimi, KUJDES и JO_KOMPLIANT;
  • message - nëse një rregull shkelet, përmbajtja e kësaj rreshti shfaqet;
  • resource — llojin e burimit për të cilin zbatohet ky rregull;
  • assertions — një listë kushtesh që do të vlerësohen në lidhje me këtë burim.

Në rregullin e mësipërm assertion i quajtur every kontrollon që të gjithë kontejnerët janë në vendosje (key: spec.templates.spec.containers) përdorni imazhe të besuara (d.m.th. duke filluar me my-company.com/).

Kompleti i rregullave duket kështu:

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)

Për të provuar testin, le ta ruajmë atë si check_image_repo.yaml. Le të bëjmë një kontroll në skedar 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"
  }
]

Kontrolli dështoi. Tani le të shohim manifestin e mëposhtëm me depon e duhur të imazhit:

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 kryejmë të njëjtin test me manifestin e mësipërm. Nuk u gjetën probleme:

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

Config-lint është një kornizë premtuese që ju lejon të krijoni testet tuaja për të vërtetuar manifestet e Kubernetes YAML duke përdorur YAML DSL.

Por çka nëse keni nevojë për logjikë dhe teste më komplekse? A nuk është YAML shumë i kufizuar për këtë? Po sikur të mund të krijoni teste në një gjuhë të plotë programimi?

4. Bakri

Bakri V2 është një kornizë për vërtetimin e manifesteve duke përdorur teste të personalizuara (të ngjashme me config-lint).

Megjithatë, ai ndryshon nga kjo e fundit në atë që nuk përdor YAML për të përshkruar testet. Në vend të kësaj, testet mund të shkruhen në JavaScript. Bakri siguron një bibliotekë me disa mjete bazë, të cilat ju ndihmojnë të lexoni informacione rreth objekteve të Kubernetes dhe të raportoni gabime.

Hapat për instalimin e bakrit mund të gjenden në dokumentacion zyrtar.

2.0.1 është versioni më i fundit i këtij programi në kohën e shkrimit të artikullit origjinal.

Ashtu si config-lint, Copper nuk ka teste të integruara. Le të shkruajmë një. Le të kontrollojë që vendosjet përdorin imazhe të kontejnerëve ekskluzivisht nga depo të besuara si p.sh my-company.com.

Krijo 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)
            }
        });
    }
});

Tani për të testuar manifestin tonë base-valid.yaml, përdorni komandën 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

Është e qartë se me ndihmën e bakrit mund të kryeni teste më komplekse - për shembull, kontrollimi i emrave të domeneve në manifestimet Ingress ose refuzimi i pods që funksionojnë në modalitetin e privilegjuar.

Bakri ka funksione të ndryshme të dobishme të integruara në të:

  • DockerImage lexon skedarin hyrës të specifikuar dhe krijon një objekt me atributet e mëposhtme:
    • name - emri i imazhit,
    • tag - etiketa e imazhit,
    • registry - regjistri i imazheve,
    • registry_url - protokoll (https://) dhe regjistrin e imazheve,
    • fqin — vendndodhjen e plotë të imazhit.
  • Funksion findByName ndihmon për të gjetur një burim sipas një lloji të caktuar (kind) dhe emri (name) nga skedari hyrës.
  • Funksion findByLabels ndihmon për të gjetur një burim sipas një lloji të caktuar (kind) dhe etiketat (labels).

Mund të shikoni të gjitha funksionet e disponueshme të shërbimit këtu.

Si parazgjedhje, ai ngarkon të gjithë skedarin hyrës YAML në një variabël $$ dhe e bën atë të disponueshëm për skriptim (një teknikë e njohur për ata me përvojë jQuery).

Avantazhi kryesor i Copper është i dukshëm: nuk keni nevojë të zotëroni një gjuhë të specializuar dhe mund të përdorni veçori të ndryshme JavaScript për të krijuar testet tuaja, të tilla si interpolimi i vargjeve, funksionet, etj.

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

Detajet në dispozicion në faqen zyrtare të projektit.

Sidoqoftë, nëse nuk ju pëlqen vërtet JavaScript dhe preferoni një gjuhë të krijuar posaçërisht për krijimin e pyetjeve dhe përshkrimin e politikave, duhet t'i kushtoni vëmendje kontestit.

5.Kontesti

Conftest është një kornizë për testimin e të dhënave të konfigurimit. Gjithashtu i përshtatshëm për testimin/verifikimin e manifestimeve të Kubernetes. Testet përshkruhen duke përdorur një gjuhë të specializuar për pyetje Rego.

Ju mund ta instaloni kontestin duke përdorur udhëzimettë listuara në faqen e internetit të projektit.

Në kohën e shkrimit të artikullit origjinal, versioni më i fundit i disponueshëm ishte 0.18.2.

Ngjashëm me konfigurimin dhe bakrin, kontesti vjen pa asnjë provë të integruar. Le ta provojmë dhe të shkruajmë politikën tonë. Si në shembujt e mëparshëm, ne do të kontrollojmë nëse imazhet e kontejnerit janë marrë nga një burim i besueshëm.

Krijo një drejtori conftest-checks, dhe në të ka 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 në mënyrë të parashikueshme dështoi sepse imazhet erdhën nga një burim i pabesueshëm.

Në skedarin Rego përcaktojmë bllokun deny. E vërteta e saj konsiderohet shkelje. Nëse bllokon deny disa, kontesti i kontrollon ato në mënyrë të pavarur nga njëri-tjetri dhe e vërteta e ndonjërit prej blloqeve trajtohet si shkelje.

Përveç prodhimit të paracaktuar, conftest mbështet formatin JSON, TAP dhe tabelën - një veçori jashtëzakonisht e dobishme nëse keni nevojë të futni raporte në një tubacion ekzistues CI. Ju mund të vendosni formatin e dëshiruar duke përdorur flamurin --output.

Për ta bërë më të lehtë korrigjimin e politikave, kontesti ka një flamur --trace. Ai nxjerr një gjurmë se si conftest analizon skedarët e politikave të specifikuara.

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

komandat push и pull ju lejon të publikoni një objekt ose të merrni një objekt ekzistues nga një regjistër i largët. Le të përpiqemi të publikojmë politikën që krijuam në regjistrin lokal të Docker duke përdorur conftest push.

Filloni regjistrin tuaj lokal Docker:

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

Në një terminal tjetër, shkoni te drejtoria 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 ishte e suksesshme, do të shihni një mesazh si ky:

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

Tani krijoni një drejtori të përkohshme dhe ekzekutoni komandën në të conftest pull. Do të shkarkojë paketën e krijuar nga komanda e mëparshme:

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

Një nëndrejtori do të shfaqet në drejtorinë e përkohshme policyqë përmban skedarin tonë të politikës:

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

Testet mund të ekzekutohen direkt nga depoja:

$ 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

Fatkeqësisht, DockerHub nuk mbështetet ende. Pra, konsiderojeni veten me fat nëse përdorni Regjistri i kontejnerëve Azure (ACR) ose regjistrin tuaj.

Formati i objektit është i njëjtë si Hapni paketat e agjentëve të politikave (OPA), i cili ju lejon të përdorni konftestin për të ekzekutuar teste nga paketat ekzistuese OPA.

Mund të mësoni më shumë rreth ndarjes së politikave dhe veçorive të tjera të kontestit në faqen zyrtare të projektit.

6. ylli Polar

Mjeti i fundit që do të diskutohet në këtë artikull është Ylli Polar. (Njoftimi i tij i vitit të kaluar ne tashmë të përkthyer - përafërsisht. përkthimi)

Polaris mund të instalohet në një grup ose të përdoret në modalitetin e linjës së komandës. Siç mund ta keni marrë me mend, ju lejon të analizoni në mënyrë statike manifestimet e Kubernetes.

Kur ekzekutohet në modalitetin e linjës së komandës, testet e integruara janë të disponueshme që mbulojnë fusha të tilla si siguria dhe praktikat më të mira (të ngjashme me kube-score). Përveç kësaj, ju mund të krijoni testet tuaja (si në config-lint, bapper dhe confest).

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

Për të instaluar Polaris në modalitetin e linjës së komandës, përdorni udhëzimet në faqen e projektit.

Në kohën e shkrimit të artikullit origjinal, versioni 1.0.3 është i disponueshëm.

Pasi të përfundojë instalimi, mund të ekzekutoni polaris në manifest base-valid.yaml me komandën e mëposhtme:

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

Ai do të nxjerrë një varg në format JSON me një përshkrim të detajuar të testeve të kryera dhe rezultateve të tyre. Prodhimi do të ketë strukturën e mëposhtme:

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

Prodhimi i plotë i disponueshëm këtu.

Ashtu si kube-score, Polaris identifikon çështje në zonat ku manifesti nuk plotëson praktikat më të mira:

  • Nuk ka kontrolle shëndetësore për bishtajat.
  • Etiketat për imazhet e kontejnerëve nuk janë specifikuar.
  • Enë funksionon si rrënjë.
  • Kërkesat dhe kufijtë për memorie dhe CPU nuk janë të specifikuara.

Çdo testi, në varësi të rezultateve të tij, i caktohet një shkallë kritike: Paralajmërimi ose rrezik. Për të mësuar më shumë rreth testeve të integruara të disponueshme, ju lutemi referojuni dokumentacionin.

Nëse detajet nuk nevojiten, mund të specifikoni flamurin --format score. Në këtë rast, Polaris do të nxjerrë një numër që varion nga 1 në 100 - rezultat (d.m.th. vlerësimi):

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

Sa më afër rezultatit të jetë 100, aq më e lartë është shkalla e pajtimit. Nëse kontrolloni kodin e daljes së komandës polaris audit, rezulton se është e barabartë me 0.

Forca polaris audit Ju mund ta përfundoni punën me kod jo zero duke përdorur dy flamuj:

  • flamur --set-exit-code-below-score merr si argument një vlerë pragu në intervalin 1-100. Në këtë rast, komanda do të dalë me kodin e daljes 4 nëse rezultati është nën pragun. Kjo është shumë e dobishme kur keni një vlerë të caktuar pragu (të themi 75) dhe duhet të merrni një alarm nëse rezultati shkon më poshtë.
  • flamur --set-exit-code-on-danger do të bëjë që komanda të dështojë me kodin 3 nëse një nga testet e rrezikut dështon.

Tani le të përpiqemi të krijojmë një test të personalizuar që kontrollon nëse imazhi është marrë nga një depo e besuar. Testet e personalizuara janë specifikuar në formatin YAML dhe vetë testi përshkruhet duke përdorur skemën JSON.

Pjesa e mëposhtme e kodit YAML përshkruan një test të ri të quajtur 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/.+$

Le ta shohim më nga afër:

  • successMessage — ky rresht do të printohet nëse testi përfundon me sukses;
  • failureMessage — ky mesazh do të shfaqet në rast dështimi;
  • category — tregon një nga kategoritë: Images, Health Checks, Security, Networking и Resources;
  • target--- përcakton llojin e objektit (spec) aplikohet testi. Vlerat e mundshme: Container, Pod ose Controller;
  • Vetë testi është specifikuar në objekt schema duke përdorur skemën JSON. Fjala kyçe në këtë test është pattern përdoret për të krahasuar burimin e imazhit me atë të kërkuar.

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

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)

Le të analizojmë skedarin:

  • Në terren checks testet dhe niveli i tyre i kritikitetit janë të përshkruara. Meqenëse është e dëshirueshme të merrni një paralajmërim kur një imazh merret nga një burim i pabesueshëm, ne vendosim nivelin këtu danger.
  • Vetë testi checkImageRepo më pas regjistrohet në objekt customChecks.

Ruaje skedarin si custom_check.yaml. Tani mund të vraposh polaris audit me një manifest YAML që kërkon verifikim.

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

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

Ekip polaris audit ekzekutoi vetëm testin e përdoruesit të specifikuar më sipër dhe ai dështoi.

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

Tani lind pyetja: si të ekzekutohen testet e integruara së bashku me ato me porosi? Lehtë! Thjesht duhet të shtoni identifikuesit e integruar të testit në skedarin e konfigurimit. Si rezultat, ajo do të marrë formën e mëposhtme:

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)

Ekziston një shembull i një skedari të plotë konfigurimi këtu.

Kontrollo manifestin base-valid.yamlduke përdorur teste të integruara dhe të personalizuara, mund të përdorni komandën:

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

Polaris plotëson testet e integruara me ato të personalizuara, duke kombinuar kështu më të mirën e të dy botëve.

Nga ana tjetër, pamundësia për të përdorur gjuhë më të fuqishme si Rego ose JavaScript mund të jetë një faktor kufizues që parandalon krijimin e testeve më të sofistikuara.

Më shumë informacion rreth Polaris është në dispozicion në uebsajti i projektit.

Përmbledhje

Ndërsa ka shumë mjete në dispozicion për të inspektuar dhe vlerësuar skedarët Kubernetes YAML, është e rëndësishme të kemi një kuptim të qartë se si do të hartohen dhe ekzekutohen testet.

Për shembull, nëse merrni manifestimet e Kubernetes duke kaluar nëpër një tubacion, kubeval mund të jetë hapi i parë në një tubacion të tillë. Ai do të monitoronte nëse përkufizimet e objekteve përputhen me skemën e Kubernetes API.

Pasi të përfundojë një rishikim i tillë, mund të kalohet në teste më të sofistikuara, të tilla si pajtueshmëria me praktikat më të mira standarde dhe politikat specifike. Kjo është ajo ku kube-score dhe Polaris do të ishin të dobishëm.

Për ata që kanë kërkesa komplekse dhe duhet të personalizojnë testet në detaje, bakri, konfigurimi dhe kontesti do të ishin të përshtatshëm..

Conftest dhe config-lint përdorin YAML për të përcaktuar testet e personalizuara, dhe bakri ju jep akses në një gjuhë të plotë programimi, duke e bërë atë një zgjedhje mjaft tërheqëse.

Nga ana tjetër, a ia vlen të përdorni një nga këto mjete dhe, për rrjedhojë, të krijoni të gjitha testet me dorë, apo të preferoni Polaris dhe t'i shtoni vetëm atë që nevojitet? Nuk ka përgjigje të qartë për këtë pyetje.

Tabela më poshtë ofron një përshkrim të shkurtër të secilit mjet:

Mjet
fat
Kufizimet
Testet e përdoruesit

kubeval
Vërteton manifestimet YAML kundrejt një versioni specifik të skemës API
Nuk mund të punojë me CRD
Jo

kube-rezultat
Analizon manifestimet e YAML kundrejt praktikave më të mira
Nuk mund të zgjidhet versioni i Kubernetes API për të kontrolluar burimet
Jo

bakër
Një kornizë e përgjithshme për krijimin e testeve të personalizuara JavaScript për manifestet YAML
Nuk ka teste të integruara. Dokumentacion i dobët
Po

konfigurim-lint
Një kornizë e përgjithshme për krijimin e testeve në një gjuhë specifike për domenin e ngulitur në YAML. Mbështet formate të ndryshme konfigurimi (p.sh. Terraform)
Nuk ka teste të gatshme. Pohimet dhe funksionet e integruara mund të mos jenë të mjaftueshme
Po

kontestim
Një kornizë për krijimin e testeve tuaja duke përdorur Rego (një gjuhë e specializuar për pyetje). Lejon ndarjen e politikave nëpërmjet paketave OCI
Nuk ka teste të integruara. Më duhet të mësoj Rego. Docker Hub nuk mbështetet kur publikohen politikat
Po

Ylli Polar
Shqyrtimet YAML manifestohet kundrejt praktikave më të mira standarde. Ju lejon të krijoni testet tuaja duke përdorur skemën JSON
Aftësitë e testimit të bazuara në skemën JSON mund të mos jenë të mjaftueshme
Po

Për shkak se këto mjete nuk mbështeten në aksesin në grupin Kubernetes, ato janë të lehta për t'u instaluar. Ato ju lejojnë të filtroni skedarët burimor dhe të ofroni reagime të shpejta për autorët e kërkesave për tërheqje në projekte.

PS nga përkthyesi

Lexoni edhe në blogun tonë:

Burimi: www.habr.com

Shto një koment