Validácia Kubernetes YAML podľa najlepších praktík a politík

Pozn. prekl.: S rastom počtu YAML konfigurácií pre K8s prostredia sa čoraz viac stáva aktuálnou potreba ich automatizovanej kontroly. Autor tejto recenzie nielenže vybral existujúce riešenia pre túto úlohu, ale aj na príklade Deploymentu sa pozrel, ako fungujú. Vzniklo to veľmi informatívne pre tých, ktorých táto téma zaujíma.

Validácia Kubernetes YAML podľa najlepších praktík a politík

TL;DR: V článku sa porovnávajú šesť statických nástrojov na kontrolu a hodnotenie YAML súborov Kubernetes na dodržiavanie najlepších praktík a požiadaviek.

Pracovné zaťaženia Kubernetes sa zvyčajne definujú vo forme YAML dokumentov. Jedným z problémov s YAMLom je zložitá definícia obmedzení alebo vzťahov medzi súbormi manifestov.

Čo ak sa chceme uistiť, že všetky obrazy nasadzované v klastri pochádzajú z dôveryhodného registru?

Ako zabrániť odoslaniu Deploymentov do klastra, pre ktoré nie sú nastavené PodDisruptionBudgets?

Integrácia statického testovania umožňuje odhaľovať chyby a porušovania politík už na fáze vývoja. Tým sa zvyšujú záruky správnosti a bezpečnosti definícií zdrojov a zvyšuje sa pravdepodobnosť, že produkčné zaťaženia budú dodržiavať najlepšie praktiky.

Ekosystém statickej kontroly YAML súborov Kubernetes možno rozdeliť do nasledujúcich kategórií:

  • API validátory. Nástroje v tejto kategórii kontrolujú YAML manifest na dodržiavanie požiadaviek API servera Kubernetes.
  • Hotové testery. Nástroje z tejto kategórie prichádzajú s pripravenými testami na bezpečnosť, dodržiavanie najlepších praktík atď.
  • Vlastné validátory. Predstavitelia tejto kategórie umožňujú vytvárať vlastné testy v rôznych programovacích jazykoch, napríklad v Rego a Javascript.

V tomto článku opíšeme a porovnáme šesť rôznych nástrojov:

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

No, poďme na to!

Kontrola Deploymentov

Predtým, ako sa pustíme do porovnávania nástrojov, vytvorme nejaký základ, na ktorom ich budeme testovať.

Nižšie uvedený manifest obsahuje množstvo chýb a nezrovnalostí s najlepšími praktikami: koľko z nich dokážete nájsť?

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 budeme používať na porovnanie rôznych nástrojov.

Verejný manifest base-valid.yaml a ďalšie manifesty z tohto článku nájdete v Git-repozitáriu.

Manifest popisuje webovú aplikáciu, ktorej hlavnou úlohou je odpovedať správou „Hello World“ na porte 5678. Môžete ho nasadiť nasledujúcim príkazom:

kubectl apply -f hello-world.yaml

A teraz — skontrolovať funkčnosť:

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

Teraz prejdite na http://localhost:8080 a potvrďte, že aplikácia funguje. Ale spĺňa to najlepšie praktiky? Poďme to skontrolovať.

1. Kubeval

Základná myšlienka kubeval je, že akákoľvek interakcia s Kubernetes prebieha prostredníctvom jeho REST API. Inými slovami, môžete použiť API schému na overenie, či je daný YAML v súlade s ňou. Pozrime sa na príklad.

Inštrukcie na inštaláciu kubeval sú dostupné na stránke projektu.

V čase písania pôvodného článku bola dostupná verzia 0.15.0.

Po inštalácii poďme "dávkovať" mu vyššie uvedený manifest:

$ kubeval base-valid.yaml
PASS - base-valid.yaml obsahuje platný Deployment (http-echo)
PASS - base-valid.yaml obsahuje platný Service (http-echo)

V prípade úspechu kubeval sa ukončí s exit-kódom 0. Môžete to skontrolovať nasledovne:

$ echo $?
0

Teraz skúsme kubeval s iným manifestom:

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)

Môžete na prvý pohľad určiť problém? Spúšťame:

$ kubeval kubeval-invalid.yaml
WARN - kubeval-invalid.yaml obsahuje neplatný Deployment (http-echo) - selector: selector je povinný
PASS - kubeval-invalid.yaml obsahuje platný Service (http-echo)

