Ověřte Kubernetes YAML podle osvědčených postupů a zásad

Poznámka. přel.: S rostoucím počtem konfigurací YAML pro prostředí K8 je potřeba jejich automatizovaného ověřování stále naléhavější. Autor této recenze nejen vybral existující řešení pro tento úkol, ale také použil Deployment jako příklad, aby viděl, jak fungují. Ukázalo se, že je to velmi poučné pro ty, kteří se o toto téma zajímají.

Ověřte Kubernetes YAML podle osvědčených postupů a zásad

TL, DR: Tento článek porovnává šest statických nástrojů pro ověřování a hodnocení souborů Kubernetes YAML s osvědčenými postupy a požadavky.

Úlohy Kubernetes jsou obvykle definovány ve formě dokumentů YAML. Jedním z problémů YAML je obtížnost specifikování omezení nebo vztahů mezi soubory manifestu.

Co když se potřebujeme ujistit, že všechny obrázky nasazené do clusteru pocházejí z důvěryhodného registru?

Jak mohu zabránit odeslání Deploymentů, které nemají PodDisruptionBudgets, do clusteru?

Integrace statického testování vám umožňuje identifikovat chyby a porušení zásad ve fázi vývoje. To zvyšuje záruku, že definice prostředků jsou správné a bezpečné, a zvyšuje pravděpodobnost, že produkční úlohy budou dodržovat osvědčené postupy.

Ekosystém kontroly statických souborů YAML Kubernetes lze rozdělit do následujících kategorií:

  • API validátory. Nástroje v této kategorii kontrolují manifest YAML podle požadavků serveru Kubernetes API.
  • Připravené testery. Nástroje z této kategorie jsou dodávány s hotovými testy bezpečnosti, souladu s osvědčenými postupy atd.
  • Vlastní validátory. Zástupci této kategorie vám umožňují vytvářet vlastní testy v různých jazycích, například Rego a Javascript.

V tomto článku popíšeme a porovnáme šest různých nástrojů:

  1. kubeval;
  2. kube-score;
  3. config-lint;
  4. měď;
  5. zápasit;
  6. polaris.

No, pojďme začít!

Kontrola nasazení

Než začneme nástroje porovnávat, vytvoříme nějaké pozadí, na kterém je otestujeme.

Níže uvedený manifest obsahuje řadu chyb a nedodržování osvědčených postupů: kolik z nich můžete najít?

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)

Tento YAML použijeme k porovnání různých nástrojů.

Výše uvedený manifest base-valid.yaml a další manifesty z tohoto článku lze nalézt v Repozitáře Git.

Manifest popisuje webovou aplikaci, jejímž hlavním úkolem je odpovědět zprávou „Hello World“ na port 5678. Lze ji nasadit pomocí následujícího příkazu:

kubectl apply -f hello-world.yaml

A tak - zkontrolujte práci:

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

Nyní přejděte na http://localhost:8080 a potvrďte, že aplikace funguje. Dodržuje však osvědčené postupy? Pojďme zkontrolovat.

1. Kubeval

V srdci kubeval Myšlenka je taková, že k jakékoli interakci s Kubernetes dochází prostřednictvím jeho REST API. Jinými slovy, můžete použít schéma API ke kontrole, zda mu daný YAML odpovídá. Podívejme se na příklad.

Pokyny pro instalaci kubeval jsou k dispozici na webových stránkách projektu.

V době psaní původního článku byla dostupná verze 0.15.0.

Po instalaci do něj dáme výše uvedený manifest:

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

Pokud bude úspěšný, kubeval se ukončí s kódem ukončení 0. Můžete to zkontrolovat následovně:

$ echo $?
0

Zkusme nyní kubeval s jiným manifestem:

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)

Dokážete odhalit problém očima? Pojďme spustit:

$ 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

Zdroj se neověřuje.

Nasazení pomocí verze API apps/v1, musí obsahovat selektor, který odpovídá štítku podu. Manifest výše neobsahuje selektor, takže kubeval nahlásil chybu a skončil s nenulovým kódem.

Zajímalo by mě, co se stane, když to udělám kubectl apply -f s tímto manifestem?

No, zkusíme:

$ 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

To je přesně ta chyba, před kterou kubeval varoval. Můžete to opravit přidáním selektoru:

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)

