Konfirmu Kubernetes YAML kontraŭ plej bonaj praktikoj kaj politikoj

Notu. transl.: Kun la kreskanta nombro da YAML-agordoj por K8s-medioj, la bezono de ilia aŭtomata kontrolado fariĝas pli kaj pli urĝa. La aŭtoro de ĉi tiu revizio ne nur elektis ekzistantajn solvojn por ĉi tiu tasko, sed ankaŭ uzis Deplojon kiel ekzemplon por vidi kiel ili funkcias. Ĝi montriĝis tre informa por tiuj, kiuj interesiĝas pri ĉi tiu temo.

Konfirmu Kubernetes YAML kontraŭ plej bonaj praktikoj kaj politikoj

TL; DR: Ĉi tiu artikolo komparas ses senmovajn ilojn por validigi kaj taksi Kubernetes YAML-dosierojn kontraŭ plej bonaj praktikoj kaj postuloj.

Kubernetes laborkvantoj estas tipe difinitaj en la formo de YAML-dokumentoj. Unu el la problemoj kun YAML estas la malfacileco precizigi limojn aŭ rilatojn inter manifestdosieroj.

Kio se ni devas certigi, ke ĉiuj bildoj deplojitaj al la areto venas de fidinda registro?

Kiel mi povas malhelpi Deplojojn kiuj ne havas PodDisruptionBudgets esti senditaj al la areto?

Integriĝo de senmova testado permesas identigi erarojn kaj politikajn malobservojn en la disvolva stadio. Ĉi tio pliigas la garantion, ke difinoj de rimedoj estas ĝustaj kaj sekuraj, kaj pliverŝajnigas, ke produktaj laborkvantoj sekvos plej bonajn praktikojn.

La Kubernetes-senmova YAML-dosiera inspekta ekosistemo povas esti dividita en la jenajn kategoriojn:

  • API validigiloj. Iloj en ĉi tiu kategorio kontrolas la manifeston YAML kontraŭ la postuloj de la Kubernetes API-servilo.
  • Готовые тестеры. Iloj de ĉi tiu kategorio venas kun pretaj testoj pri sekureco, konformeco al plej bonaj praktikoj ktp.
  • Propraj validigiloj. Reprezentantoj de ĉi tiu kategorio permesas krei kutimajn testojn en diversaj lingvoj, ekzemple, Rego kaj Javascript.

En ĉi tiu artikolo ni priskribos kaj komparos ses malsamajn ilojn:

  1. kubeval;
  2. kube-score;
  3. konfig-lint;
  4. kupro;
  5. konkurso;
  6. polaris.

Nu, ni komencu!

Kontrolante Deplojojn

Antaŭ ol ni komencu kompari ilojn, ni kreu fonon por testi ilin.

La suba manifesto enhavas kelkajn erarojn kaj nerespekton de plej bonaj praktikoj: kiom da ili vi povas trovi?

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)

Ni uzos ĉi tiun YAML por kompari malsamajn ilojn.

La supra manifesto base-valid.yaml kaj aliaj manifestoj de ĉi tiu artikolo troveblas en Git-deponejoj.

La manifesto priskribas retejon, kies ĉefa tasko estas respondi per mesaĝo "Saluton Mondo" al la haveno 5678. Ĝi povas esti deplojita per la sekva komando:

kubectl apply -f hello-world.yaml

Kaj do - kontrolu la laboron:

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

Nun iru al http://localhost:8080 kaj konfirmu, ke la aplikaĵo funkcias. Sed ĉu ĝi sekvas plej bonajn praktikojn? Ni kontrolu.

1. Kubeval

Ĉe la bazo kubeval La ideo estas, ke ajna interago kun Kubernetes okazas per ĝia REST API. Alivorte, vi povas uzi API-skemon por kontroli ĉu donita YAML konformas al ĝi. Ni rigardu ekzemplon.

Instalaj instrukcioj kubeval estas disponeblaj en la retejo de la projekto.

En la momento de verkado de la originala artikolo, versio 0.15.0 estis havebla.