# skontrolujeme návratový kód
$ echo $?
1

Zdroje neprejdú overením.

Deploymenty používajúce verziu API apps/v1, musia zahŕňať selektor zodpovedajúci štítku podu. Vyššie uvedený manifest neobsahuje selektor, preto kubeval uvedenú chybu a skončil s nenulovým kódom.

Zaujímavé, čo sa stane, ak spustíte kubectl apply -f s týmto manifestom?

Nuže, poďme to skúsiť:

$ 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

Ide o tú chybu, na ktorú upozorňoval kubeval. Môžete ju opraviť pridaním selektora:

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ástrojov ako kubeval je, že podobné chyby môžete zachytiť v raných fázach cyklu nasadenia.

Okrem toho na tieto kontroly nie je potrebný prístup do klastra: môžu sa vykonávať offline.

Predvolene kubeval kontroluje zdroje na zhodu s najnovšou schémou Kubernetes API. V mnohých prípadoch však môže byť potrebné vykonať kontrolu na zhodu s konkrétnou verziou Kubernetes. Môžete to urobiť pomocou prepínača --kubernetes-version:

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

Všimnite si, že verzia musí byť uvedená v formáte Major.Minor.Patch.

Aby ste si prezreli zoznam verzií, pre ktoré je podpora kontroly, navštívte JSON schému na GitHub, ktorú kubeval používa na validáciu. Ak potrebujete spustiť kubeval offline, stiahnite si schémy a uveďte ich miestne umiestnenie pomocou prepínača --schema-location.

Okrem samostatných YAML súborov môže kubeval pracovať aj s adresármi a stdin.

Okrem toho sa Kubeval ľahko integruje do CI pipeline. Tí, ktorí chcú vykonávať testy pred odoslaním manifestov do klastra, budú radi, že kubeval podporuje tri formáty výstupu:

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

A ktorýkoľvek z formátov môžete použiť na ďalšie spracovanie výstupu na vytvorenie prehľadu výsledkov v požadovanom formáte.

Jedna z nevýhod kubevalu — v súčasnosti nemôže kontrolovať zhodu Custom Resource Definitions (CRDs). Avšak môžete nastaviť kubeval, aby ich ignoroval..

Kubeval je skvelý nástroj na kontrolu a hodnotenie zdrojov; pravda, treba zdôrazniť, že úspešné absolvovanie testu nezaručuje, že zdroj zodpovedá najlepším praktikám.

Napríklad použitie tagu latest v kontejnere nespĺňa najlepšie praktiky. Avšak kubeval to nepovažuje za chybu a neoznamuje ju. To znamená, že kontrola takéhoto YAML skončí bez varovaní.

Ale čo ak potrebujete posúdiť YAML a odhaliť porušenia ako tag latest? Как проверить YAML-файл на соответствие лучшим практикам?

2. Kube-score

Kube-score analyzuje manifesty YAML a hodnotí ich podľa zabudovaných testov. Tieto testy sú vybrané na základe odporúčaní týkajúcich sa bezpečnosti a najlepších praktík, ako napríklad:

  • Spustenie kontajnera nepod rootom.
  • Existencia kontrol zdravia podov.
  • Zadanie požiadaviek a limitov pre zdroje.

Na základe testu sú vydané tri výsledky: OK, UPOZORNENIE a KRITICKÉ.

Kube-score si môžete vyskúšať online alebo ho nainštalovať lokálne.

V čase písania originálneho článku bola najnovšia verzia kube-score 1.7.0.

Poďme ho vyskúšať na našom manifeste base-valid.yaml:

$ kube-score score base-valid.yaml

apps/v1/Deployment http-echo
[KRITICKÉ] Tag obrazca kontajnera
  · http-echo -> Obrazec s tagom latest
      Odporúča sa používať fixný tag, aby sa predišlo náhodným aktualizáciám
[KRITICKÉ] Politika siete podov
  · Pod nemá zodpovedajúcu politiku siete
      Vytvorte sieťovú politiku, ktorá cielená na tento pod
[KRITICKÉ] Kontroly podov
  · Kontajner nemá nastavenú readinessProbe
      ReadinessProbe by sa mala používať na označenie, kedy je služba pripravená prijímať prevádzku.
      Bez nej, Pod riskuje prijímanie prevádzky predtým, ako sa spustí. Taktiež sa používa počas
      rolloutov a môže zabrániť výpadku, ak nová verzia aplikácie zlyhá.
      Viac informácií: https://github.com/zegl/kube-score/blob/master/README_PROBES.md