Výhodou nástrojů, jako je kubeval, je to, že chyby, jako jsou tyto, lze zachytit na začátku cyklu nasazení.

Tyto kontroly navíc nevyžadují přístup ke clusteru, lze je provádět offline.

Ve výchozím nastavení kubeval kontroluje prostředky podle nejnovějšího schématu Kubernetes API. Ve většině případů však možná budete muset zkontrolovat konkrétní verzi Kubernetes. To lze provést pomocí příznaku --kubernetes-version:

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

Upozorňujeme, že verze musí být uvedena ve formátu Major.Minor.Patch.

Seznam verzí, pro které je ověřování podporováno, naleznete na Schéma JSON na GitHubu, který kubeval používá pro validaci. Pokud potřebujete spustit kubeval offline, stáhněte si schémata a určete jejich místní umístění pomocí příznaku --schema-location.

Kromě jednotlivých souborů YAML umí kubeval pracovat také s adresáři a stdin.

Kubeval se navíc snadno integruje do potrubí CI. Ti, kteří chtějí provést testy před odesláním manifestů do clusteru, budou potěšeni, že kubeval podporuje tři výstupní formáty:

  1. Prostý text;
  2. JSON;
  3. Test Anything Protocol (TAP).

A kterýkoli z formátů lze použít pro další analýzu výstupu pro generování souhrnu výsledků požadovaného typu.

Jednou z nevýhod kubeval je, že v současné době nemůže kontrolovat shodu s vlastními definicemi zdrojů (CRD). Je však možné nakonfigurovat kubeval ignorovat je.

Kubeval je skvělý nástroj pro kontrolu a hodnocení zdrojů; Je však třeba zdůraznit, že absolvování testu nezaručuje, že zdroj vyhovuje osvědčeným postupům.

Například pomocí značky latest v kontejneru nedodržuje doporučené postupy. To však kubeval nepovažuje za chybu a nehlásí to. To znamená, že ověření takového YAML proběhne bez varování.

Ale co když chcete vyhodnotit YAML a identifikovat porušení, jako je značka latest? Jak porovnám soubor YAML s osvědčenými postupy?

2. Kube-skóre

Kube-skóre analyzuje manifesty YAML a vyhodnocuje je proti vestavěným testům. Tyto testy jsou vybírány na základě bezpečnostních pokynů a osvědčených postupů, jako jsou:

  • Spuštění kontejneru ne jako root.
  • Dostupnost kontrol stavu pod.
  • Nastavení požadavků a limitů na zdroje.

Na základě výsledků testu jsou uvedeny tři výsledky: OK, VAROVÁNÍ и KRITICKÝ.

Kube-score můžete vyzkoušet online nebo jej nainstalovat lokálně.

V době psaní původního článku byla nejnovější verze kube-score 1.7.0.

Zkusme to na našem manifestu 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 projde testy kubeval, zatímco kube-score poukazuje na následující nedostatky:

  • Kontroly připravenosti nejsou nakonfigurovány.
  • Neexistují žádné požadavky ani omezení na zdroje CPU a paměť.
  • Rozpočty na přerušení podu nejsou specifikovány.
  • Neexistují žádná pravidla oddělení (anti-afinitní) pro maximalizaci dostupnosti.
  • Kontejner běží jako root.

To vše jsou platné body o nedostatcích, které je třeba vyřešit, aby bylo nasazení efektivnější a spolehlivější.

Tým kube-score zobrazuje informace v podobě čitelné pro člověka, včetně všech typů porušení VAROVÁNÍ и KRITICKÝ, což hodně pomáhá při vývoji.