Post instalite, ni nutru al ĝi la manifeston supre:

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

Se sukcesa, kubeval eliros kun elirkodo 0. Vi povas kontroli ĝin jene:

$ echo $?
0

Ni nun provu kubeval kun malsama manifesto:

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)

Ĉu vi povas ekvidi la problemon okule? Ni lanĉu:

$ 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

La rimedo ne estas kontrolita.

Deplojoj uzante la API-version apps/v1, devas inkluzivi elektilon kiu kongruas kun la etikedo de la pod. La ĉi-supra manifesto ne inkluzivas elektilon, do kubeval raportis eraron kaj eliris kun ne-nula kodo.

Mi scivolas, kio okazos se mi faros kubectl apply -f kun ĉi tiu manifesto?

Nu, ni provu:

$ 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

Ĝuste ĉi tio estas la eraro pri kiu avertis kubeval. Vi povas ripari ĝin aldonante elektilon:

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)

La avantaĝo de iloj kiel kubeval estas, ke eraroj kiel ĉi tiuj povas esti kaptitaj frue en la deploja ciklo.

Krome, ĉi tiuj kontroloj ne postulas aliron al la areto; ili povas esti faritaj eksterrete.

Defaŭlte, kubeval kontrolas rimedojn kontraŭ la plej nova skemo de Kubernetes API. Tamen, plejofte vi eble bezonos kontroli specifan eldonon de Kubernetes. Ĉi tio povas esti farita uzante la flagon --kubernetes-version:

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

Обратите внимание, что версия должна указываться в формате Major.Minor.Patch.

Por listo de versioj por kiuj konfirmo estas subtenata, bonvolu raporti al JSON-skemo en GitHub, kiun kubeval uzas por validumado. Se vi bezonas ruli kubeval eksterrete, elŝutu la skemojn kaj specifu ilian lokan lokon per la flago --schema-location.

Krom individuaj YAML-dosieroj, kubeval ankaŭ povas funkcii kun dosierujoj kaj stdin.

Krome, Kubeval facile integriĝas en la CI-dukto. Tiuj, kiuj volas fari testojn antaŭ sendi manifestojn al la areto, ĝojos scii, ke kubeval subtenas tri eligformatojn:

  1. Klara teksto;
  2. JSON;
  3. Proto Io ajn Protokolo (TAP).

Kaj iu ajn el la formatoj povas esti uzata por plia analizado de la eligo por generi resumon de la rezultoj de la dezirata tipo.

Unu el la malavantaĝoj de kubeval estas, ke ĝi nuntempe ne povas kontroli la plenumon de Propraj Rimedaj Difinoj (CRD). Tamen eblas agordi kubeval ignoru ilin.

Kubeval estas bonega ilo por kontroli kaj taksi rimedojn; Tamen, oni devas emfazi, ke trapasi la teston ne garantias, ke la rimedo konformas al plej bonaj praktikoj.

Ekzemple, uzante la etikedon latest en ujo ne sekvas plej bonajn praktikojn. Tamen, kubeval ne konsideras tion eraro kaj ne raportas ĝin. Tio estas, la konfirmo de tia YAML finiĝos sen avertoj.

Sed kio se vi volas taksi YAML kaj identigi malobservojn kiel la etikedo latest? Kiel mi kontrolas YAML-dosieron kontraŭ plej bonaj praktikoj?

2. Kube-poentaro

Kube-poentaro analizas YAML-manifestojn kaj taksas ilin kontraŭ enkonstruitaj testoj. Ĉi tiuj provoj estas elektitaj surbaze de sekurecaj gvidlinioj kaj plej bonaj praktikoj, kiel ekzemple:

  • Запуск контейнера не под root’ом.
  • Havebleco de podaj sankontroloj.
  • Fiksi petojn kaj limojn por rimedoj.

Surbaze de la testrezultoj, tri rezultoj estas donitaj: OK, AVERTO и KRITIKAJ.

Vi povas provi Kube-score interrete aŭ instali ĝin loke.

En la momento de verkado de la originala artikolo, la plej nova versio de kube-score estis 1.7.0.