[KRITICKÉ] Bezpečnostný kontext kontajnera
  · http-echo -> Kontajner nemá nastavený bezpečnostný kontext
      Nastavte securityContext na spustenie kontajnera v bezpečnejšom kontexte.
[KRITICKÉ] Zdroje kontajnera
  · http-echo -> CPU limit nie je nastavený
      Odporúča sa nastaviť limity zdrojov, aby sa predišlo DDoS útokowi na zdroje. Nastavte resources.limits.cpu
  · http-echo -> Limit pamäte nie je nastavený
      Odporúča sa nastaviť limity zdrojov, aby sa predišlo DDoS útokowi na zdroje. Nastavte resources.limits.memory
  · http-echo -> CPU požiadavka nie je nastavená
      Odporúča sa nastaviť požiadavky na zdroje, aby sa zabezpečilo, že aplikácia sa môže spustiť a bežať bez
      zlyhania. Nastavte resources.requests.cpu
  · http-echo -> Požiadavka na pamäť nie je nastavená
      Odporúča sa nastaviť požiadavky na zdroje, aby sa zabezpečilo, že aplikácia sa môže spustiť a bežať bez zlyhania.
      Nastavte resources.requests.memory
[KRITICKÉ] Nasadenie má PodDisruptionBudget
  · Nebol nájdený zodpovedajúci PodDisruptionBudget
      Odporúča sa definovať PodDisruptionBudget, aby sa predišlo neočakávanému výpadku počas údržby Kubernetes,
      ako napríklad pri vypúšťaní uzla.
[UPOZORNENIE] Nasadenie má hostiteľskú PodAntiAffinity
  · Nasadenie nemá nastavené hostiteľské podAntiAffinity
      Odporúča sa nastaviť podAntiAffinity, aby sa zabránilo viacerým podom z nasadenia
      byť naplánované na tom istom uzle. To zvyšuje dostupnosť v prípade, že sa uzol stane nedostupným.

YAML prechádza kontrolami kubeval, zatiaľ čo kube-score označuje nasledujúce nedostatky:

  • Nepodporujú sa pripravenostné kontroly.
  • Chýbajú požiadavky a limity pre zdroje CPU a pamäť.
  • Neboli nastavené Pod disruption budgets.
  • Chýbajú pravidlá pre oddelené existovanie (anti-affinity) na maximalizáciu dostupnosti.
  • Kontajner beží pod rootom.

Všetky tieto sú rozumné pripomienky k nedostatkom, ktoré je potrebné odstrániť, aby bol Deployment efektívnejší a spoľahlivejší.

Tím kube-score vydáva informácie v čitateľnej forme so zahrnutím všetkých porušení typu UPOZORNENIE a KRITICKÉ, čo veľmi pomáha počas vývoja.

Záujemcovia o použitie tohto nástroja v rámci CI pipeline môžu zapnúť zjednodušený výstup pomocou prepínača --output-format ci (v tomto prípade sa zobrazujú aj testy s výsledkom 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 nie je nastavený
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory limit nie je nastavený
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) CPU request nie je nastavený
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Memory request nie je nastavený
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Image je nastavený na posledný tag
[OK] http-echo apps/v1/Deployment
[CRITICAL] http-echo apps/v1/Deployment: Pod nemá zodpovedajúcu sieťovú politiku
[CRITICAL] http-echo apps/v1/Deployment: Kontajner nemá nastavený readinessProbe
[CRITICAL] http-echo apps/v1/Deployment: (http-echo) Kontajner nemá konfigurované bezpečnostné prostredie
[CRITICAL] http-echo apps/v1/Deployment: Nebola nájdená zodpovedajúca PodDisruptionBudget
[WARNING] http-echo apps/v1/Deployment: Deployment nemá nastavené host podAntiAffinity
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service
[OK] http-echo v1/Service

Podobne ako kubeval, kube-score vracia nenulový kód výstupu, ak je test, ktorý sa skončil chybou. KRITICKÉ. Takisto je možné zapnúť podobné spracovanie aj pre UPOZORNENIE.