Ti, kteří chtějí používat tento nástroj v rámci kanálu CI, mohou povolit více komprimovaný výstup pomocí příznaku --output-format ci (v tomto případě se zobrazí také testy s výsledkem 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

Podobně jako kubeval vrací kube-score nenulový výstupní kód, když test selže KRITICKÝ. Můžete také povolit podobné zpracování pro VAROVÁNÍ.

Kromě toho je možné kontrolovat zdroje pro shodu s různými verzemi API (jako v kubeval). Tyto informace jsou však pevně zakódovány v samotném kube-score: nemůžete vybrat jinou verzi Kubernetes. Toto omezení může být velkým problémem, pokud máte v úmyslu upgradovat svůj cluster nebo pokud máte více clusterů s různými verzemi K8.

Vezměte prosím na vědomí, že již existuje problém s návrhem na realizaci této příležitosti.

Více informací o kube-score naleznete na oficiální stránky.

Testy Kube-score jsou skvělým nástrojem pro implementaci osvědčených postupů, ale co když potřebujete provést změny v testu nebo přidat vlastní pravidla? Bohužel, to nelze udělat.

Kube-score není rozšiřitelné: nemůžete do něj přidávat zásady ani je upravovat.

Pokud potřebujete napsat vlastní testy k ověření souladu s firemními zásadami, můžete použít jeden z následujících čtyř nástrojů: config-lint, měď, conftest nebo polaris.

3.Config-lint

Config-lint je nástroj pro ověřování konfiguračních souborů YAML, JSON, Terraform, CSV a manifestů Kubernetes.

Můžete jej nainstalovat pomocí instrukce na webu projektu.

Aktuální verze v době psaní původního článku je 1.5.0.

Config-lint nemá vestavěné testy pro ověřování manifestů Kubernetes.

Chcete-li provádět jakékoli testy, musíte vytvořit vhodná pravidla. Jsou zapsány v souborech YAML, které se nazývají „sady pravidel“ (sady pravidel)a mají následující strukturu:

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

(rule.yaml)

Pojďme si to prostudovat blíže:

  • Pole type určuje, jaký typ konfigurace bude config-lint používat. U manifestů K8 to tak je vždy Kubernetes.
  • V files Kromě samotných souborů můžete zadat adresář.
  • Pole rules určené pro nastavení uživatelských testů.

Řekněme, že se chcete ujistit, že obrázky v Deployment jsou vždy stahovány z důvěryhodného úložiště, jako je my-company.com/myapp:1.0. Pravidlo config-lint, které takovou kontrolu provádí, by vypadalo takto:

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

Každé pravidlo musí mít následující atributy:

  • id — jedinečný identifikátor pravidla;
  • severity - Možná SELHÁNÍ, VAROVÁNÍ и NON_COMPLIANT;
  • message — pokud dojde k porušení pravidla, zobrazí se obsah tohoto řádku;
  • resource — typ zdroje, na který se toto pravidlo vztahuje;
  • assertions — seznam podmínek, které budou vyhodnoceny ve vztahu k tomuto zdroji.

Ve výše uvedeném pravidle assertion oprávněn every zkontroluje, zda jsou všechny kontejnery v nasazení (key: spec.templates.spec.containers) používat důvěryhodné obrázky (tj. počínaje my-company.com/).

Kompletní sada pravidel vypadá takto:

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)

Chcete-li test vyzkoušet, uložte jej jako check_image_repo.yaml. Spusťte kontrolu souboru 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"
  }
]

Kontrola se nezdařila. Nyní se podívejme na následující manifest se správným úložištěm obrázků:

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)

Provedeme stejný test s výše uvedeným manifestem. Nebyly nalezeny žádné problémy:

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

Config-lint je slibný rámec, který vám umožňuje vytvářet vlastní testy pro ověřování manifestů Kubernetes YAML pomocí YAML DSL.

Ale co když potřebujete složitější logiku a testy? Není na to YAML příliš omezený? Co kdybyste mohli vytvořit testy v plném programovacím jazyce?

4. Měď

Měď V2 je rámec pro ověřování manifestů pomocí vlastních testů (podobně jako config-lint).

Od posledně jmenovaného se však liší tím, že k popisu testů nepoužívá YAML. Testy lze místo toho psát v JavaScriptu. Copper poskytuje knihovnu s několika základními nástroji, které vám pomohou číst informace o objektech Kubernetes a hlásit chyby.

Kroky pro instalaci Copper naleznete v oficiální dokumentace.

2.0.1 je nejnovější vydání tohoto nástroje v době psaní původního článku.

Stejně jako config-lint, ani Copper nemá vestavěné testy. Pojďme si jeden napsat. Nechte to zkontrolovat, že nasazení používá obrázky kontejnerů výhradně z důvěryhodných úložišť, jako je my-company.com.

Vytvořte soubor check_image_repo.js s následujícím obsahem:

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

Nyní otestovat náš manifest base-valid.yaml, použijte příkaz 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