Ni provu ĝin sur nia manifesto 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 pasas kubeval-testojn, dum kube-poentaro montras al la sekvaj difektoj:

  • Pretecaj kontroloj ne estas agorditaj.
  • Ne estas petoj aŭ limoj por CPU-resursoj kaj memoro.
  • Buĝetoj pri interrompo de podoj ne estas specifitaj.
  • Ne ekzistas reguloj de apartigo (kontraŭ-afineco) por maksimumigi haveblecon.
  • La ujo funkcias kiel radiko.

Ĉi tiuj estas ĉiuj validaj punktoj pri mankoj, kiujn oni devas trakti por fari Deplojon pli efika kaj fidinda.

teamo kube-score montras informojn en homlegebla formo inkluzive de ĉiuj tipaj malobservoj AVERTO и KRITIKAJ, kiu multe helpas dum evoluo.

Tiuj, kiuj deziras uzi ĉi tiun ilon ene de la CI-dukto, povas ebligi pli kunpremitan eliron uzante la flagon --output-format ci (en ĉi tiu kazo, testoj kun la rezulto ankaŭ estas montrataj 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

Simile al kubeval, kube-score resendas ne-nulan elirkodon kiam estas testo kiu malsukcesas KRITIKAJ. Также можно включить подобную обработку и для AVERTO.

Krome, eblas kontroli rimedojn por konformeco al malsamaj API-versioj (kiel en kubeval). Tamen, ĉi tiu informo estas malmola kodita en la kube-poentaro mem: vi ne povas elekti malsaman version de Kubernetes. Ĉi tiu limigo povas esti granda problemo se vi intencas ĝisdatigi vian areton aŭ se vi havas plurajn aretojn kun malsamaj versioj de K8s.

notu tion jam estas problemo kun propono realigi ĉi tiun ŝancon.

Pliaj informoj pri kube-score troveblas ĉe oficiala retejo.

Kube-poentaraj testoj estas bonega ilo por efektivigi plej bonajn praktikojn, sed kio se vi bezonas fari ŝanĝojn al la testo aŭ aldoni viajn proprajn regulojn? Ve, ĉi tio ne povas esti farita.

Kube-score ne estas etendebla: vi ne povas aldoni politikojn al ĝi aŭ alĝustigi ilin.

Se vi bezonas verki kutimajn testojn por kontroli konformecon al kompaniaj politikoj, vi povas uzi unu el la sekvaj kvar iloj: konfig-lint, kupro, kontesto aŭ polaris.

3.Config-lint

Config-lint estas ilo por validigi YAML, JSON, Terraform, CSV-agordajn dosierojn kaj manifestojn de Kubernetes.

Vi povas instali ĝin uzante instrukcioj en la retejo de la projekto.

Текущий релиз по состоянию на момент написания оригинальной статьи — 1.5.0.

Config-lint ne havas enkonstruitajn testojn por validigi manifestojn de Kubernetes.

Por fari iujn ajn provojn, vi devas krei taŭgajn regulojn. Ili estas skribitaj en YAML-dosieroj nomataj "reguloj" (reguloj), kaj havas la sekvan strukturon:

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

(rule.yaml)

Ni studu ĝin pli detale:

  • kampo type specifas kian agordon konfig-lint uzos. Por K8s manifestoj ĉi tio estas ĉiam Kubernetes.
  • En kampo files Krom la dosieroj mem, vi povas specifi dosierujon.
  • kampo rules destinita por starigi uzantajn testojn.

Ni diru, ke vi volas certigi, ke bildoj en Deployment ĉiam estas elŝutitaj el fidinda deponejo kiel my-company.com/myapp:1.0. Regulo config-lint kiu plenumas tian kontrolon aspektus jene:

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

Ĉiu regulo devas havi la sekvajn atributojn:

  • id — unika identigilo de la regulo;
  • severity - Eble FALSO, AVERTO и NE_KOMPLIANTA;
  • message — se regulo estas malobservita, la enhavo de ĉi tiu linio estas montrata;
  • resource — la speco de rimedo al kiu ĉi tiu regulo aplikas;
  • assertions — listo de kondiĉoj, kiuj estos taksataj rilate al ĉi tiu rimedo.

En la supra regulo assertion sub la nomo every kontrolas ke ĉiuj ujoj estas en Deplojo (key: spec.templates.spec.containers) uzu fidindajn bildojn (t.e. komencante per my-company.com/).

Полный ruleset выглядит следующим образом:

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)