Okrem toho je možné kontroly zdrojov na zodpovednosť rôznym verziám API (rovnako ako v kubeval). Avšak tieto informácie sú za'hardcode'ované v samotnom kube-score: nie je možné vybrať inú verziu Kubernetes. Toto obmedzenie môže byť veľkým problémom, ak plánujete aktualizovať cluster alebo máte niekoľko clustrov s rôznymi verziami K8s.

Všimnite si, že už existuje issue s návrhom implementovať túto možnosť.

Viac o kube-score sa môžete dozvedieť na oficiálnej stránke.

Testy kube-score sú skvelý nástroj na zavedenie osvedčených praktík, ale čo ak je potrebné vykonať zmeny v teste alebo pridať vlastné pravidlá? Bohužiaľ, to nebude možné.

Kube-score nie je rozšíriteľný: do neho nie je možné pridať politiky ani ich prispôsobiť.

Ak je potrebné písať vlastné testy na kontroly dodržiavania politík prijatých v spoločnosti, môžete použiť jeden z týchto štyroch nástrojov: config-lint, copper, conftest alebo polaris.

3. Config-lint

Config-lint je nástroj na validáciu konfiguračných súborov vo formáte YAML, JSON, Terraform, CSV a manifestov Kubernetes.

Môžete ho nainštalovať podľa pokynov na stránke projektu.

Aktuálna verzia k okamihu písania pôvodného článku je 1.5.0.

Config-lint neobsahuje vstavané testy na kontrolu manifestov Kubernetes.

Na vykonávanie akýchkoľvek testov je potrebné vytvoriť príslušné pravidlá. Tieto sa zapisujú do YAML súborov nazývaných „sady pravidiel“ (rulesets), a majú nasledujúcu štruktúru:

version: 1
description: Pravidlá pre špecifikačné súbory Kubernetes
type: Kubernetes
files:
  - "*.yaml"
rules:
   # zoznam pravidiel

(rule.yaml)

Pozrime sa na to podrobnejšie:

  • Pole type určuje, aký typ konfigurácie bude config-lint používať. Pre manifesty K8s je to vždy Kubernetes.
  • V poli files okrem samotných súborov je možné zadať aj adresár.
  • Pole rules je určené na definovanie používateľských testov.

Povedzme, že chcete zabezpečiť, aby sa obrazy v Deploymente vždy sťahovali z dôveryhodného úložiska, ako je my-company.com/myapp:1.0. Pravidlo pre config-lint, ktoré vykonáva podobnú kontrolu, bude vyzerať nasledovne:

- id: MY_DEPLOYMENT_IMAGE_TAG
  severity: FAILURE
  message: Deployment musí používať platný obrazový tag
  resource: Deployment
  assertions:
    - every:
        key: spec.template.spec.containers
        expressions:
          - key: image
            op: starts-with
            value: "my-company.com/"

(rule-trusted-repo.yaml)

Pre každé pravidlo musia byť uvedené nasledujúce atribúty:

  • id — jedinečný identifikátor pravidla;
  • severity — môže byť FAILURE, UPOZORNENIE a NON_COMPLIANT;
  • message — obsah tejto riadky sa zobrazí pri porušení pravidla;
  • resource — typ zdroja, na ktorý sa pravidlo vzťahuje;
  • assertions — zoznam podmienok, ktoré budú hodnotené vo vzťahu k tomuto zdroju.

V pravidle vyššie assertion s názvom every kontroluje, že všetky kontajnery v Deploymente (key: spec.templates.spec.containers) používajú dôveryhodné obrazy (t.j. začínajúce s my-company.com/).

Celý ruleset vyzerá nasledovne:

version: 1
description: Pravidlá pre špecifikačné súbory Kubernetes
type: Kubernetes
files:
  - "*.yaml"
rules:

 - id: DEPLOYMENT_IMAGE_REPOSITORY # !!!
    severity: FAILURE
    message: Deployment musí používať platnú obrazovú úložisko
    resource: Deployment
    assertions:
      - every:
          key: spec.template.spec.containers
          expressions:
            - key: image
              op: starts-with
              value: "my-company.com/"

(ruleset.yaml)

Aby sme otestovali test, uložme ho ako check_image_repo.yaml. Spustíme kontrolu na súbore base-valid.yaml:

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