Je jasné, že s pomocí mědi můžete provádět složitější testy – například kontrolu doménových jmen v Ingress manifestech nebo odmítání podů běžících v privilegovaném režimu.

Měď má v sobě zabudované různé užitečné funkce:

  • DockerImage přečte zadaný vstupní soubor a vytvoří objekt s následujícími atributy:
    • name - název obrázku,
    • tag - obrázková značka,
    • registry - registr obrázků,
    • registry_url - protokol (https://) a registr obrázků,
    • fqin — úplné umístění obrázku.
  • Funkce findByName pomáhá najít zdroj podle daného typu (kind) a jméno (name) ze vstupního souboru.
  • Funkce findByLabels pomáhá najít zdroj podle zadaného typu (kind) a štítky (labels).

Můžete zobrazit všechny dostupné servisní funkce zde.

Ve výchozím nastavení načte celý vstupní soubor YAML do proměnné $$ a zpřístupňuje jej pro skriptování (známá technika pro ty, kteří mají zkušenosti s jQuery).

Hlavní výhoda Copperu je zřejmá: nepotřebujete ovládat specializovaný jazyk a můžete využít různé funkce JavaScriptu k vytváření vlastních testů, jako je interpolace řetězců, funkce atd.

Je třeba také poznamenat, že současná verze Copper pracuje s verzí JavaScriptu ES5, nikoli ES6.

Podrobnosti jsou k dispozici na oficiální stránky projektu.

Pokud však nemáte příliš rádi JavaScript a preferujete jazyk speciálně navržený pro vytváření dotazů a popis politik, měli byste věnovat pozornost conftestu.

5. Soutěž

Conftest je rámec pro testování konfiguračních dat. Vhodné také pro testování/ověřování Kubernetes manifestů. Testy jsou popsány pomocí specializovaného dotazovacího jazyka Rego.

Contest můžete nainstalovat pomocí instrukceuvedené na webu projektu.

V době psaní původního článku byla poslední dostupná verze 0.18.2.

Podobně jako config-lint a měď, conftest přichází bez jakýchkoli vestavěných testů. Pojďme si to vyzkoušet a napsat vlastní politiku. Stejně jako v předchozích příkladech zkontrolujeme, zda jsou obrázky kontejnerů převzaty ze spolehlivého zdroje.

Vytvořte adresář conftest-checksa v něm je soubor s názvem check_image_registry.rego s následujícím obsahem:

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

Nyní pojďme testovat base-valid.yaml přes conftest:

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

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

Test podle očekávání selhal, protože snímky pocházely z nedůvěryhodného zdroje.

V souboru Rego definujeme blok deny. Jeho pravdivost je považována za porušení. Pokud blokuje deny několik, confest je kontroluje nezávisle na sobě a pravdivost kteréhokoli z bloků je považována za porušení.

Kromě výchozího výstupu podporuje conftest formát JSON, TAP a tabulky – mimořádně užitečná funkce, pokud potřebujete vložit sestavy do existujícího kanálu CI. Pomocí příznaku můžete nastavit požadovaný formát --output.

Aby bylo ladění zásad snazší, má conftest příznak --trace. Vydává stopu toho, jak conftest analyzuje zadané soubory zásad.

Zásady soutěže mohou být publikovány a sdíleny v registrech OCI (Open Container Initiative) jako artefakty.

Týmy push и pull vám umožní publikovat artefakt nebo načíst existující artefakt ze vzdáleného registru. Zkusme publikovat politiku, kterou jsme vytvořili, do místního registru Docker pomocí conftest push.

Spusťte místní registr Docker:

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

V jiném terminálu přejděte do adresáře, který jste vytvořili dříve conftest-checks a spusťte následující příkaz:

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

Pokud byl příkaz úspěšný, zobrazí se tato zpráva:

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

Nyní vytvořte dočasný adresář a spusťte v něm příkaz conftest pull. Stáhne balíček vytvořený předchozím příkazem:

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

V dočasném adresáři se objeví podadresář policyobsahující náš soubor zásad:

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

Testy lze spouštět přímo z úložiště:

$ 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

DockerHub bohužel zatím není podporován. Takže se považujte za štěstí, pokud používáte Azure Container Registry (ACR) nebo vlastní registr.

Formát artefaktu je stejný jako Otevřete balíčky agenta zásad (OPA), který vám umožňuje používat conftest ke spouštění testů ze stávajících balíčků OPA.

Více o sdílení zásad a dalších funkcích conftestu se můžete dozvědět na oficiální stránky projektu.

6. Polaris

Posledním nástrojem, o kterém bude v tomto článku řeč, je Polaris. (Jeho loňské oznámení my již přeloženo - Cca. přel.)

Polaris lze nainstalovat do clusteru nebo použít v režimu příkazového řádku. Jak jste možná uhodli, umožňuje vám staticky analyzovat manifesty Kubernetes.

Při spuštění v režimu příkazového řádku jsou k dispozici vestavěné testy pokrývající oblasti, jako je zabezpečení a osvědčené postupy (podobně jako kube-score). Kromě toho si můžete vytvořit vlastní testy (jako v config-lint, měď a conftest).

Jinými slovy, Polaris kombinuje výhody obou kategorií nástrojů: s vestavěnými a vlastními testy.

Chcete-li nainstalovat Polaris v režimu příkazového řádku, použijte pokyny na webu projektu.

V době psaní původního článku je k dispozici verze 1.0.3.

Po dokončení instalace můžete spustit polaris na manifestu base-valid.yaml s následujícím příkazem:

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

Vypíše řetězec ve formátu JSON s podrobným popisem provedených testů a jejich výsledků. Výstup bude mít následující strukturu:

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

Plný výstup k dispozici zde.

Stejně jako kube-score i Polaris identifikuje problémy v oblastech, kde manifest nesplňuje osvědčené postupy:

  • Pro lusky nejsou žádné zdravotní kontroly.
  • Značky pro obrázky kontejnerů nejsou zadány.
  • Kontejner běží jako root.
  • Požadavky a limity pro paměť a CPU nejsou specifikovány.

Každému testu je v závislosti na jeho výsledcích přiřazen stupeň kritičnosti: varování nebo nebezpečí. Chcete-li se dozvědět více o dostupných vestavěných testech, viz dokumentace.

Pokud podrobnosti nejsou potřeba, můžete zadat příznak --format score. V tomto případě Polaris vydá číslo v rozsahu od 1 do 100 − skóre (tj. hodnocení):

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

Čím více se skóre blíží 100, tím vyšší je míra shody. Pokud zkontrolujete výstupní kód příkazu polaris audit, ukáže se, že se rovná 0.

Udělat polaris audit Práci s nenulovým kódem můžete ukončit pomocí dvou příznaků:

  • Vlajka --set-exit-code-below-score bere jako argument prahovou hodnotu v rozsahu 1-100. V tomto případě se příkaz ukončí s kódem ukončení 4, pokud je skóre pod prahovou hodnotou. To je velmi užitečné, když máte určitou prahovou hodnotu (řekněme 75) a potřebujete obdržet upozornění, pokud skóre klesne.
  • Vlajka --set-exit-code-on-danger způsobí selhání příkazu s kódem 3, pokud selže jeden z testů nebezpečí.

Nyní se pokusíme vytvořit vlastní test, který zkontroluje, zda je obrázek převzat z důvěryhodného úložiště. Vlastní testy jsou specifikovány ve formátu YAML a samotný test je popsán pomocí schématu JSON.

Následující fragment kódu YAML popisuje nový test s názvem 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/.+$

Pojďme se na to podívat blíže:

  • successMessage — tento řádek bude vytištěn v případě úspěšného dokončení testu;
  • failureMessage — tato zpráva se zobrazí v případě selhání;
  • category — označuje jednu z kategorií: Images, Health Checks, Security, Networking и Resources;
  • target--- určuje, jaký typ objektu (spec) je použit test. Možné hodnoty: Container, Pod nebo Controller;
  • Vlastní test je specifikován v objektu schema pomocí schématu JSON. Klíčové slovo v tomto testu je pattern slouží k porovnání zdroje obrazu s požadovaným.

Chcete-li spustit výše uvedený test, musíte vytvořit následující konfiguraci 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)