Por provi la teston, ni konservu ĝin kiel check_image_repo.yaml. Ni kontrolu la dosieron 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"
  }
]

La kontrolo malsukcesis. Nun ni kontrolu la sekvan manifeston kun la ĝusta bilddeponejo:

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)

Ni faras la saman teston kun la ĉi-supra manifesto. Neniuj problemoj trovitaj:

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

Config-lint estas promesplena kadro, kiu ebligas al vi krei viajn proprajn testojn por validigi manifestojn de Kubernetes YAML per la YAML DSL.

Sed kio se vi bezonas pli kompleksan logikon kaj provojn? Ĉu YAML ne estas tro limigita por ĉi tio? Kio se vi povus krei testojn en plena programlingvo?

4. Kupro

Kupro V2 estas kadro por validigi manifestojn per kutimaj testoj (similaj al konfig-lint).

Однако от последнего он отличается тем, что не использует YAML для описания тестов. Testoj povas esti skribitaj en JavaScript anstataŭe. Kupro provizas bibliotekon per pluraj bazaj iloj, kiuj helpas vin legi informojn pri Kubernetes-objektoj kaj raporti erarojn.

La paŝoj por instali Kupro troviĝas en oficiala dokumentaro.

2.0.1 estas la plej nova eldono de ĉi tiu utileco en la momento de verkado de la originala artikolo.

Kiel konfig-lint, Kupro ne havas enkonstruitajn testojn. Ni skribu unu. Lasu ĝin kontroli, ke deplojoj uzas ujajn bildojn ekskluzive de fidindaj deponejoj kiel my-company.com.

Kreu dosieron check_image_repo.js kun la jena enhavo:

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

Nun provi nian manifeston base-valid.yaml, uzu la komandon 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

Estas klare, ke kun la helpo de kupro vi povas fari pli kompleksajn testojn - ekzemple, kontroli domajnajn nomojn en Ingress-manifestoj aŭ malakcepti podojn kurantajn en privilegia reĝimo.