[
  {
  "AssertionMessage": "Každý výraz zlyhal: A výraz zlyhal: obrázok nezačína s 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": "Nasadenie musí používať platný repozitár obrázkov",
  "Status": "FAILURE"
  }
]

Kontrola zlyhala. Teraz skontrolujme ďalší manifest s platným repozitárom obrázkov:

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)

Spúšťame ten istý test s uvedeným manifestom. Problémy neboli zistené:

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

Config-lint je perspektívny rámec, ktorý umožňuje vytvárať vlastné testy na overovanie YAML manifestov Kubernetes pomocou YAML DSL.

Ale čo robiť, ak sú potrebné zložitejšie logiky a testy? Nie sú možnosti YAML na to príliš obmedzené? Čo ak by sme mohli vytvárať testy v plnohodnotnom programovacom jazyku?

4. Copper

Copper V2 je rámec na validáciu manifestov pomocou vlastných testov (podobne ako config-lint).

Napriek tomu sa od posledného líši v tom, že nepoužíva YAML na popis testov. Namiesto toho je možné vytvárať testy v JavaScripte. Copper poskytuje knižnicu s niekoľkými základnými nástrojmi, ktoré pomáhajú načítať informácie o objektoch Kubernetes a hlásiť chyby.

Postup inštalácie Copper nájdete v oficiálnej dokumentácii.

2.0.1 — najnovšie vydanie tohto nástroja v čase písania pôvodného článku.

Rovnako ako config-lint, ani Copper nemá vstavané testy. Poďme napísať jeden. Nech overuje, že nasadenia používajú kontajnerové obrázky výlučne z dôveryhodných repozitárov, ako je my-company.com.

Vytvorte súbor check_image_repo.js s nasledujúcim obsahom:

$$.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 + " nie je z repozitáru my-company.com", 1)
            }
        });
    }
});

Teraz, aby ste skontrolovali náš manifest base-valid.yaml, použite príkaz copper validate:

$ copper validate --in=base-valid.yaml --validator=check_image_tag.js

Test no_company_repo zlyhal s váhou 1 z dôvodu, že obrázok http-echo nie je z repozitára my-company.com
Overenie zlyhalo

Je jasné, že pomocou copper je možné vykonávať zložitejšie testy — napríklad overovať doménové mená v manifestoch Ingress alebo odmietať pod’y, ktoré bežia v privilegovanom režime.