Pojďme analyzovat soubor:

  • V checks testy a jejich úroveň kritičnosti jsou předepsány. Protože je žádoucí dostávat upozornění, když je snímek pořízen z nedůvěryhodného zdroje, nastavujeme úroveň zde danger.
  • Samotný test checkImageRepo poté registrován v objektu customChecks.

Uložte soubor jako custom_check.yaml. Nyní můžete běžet polaris audit s manifestem YAML, který vyžaduje ověření.

Vyzkoušíme náš manifest base-valid.yaml:

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

Tým polaris audit spustil pouze výše uvedený uživatelský test a selhal.

Pokud obrázek opravíte na my-company.com/http-echo:1.0, Polaris úspěšně dokončí. Manifest se změnami je již ve hře úložišťtakže můžete zkontrolovat předchozí příkaz v manifestu image-valid-mycompany.yaml.

Nyní vyvstává otázka: jak spustit vestavěné testy spolu s vlastními? Snadno! Stačí přidat vestavěné testovací identifikátory do konfiguračního souboru. V důsledku toho bude mít následující podobu:

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)

K dispozici je příklad úplného konfiguračního souboru zde.

Zkontrolujte manifest base-valid.yamlpomocí vestavěných a vlastních testů můžete použít příkaz:

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

Polaris doplňuje vestavěné testy vlastními testy, čímž kombinuje to nejlepší z obou světů.

Na druhou stranu nemožnost používat výkonnější jazyky jako Rego nebo JavaScript může být limitujícím faktorem bránícím vytváření sofistikovanějších testů.

Více informací o Polaris je k dispozici na projektové místo.

Shrnutí

I když je k dispozici mnoho nástrojů pro kontrolu a hodnocení souborů Kubernetes YAML, je důležité mít jasnou představu o tom, jak budou testy navrženy a provedeny.

Například, pokud vezmete manifesty Kubernetes procházející potrubím, kubeval by mohl být prvním krokem v takovém potrubí. Monitoroval by, zda definice objektů odpovídají schématu Kubernetes API.

Jakmile je taková revize dokončena, lze přejít k sofistikovanějším testům, jako je dodržování standardních osvědčených postupů a specifických zásad. Tady by se hodily kube-score a Polaris.

Pro ty, kteří mají složité požadavky a potřebují si testy detailně přizpůsobit, by byly vhodné měděné, config-lint a conftest.

Conftest a config-lint používají YAML k definování vlastních testů a měď vám poskytuje přístup k úplnému programovacímu jazyku, což z něj dělá docela atraktivní volbu.

Na druhou stranu, vyplatí se použít některý z těchto nástrojů a tedy vytvářet všechny testy ručně, nebo dát přednost Polarisu a přidat do něj jen to, co je potřeba? Na tuto otázku neexistuje jednoznačná odpověď.

Níže uvedená tabulka obsahuje stručný popis každého nástroje:

Nástroj
Účel
Omezení
Uživatelské testy

kubeval
Ověřuje manifesty YAML proti konkrétní verzi schématu API
Nelze pracovat s CRD
Ne

kube-skóre
Analyzuje projevy YAML proti osvědčeným postupům
Nelze vybrat verzi Kubernetes API ke kontrole zdrojů
Ne

měď
Obecný rámec pro vytváření vlastních testů JavaScriptu pro manifesty YAML
Žádné vestavěné testy. Špatná dokumentace
Ano

config-lint
Obecný rámec pro vytváření testů v jazyce specifickém pro doménu vloženém do YAML. Podporuje různé konfigurační formáty (např. Terraform)
Neexistují žádné hotové testy. Vestavěná tvrzení a funkce nemusí stačit
Ano

zápas
Rámec pro vytváření vlastních testů pomocí Rego (specializovaný dotazovací jazyk). Umožňuje sdílení politik prostřednictvím balíčků OCI
Žádné vestavěné testy. Musím se naučit Rego. Docker Hub není podporován při publikování zásad
Ano

Polaris
Recenze manifestů YAML proti standardním osvědčeným postupům. Umožňuje vytvářet vlastní testy pomocí schématu JSON
Testovací možnosti založené na schématu JSON nemusí být dostatečné
Ano

Protože tyto nástroje nespoléhají na přístup ke clusteru Kubernetes, lze je snadno nainstalovat. Umožňují filtrovat zdrojové soubory a poskytují rychlou zpětnou vazbu autorům žádostí o stažení v projektech.

PS od překladatele

Přečtěte si také na našem blogu:

Zdroj: www.habr.com

Přidat komentář