Kupro havas diversajn utilajn funkciojn enkonstruitajn en ĝi:

  • DockerImage legas la specifitan enigdosieron kaj kreas objekton kun la sekvaj atributoj:
    • name - nomo de la bildo,
    • tag - bilda etikedo,
    • registry - bilda registro,
    • registry_url - protokolo (https://) kaj bildregistro,
    • fqin — plena loko de la bildo.
  • funkcio findByName helpas trovi rimedon laŭ difinita tipo (kind) kaj nomo (name) el la eniga dosiero.
  • funkcio findByLabels helpas trovi rimedon per specifa tipo (kind) kaj etikedoj (labels).

Vi povas vidi ĉiujn disponeblajn servofunkciojn tie.

Defaŭlte ĝi ŝarĝas la tutan enigon YAML-dosieron en variablon $$ kaj disponigas ĝin por skripto (konata tekniko por tiuj kun jQuery-sperto).

La ĉefa avantaĝo de Kupro estas evidenta: vi ne bezonas regi specialan lingvon kaj vi povas uzi diversajn JavaScript-funkciojn por krei viajn proprajn testojn, kiel interpoladon de ŝnuroj, funkciojn ktp.

Oni devas ankaŭ rimarki, ke la nuna versio de Kupro funkcias kun la ES5-versio de la JavaScript-motoro, ne ES6.

Detaloj haveblaj ĉe oficiala retejo de la projekto.

Tamen, se vi ne vere ŝatas JavaScript kaj preferas lingvon specife desegnitan por krei demandojn kaj priskribi politikojn, vi devus atenti pri konkurso.

5.Kontesto

Conftest estas kadro por testi agordajn datumojn. Ankaŭ taŭgas por testi/kontroli manifestojn de Kubernetes. Testoj estas priskribitaj uzante specialan demandlingvon Rego.

Vi povas instali konkurson uzante instrukciojlistigita en la retejo de la projekto.

En la momento de verkado de la originala artikolo, la plej nova disponebla versio estis 0.18.2.

Simile al konfig-lint kaj kupro, konkurso venas sen enkonstruitaj testoj. Ni provu ĝin kaj skribu nian propran politikon. Kiel en antaŭaj ekzemploj, ni kontrolos ĉu la ujbildoj estas prenitaj de fidinda fonto.

Kreu dosierujon conftest-checks, kaj en ĝi estas dosiero nomita check_image_registry.rego kun la jena enhavo:

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

Nun ni provu base-valid.yaml tra 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

La testo antaŭvideble malsukcesis ĉar la bildoj venis de nefidinda fonto.

En la Rego-dosiero ni difinas la blokon deny. Ĝia vero estas konsiderata kiel malobservo. Se blokoj deny несколько, conftest проверяет их независимо друг от друга, и истинность любого из блоков трактуется как нарушение.

Krom la defaŭlta eligo, konkurso subtenas JSON, TAP kaj tabelformaton - ege utila funkcio se vi bezonas enigi raportojn en ekzistanta CI-dukto. Vi povas agordi la deziratan formaton uzante la flagon --output.

Por faciligi sencimigi politikojn, konkurso havas flagon --trace. Ĝi eligas spuron de kiel conftest analizas la specifitajn politikajn dosierojn.

Konkursaj politikoj povas esti publikigitaj kaj dividitaj en registroj de OCI (Open Container Initiative) kiel artefaktoj.

Teamoj push и pull permesas vin publikigi artefakton aŭ preni ekzistantan artefakton el fora registro. Ni provu publikigi la politikon, kiun ni kreis al la loka Docker-registro uzante conftest push.

Komencu vian lokan Docker-registron:

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

En alia terminalo, iru al la dosierujo, kiun vi kreis pli frue conftest-checks kaj rulu la sekvan komandon:

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

Se la komando sukcesis, vi vidos mesaĝon kiel ĉi tio:

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

Nun kreu provizoran dosierujon kaj rulu la komandon en ĝi conftest pull. Ĝi elŝutos la pakaĵon kreitan per la antaŭa komando:

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

Subdosierujo aperos en la provizora dosierujo policyenhavanta nian politikan dosieron:

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

Testoj povas esti rulitaj rekte de la deponejo:

$ 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

Bedaŭrinde, DockerHub ankoraŭ ne estas subtenata. Do konsideru vin bonŝanca se vi uzas Azure Container Registry (ACR) aŭ via propra registro.

Artefakta formato estas la sama kiel Malfermu Policy Agent-pakaĵojn (OPA), kiu permesas vin uzi konkurson por fari testojn de ekzistantaj OPA-pakaĵoj.

Vi povas lerni pli pri politika kundivido kaj aliaj funkcioj de konkurso ĉe oficiala retejo de la projekto.

6. Polaris

La lasta ilo, kiu estos diskutita en ĉi tiu artikolo, estas Polaris. (Lia lastjara anonco ni jam tradukita - ĉ. traduko)

Polaris povas esti instalita en areto aŭ uzata en komandlinia reĝimo. Kiel vi eble divenis, ĝi permesas vin statike analizi Kubernetes manifestojn.

Dum funkciado en komandlinia reĝimo, enkonstruitaj testoj disponeblas kovrante areojn kiel sekureco kaj plej bonaj praktikoj (similaj al kube-score). Krome, vi povas krei viajn proprajn testojn (kiel en config-lint, kupro kaj conftest).

Alivorte, Polaris kombinas la avantaĝojn de ambaŭ kategorioj de iloj: kun enkonstruitaj kaj kutimaj testoj.

Por instali Polaris en komandlinia reĝimo, uzu instrukcioj en la retejo de la projekto.

En la momento de verkado de la originala artikolo, versio 1.0.3 estas disponebla.

После завершения установки можно запустить polaris на манифесте base-valid.yaml kun la sekva komando:

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

Ĝi eligos ĉenon en formato JSON kun detala priskribo de la testoj faritaj kaj iliaj rezultoj. La eligo havos la sekvan strukturon:

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

Plena eligo havebla tie.

Kiel kube-poentaro, Polaris identigas problemojn en lokoj kie la manifesto ne renkontas plej bonajn praktikojn:

  • Ne estas sankontroloj por guŝoj.
  • Etikedoj por ujbildoj ne estas specifitaj.
  • La ujo funkcias kiel radiko.
  • Petoj kaj limoj por memoro kaj CPU ne estas specifitaj.

Ĉiu testo, depende de siaj rezultoj, ricevas gradon da kritiko: avertodanĝero. Por lerni pli pri la disponeblaj enkonstruitaj testoj, bonvolu raporti al dokumentado.

Se detaloj ne estas bezonataj, vi povas specifi la flagon --format score. En ĉi tiu kazo, Polaris eligos nombron de 1 ĝis 100 − partituro (t.e. takso):

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

Ju pli proksimas la poentaro al 100, des pli alta la grado de interkonsento. Se vi kontrolas la elirkodon de la komando polaris audit, montriĝas ke ĝi estas egala al 0.

Заставить polaris audit Vi povas ĉesigi laboron kun ne-nula kodo uzante du flagojn:

  • Flago --set-exit-code-below-score prenas kiel argumenton sojlan valoron en la intervalo 1-100. En ĉi tiu kazo, la komando eliros kun elirkodo 4 se la poentaro estas sub la sojlo. Ĉi tio estas tre utila kiam vi havas certan sojlan valoron (diru 75) kaj vi devas ricevi atentigon se la poentaro iras malsupre.
  • Flago --set-exit-code-on-danger kaŭzos la komandon malsukcesi kun kodo 3 se unu el la danĝertestoj malsukcesos.

Nun ni provu krei kutiman teston, kiu kontrolas ĉu la bildo estas prenita el fidinda deponejo. Propraj testoj estas specifitaj en YAML-formato, kaj la testo mem estas priskribita uzante JSON-Skemon.

La sekva YAML-kodfragmento priskribas novan provon nomitan 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/.+$

Ni rigardu ĝin pli detale:

  • successMessage — ĉi tiu linio estos presita se la testo finiĝos sukcese;
  • failureMessage — ĉi tiu mesaĝo estos montrita en kazo de malsukceso;
  • category — indikas unu el la kategorioj: Images, Health Checks, Security, Networking и Resources;
  • target--- determinas kian tipon de objekto (spec) testo estas aplikata. Eblaj valoroj: Container, PodController;
  • La testo mem estas specifita en la objekto schema uzante JSON-skemon. La ŝlosilvorto en ĉi tiu testo estas pattern используется для сравнения источника образа с требуемым.

Por fari ĉi-supran teston, vi devas krei la sekvan Polaris-agordon:

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)

Ni analizu la dosieron:

  • En kampo checks testoj kaj ilia nivelo de kritiko estas preskribitaj. Ĉar estas dezirinde ricevi averton kiam bildo estas prenita de nefidinda fonto, ni starigas la nivelon ĉi tie danger.
  • La provo mem checkImageRepo tiam registrita en la objekto customChecks.

Konservu la dosieron kiel custom_check.yaml. Nun vi povas kuri polaris audit kun YAML manifesto kiu postulas konfirmon.

Ni provu nian manifeston base-valid.yaml:

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

teamo polaris audit kuris nur la uzantan teston specifitan supre kaj ĝi malsukcesis.

Se vi fiksas la bildon al my-company.com/http-echo:1.0, Polaris kompletigos sukcese. La manifesto kun la ŝanĝoj jam estas en deponejojdo vi povas kontroli la antaŭan komandon sur la manifesto image-valid-mycompany.yaml.

Теперь возникает вопрос: как запускать встроенные тесты совместно с пользовательскими? Легко! Просто надо добавить идентификаторы встроенных тестов в файл конфигурации. В результате он приобретет следующий вид:

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)

Ekzemplo de kompleta agorda dosiero estas disponebla tie.

Kontrolu manifeston base-valid.yamluzante enkonstruitajn kaj kutimajn testojn, vi povas uzi la komandon:

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

Polaris kompletigas la enkonstruitajn testojn per kutimaj, tiel kombinante la plej bonan el ambaŭ mondoj.

Aliflanke, la malkapablo uzi pli potencajn lingvojn kiel Rego aŭ JavaScript povas esti limiga faktoro malhelpante la kreadon de pli kompleksaj testoj.

Pliaj informoj pri Polaris haveblas ĉe retejo de la projekto.

Resumo

Kvankam ekzistas multaj iloj disponeblaj por inspekti kaj taksi Kubernetes YAML-dosierojn, gravas havi klaran komprenon pri kiel la testoj estos dezajnitaj kaj efektivigitaj.

Ekzemple, se vi prenas manifestojn de Kubernetes tra dukto, kubeval povus esti la unua paŝo en tia dukto.. Ĝi monitorus ĉu objektodifinoj konformas al la Kubernetes API-skemo.

После завершения подобной проверки можно было бы перейти к более изощренным тестам, таким как соответствие стандартным лучшим практикам и особым политикам. И здесь бы пригодились kube-score и Polaris.

Por tiuj, kiuj havas kompleksajn postulojn kaj bezonas personecigi testojn detale, kupro, konfig-lint kaj konkurso taŭgus.

Conftest kaj konfig-lint uzas YAML por difini kutimajn testojn, kaj kupro donas al vi aliron al plena programlingvo, igante ĝin sufiĉe alloga elekto.

Aliflanke, ĉu indas uzi unu el ĉi tiuj iloj kaj, do, krei ĉiujn testojn permane, aŭ preferi Polaris kaj aldoni nur tion, kion necesas al ĝi? Ne estas klara respondo al ĉi tiu demando.

La suba tabelo provizas mallongan priskribon de ĉiu ilo:

Ilo
Intenco
mankoj
Testoj de uzantoj

kubeval
Valifikas YAML-manifestojn kontraŭ specifa versio de la API-skemo
Ne povas labori kun CRD
Neniu

kube-score
Analizas YAML-manifestojn kontraŭ plej bonaj praktikoj
Ne povas elekti vian Kubernetes API-version por kontroli rimedojn
Neniu

kupro
Ĝenerala kadro por krei kutimajn JavaScript-testojn por YAML-manifestoj
Neniuj enkonstruitaj testoj. Malbona dokumentado
Jes

konfig-lint
Ĝenerala kadro por krei testojn en domajna specifa lingvo enigita en YAML. Subtenas diversajn agordajn formatojn (ekz. Terraform)
Ne estas pretaj provoj. Enkonstruitaj asertoj kaj funkcioj eble ne sufiĉas
Jes

konkurso
Kadro por krei viajn proprajn testojn per Rego (speciala konsultlingvo). Permesas kundividon de politikoj per OCI-pakaĵoj
Neniuj enkonstruitaj testoj. Mi devas lerni Regon. Docker Hub ne estas subtenata dum publikigado de politikoj
Jes

Polaris
Recenzoj YAML-manifestoj kontraŭ normaj plej bonaj praktikoj. Permesas al vi krei viajn proprajn testojn per JSON-Skemo
Testkapabloj bazitaj sur JSON-Skemo eble ne sufiĉas
Jes

Ĉar ĉi tiuj iloj ne dependas de aliro al la Kubernetes-grupo, ili estas facile instaleblaj. Ili permesas vin filtri fontdosierojn kaj provizi rapidajn sugestojn al la aŭtoroj de tirpetoj en projektoj.

PS de tradukisto

Legu ankaŭ en nia blogo:

fonto: www.habr.com

Aldoni komenton