V Copper sú zabudované rôzne pomocné funkcie:

  • DockerImage číta zadaný vstupný súbor a vytvára objekt s nasledujúcimi atribútmi:
    • name — názov obrazu,
    • tag — tag obrazu,
    • registry — registr obrazov,
    • registry_url — protokol (https://) a registr obrazov,
    • fqin — plná lokalizácia obrazu.
  • Funkcia findByName pomáha nájsť zdroj podľa zadaného typu (druh) a názvu (name) zo vstupného súboru.
  • Funkcia findByLabels pomáha nájsť zdroj podľa zadaného typu (druh) a značiek (labels).

So všetkými dostupnými pomocnými funkciami sa môžete oboznámiť tu.

Predvolene načíta celý vstupný YAML súbor do premennej $$ a sprístupní ju pre skripty (známa metóda pre tých, ktorí majú skúsenosti s jQuery).

Hlavná výhoda Copper je zrejmá: nemusíte sa učiť špecializovaný jazyk a môžete využívať rôzne možnosti JavaScriptu na vytvorenie vlastných testov, ako je interpolácia reťazcov, funkcie a podobne.

Je tiež dôležité poznamenať, že súčasná verzia Copper funguje s verziou ES5 JavaScriptového enginu, a nie s ES6.

Podrobnosti sú k dispozícii na oficiálnej stránke projektu.

Napriek tomu, ak veľmi nemáte radi JavaScript a preferujete jazyk, špeciálne určený na vytváranie dopytov a opis politík, mali by ste sa pozrieť na conftest.

5. Conftest

Conftest je rámec na overovanie konfiguračných údajov. Je vhodný na testovanie/overovanie manifestov Kubernetes. Testy sú popísané pomocou špecializovaného jazyka dotazov Rego.

Inštaláciu conftest môžete vykonať pomocou pokynov, ktoré sú uvedené na webovej stránke projektu.

V čase písania pôvodného článku bola najnovšia dostupná verzia 0.18.2.

Na rozdiel od config-lint a copper neobsahuje conftest žiadne vstavané testy. Poďme to vyskúšať a napísať vlastnú politiku. Rovnako ako v predchádzajúcich príkladoch, budeme kontrolovať, či sú obrazy kontajnerov získané z dôveryhodného zdroja.

Vytvorte adresár conftest-checks, a v ňom súbor s názvom check_image_registry.rego s nasledujúcim obsahom:

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

Teraz otestujme base-valid.yaml cez 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 očakávane zlyhal, pretože obrazy pochádzajú z nedôveryhodného zdroja.

V súbore Rego definujeme blok deny. Jeho pravdivosť sa považuje za porušenie. Ak existuje viac blokov, conftest ich kontroluje nezávisle a pravdivosť ktoréhokoľvek bloku sa považuje za porušenie. deny Okrem výstupu podľa predvoľby, conftest podporuje JSON, TAP a tabuľkový formát — čo je mimoriadne užitočná funkcia, ak je potrebné integrovať správy do existujúceho CI pipeline. Potrebný formát môžete nastaviť pomocou príkazu

--output Pre uľahčenie ladenia politík má conftest príkaz.

--trace . Ten zobrazuje trasovanie toho, ako conftest analyzuje určené súbory politík.Politiky conftest je možné publikovať a zdieľať v OCI registroch (Open Container Initiative) vo forme artefaktov.

push

Príkazy umožňuje publikovať artefakt alebo stiahnuť existujúci artefakt z vzdialeného registra. Skúsme publikovať našu vytvorenú politiku do lokálneho Docker registra pomocou a pull conftest push Spustite lokálny Docker register:.

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

V inom termináli prejdite do predtým vytvorenej adresáre

a vykonajte nasledujúci príkaz: conftest-checks $ conftest push 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

Ak príkaz prebehne úspešne, uvidíte správu nasledujúceho typu:

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

Teraz vytvorte dočasnú adresáre a vykonajte v nej príkaz

conftest pull . Ten stiahne do nej balík vytvorený predchádzajúcim príkazom:$ cd $(mktemp -d) $ conftest pull 127.0.0.1:5000/amitsaha/opa-bundle-example:latest

V dočasnej adresáre sa objaví podadresár

, ktorý obsahuje náš súbor s politikou: politika$ tree . └── policy └── check_image_registry.rego

Testy možno vykonávať priamo z repozitára:

$ 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

Bohužiaľ, DockerHub zatiaľ nie je podporovaný. Takže považujte to za šťastie, ak používate

Azure Container Registry (ACR) alebo svoj vlastný register. Formát artefaktov je rovnaký ako u

balíkov Open Policy Agent (OPA), čo umožňuje používať conftest na vykonávanie testov zo existujúcich balíkov OPA. Viac o zdieľaní politík a iných vlastnostiach conftest sa môžete dozvedieť na

6. Polaris oficiálnej stránke projektu.

Posledný nástroj, o ktorom bude reč v tomto článku, je

(Jeho minuloročný oznámenie sme Polaris. už prekladali pozn. prekl. — pozn. prekl.)

Polaris sa dá nainštalovať do clustera alebo použiť v príkazovom riadku. Ako ste už uhádli, umožňuje statickú analýzu manifestov Kubernetes.

Pri práci v príkazovom riadku sú k dispozícii vstavané testy, pokrývajúce oblasti ako bezpečnosť a osvedčené postupy (podobne ako kube-score). Okrem toho je možné vytvárať vlastné testy (ako v config-lint, copper a conftest).

Inými slovami, Polaris spája výhody oboch kategórií nástrojov: so vstavanými a používateľskými testami.

Na inštaláciu Polaris v príkazovom riadku použite návody na webovej stránke projektu..

V čase písania pôvodného článku bola k dispozícii verzia 1.0.3.

Po dokončení inštalácie môžete spustiť polaris na manifeste base-valid.yaml pomocou nasledujúceho príkazu:

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

Vyprodukuje reťazec vo formáte JSON s podrobným popisom vykonaných testov a ich výsledkami. Výstup bude mať nasledujúcu štruktúru:

{
  "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": [
    * dlhý zoznam *
  ]
}

Úplný výstup je k dispozícii tu.

Rovnako ako kube-score, Polaris odhaľuje problémy v tých oblastiach, kde manifest nespĺňa osvedčené postupy:

  • Chýbajú kontroly zdravia podov.
  • Nie sú uvedené značky pre kontajnerové obrazy.
  • Kontajner beží pod rootom.
  • Nie sú uvedené požiadavky a limity pre pamäť a CPU.

Každému testu sa v závislosti od jeho výsledkov priradí miera kritičnosti: warning alebo danger. Ak chcete získať viac informácií o existujúcich vstavaných testoch, obráťte sa na dokumenácie.

Ak podrobnosti nie sú potrebné, môžete zadať prepínač --format score. V tomto prípade Polaris outputne číslo v rozmedzí od 1 do 100 — score (t.j. hodnotenie):

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

Čím je hodnotenie bližšie k 100, tým je vyššia miera zhody. Ak skontrolujete exit-kód príkazu polaris audit, ukáže sa, že je rovný 0.

Začať polaris audit končiť s nenulovým kódom môžete pomocou dvoch prepínačov:

  • Zástavka --set-exit-code-below-score prijíma ako argument prahovú hodnotu v rozmedzí 1-100. V takom prípade sa príkaz dokončí s exit-kódom 4, ak bude hodnotenie nižšie ako prahová hodnota. Je to veľmi pohodlné, keď máte určitú prahovú hodnotu (povedzme 75) a potrebujete získať alert, ak hodnotenie klesne pod.
  • Zástavka --set-exit-code-on-danger spôsobí, že tím sa ukončí s kódom 3, ak jeden z testov nebezpečenstva zlyhá.

Teraz sa pokúsime vytvoriť vlastný test, ktorý overí, či obraz pochádza z dôveryhodného repozitára. Vlastné testy sú definované vo formáte YAML a samotný test je popísaný pomocou JSON Schema.

Nasledujúci fragment YAML kódu popisuje nový test, nazvaný checkImageRepo:

checkImageRepo:
  successMessage: Registrácia obrazu je platná
  failureMessage: Registrácia obrazu nie je platná
  category: Obrázky
  target: Kontajner
  schema:
    '$schema': http://json-schema.org/draft-07/schema
    type: object
    properties:
      image:
        type: string
        pattern: ^my-company.com/.+$

Pozrime sa na to bližšie:

  • successMessage — táto správa sa zobrazí, ak test prebehne úspešne;
  • failureMessage — toto hlásenie sa zobrazí v prípade zlyhania;
  • category — označuje jednu z kategórií: Obrázky, Kontroly zdravia, Bezpečnosť, Sieťovanie a Zdroje;
  • target— určuje, k akému typu objektu (spec) sa test aplikuje. Možné hodnoty: Kontajner, Pod alebo Ovládač;
  • Samotný test je definovaný v objekte schema s pomocou JSON schémy. V tomto teste sa kľúčové slovo pattern používa na porovnanie zdroja obrazu s požadovaným.

Aby sme spustili vyššie uvedený test, musíme vytvoriť nasledujúcu konfiguráciu Polaris:

checks:
  checkImageRepo: danger
customChecks:
  checkImageRepo:
    successMessage: Registrácia obrazu je platná
    failureMessage: Registrácia obrazu nie je platná
    category: Obrázky
    target: Kontajner
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(polaris-conf.yaml)

Analyzujme súbor:

  • V poli checks definujú testy a ich úroveň kritickosti. Pretože je žiaduce dostávať upozornenie, keď obraz pochádza z nedôveryhodného zdroja, nastavíme tu úroveň danger.
  • Samotný test checkImageRepo následne sa zapíše v objekte customChecks.

Uložte súbor ako custom_check.yaml. Teraz môžeme spustiť polaris audit s YAML manifestom, ktorý vyžaduje overenie.

Otestujme náš manifest base-valid.yaml:

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

Tím polaris audit vykonal iba vlastný test, ako je uvedené vyššie, a ten sa neuskutočnil úspešne.

Ak opravíte obraz na my-company.com/http-echo:1.0, Polaris prejde úspešne. Manifest so zmenami už existuje v repozitári, takže môžete overiť predchádzajúcu príkazovú štruktúru s manifestom image-valid-mycompany.yaml.

Teraz vzniká otázka: ako spúšťať vstavané testy spolu s vlastnými? Je to jednoduché! Stačí pridať identifikátory vstavaných testov do konfiguračného súboru. Ako výsledok získa nasledujúci tvar:

kontroly:
  cpuRequestsMissing: varovanie
  cpuLimitsMissing: varovanie
  # Iné vstavané kontroly..
  # ..
  # vlastné kontroly
  checkImageRepo: nebezpečenstvo # !!!
vlastnéKontroly:
  checkImageRepo:        # !!!
    successMessage: Registrácia obrázkov je platná
    failureMessage: Registrácia obrázkov nie je platná
    category: Obrázky
    target: Kontejner
    schema:
      '$schema': http://json-schema.org/draft-07/schema
      type: object
      properties:
        image:
          type: string
          pattern: ^my-company.com/.+$

(config_with_custom_check.yaml)

Príklad kompletného konfiguračného súboru je k dispozícii tu.

Skontrolovať manifest base-valid.yaml, pomocou vstavaných a vlastných testov, je možné pomocou príkazu:

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

Polaris dopĺňa vstavané testy o vlastné, čím kombinuje to najlepšie z oboch svetov.

Na druhej strane, nemožnosť využívať silnejšie jazyky, ako sú Rego alebo JavaScript, môže byť obmedzujúcim faktorom pri vytváraní zložitejších testov.

Ďalšie informácie o Polari sú dostupné na webovej stránke projektu.

Zhrnutie

Hoci existuje množstvo nástrojov na kontrolu a vyhodnocovanie YAML súborov Kubernetes, je dôležité mať jasnú predstavu o tom, ako budú testy navrhnuté a vykonávané.

Napríklad, ak vezmeme manifesty Kubernetes prechádzajúce cez pipeline, kubeval by mohol byť prvým krokom v takom pipeline. Sledoval by, či definície objektov zodpovedajú schéme API Kubernetes.

Po dokončení takejto kontroly by bolo možné prejsť na zložitejšie testy, ako je zhoda so štandardnými najlepšími praktikami a špecifickými politikami. A tu by sa zídu kube-score a Polaris.

Pre tých, ktorí majú zložité požiadavky a potrebujú podrobne nastaviť testy, sú vhodné nástroje ako copper, config-lint a conftest.

Conftest a config-lint používajú YAML na definovanie vlastných testov, zatiaľ čo copper poskytuje prístup k plnohodnotnému programovaciemu jazyku, čo z neho robí veľmi atraktívnu voľbu.

Na druhej strane, má zmysel použiť jeden z týchto nástrojov a teda vytvoriť všetky testy manuálne, alebo radšej využiť Polaris a dopísať do neho iba to, čo potrebujete? Na túto otázku neexistuje jednoznačná odpoveď.

Tabuľa nižšie obsahuje stručný popis každého nástroja:

Nástroj
Účel
Nevýhody
Vlastné testy

kubeval
Kontroluje YAML manifesty, aby zodpovedali určitej verzii schémy API
Nedokáže pracovať s CRD
Nie

kube-score
Analyzuje YAML manifesty na zhode so najlepšími praktikami
Nie je možné vybrať vlastnú verziu API Kubernetes na kontrolu zdrojov
Nie

copper
Spoločný rámec na vytváranie vlastných JavaScript testov pre YAML manifesty
Žiadne vstavané testy. Chudobná dokumentácia
Áno

config-lint
Spoločný rámec na vytváranie testov v predmetovo orientovanom jazyku zabudovanom v YAML. Podporuje rôzne formáty konfigurácií (napr. Terraform)
Žiadne pripravené testy. Môže byť nedostatočný počet vstavaných assertions a funkcií
Áno

conftest
Rámec na vytváranie vlastných testov v Rego (špecializovanom jazyku dotazov). Umožňuje zdieľať politiky cez OCI balíčky
Žiadne vstavané testy. Je potrebné študovať Rego. Docker Hub nie je podporovaný pri publikovaní politík
Áno

Polaris
Analyzuje YAML manifesty na súlad so štandardnými najlepšími praktikami. Umožňuje vytvárať vlastné testy pomocou JSON schémy
Možností testov založených na JSON schéme môže byť málo
Áno

Keďže tieto nástroje nezávisia od prístupu do Kubernetes klastera, je ich ľahké inštalovať. Umožňujú filtrovať zdrojové súbory a poskytujú rýchlu spätnú väzbu autorom pull requestov v projektoch.

P.S. od prekladateľa

Prečítajte si tiež na našom blogu:

Zdroj: habr.com

Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Kúpte si spoľahlivý hosting pre webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster