Valideu Kubernetes YAML amb les millors pràctiques i polítiques

Nota. transl.: Amb el nombre creixent de configuracions YAML per a entorns K8s, la necessitat de la seva verificació automatitzada es fa cada cop més urgent. L'autor d'aquesta revisió no només va seleccionar les solucions existents per a aquesta tasca, sinó que també va examinar com funcionen utilitzant el desplegament com a exemple. Va resultar ser molt informatiu per a aquells que estiguin interessats en aquest tema.

Valideu Kubernetes YAML amb les millors pràctiques i polítiques

TL; DR: aquest article compara sis eines estàtiques per validar i avaluar fitxers YAML de Kubernetes amb les millors pràctiques i requisits.

Les càrregues de treball de Kubernetes normalment es defineixen en forma de documents YAML. Un dels problemes de YAML és la dificultat d'especificar restriccions o relacions entre fitxers de manifest.

Què passa si ens hem d'assegurar que totes les imatges desplegades al clúster provenen d'un registre de confiança?

Com puc evitar que els desplegaments que no tinguin PodDisruptionBudgets s'enviïn al clúster?

La integració de proves estàtiques us permet identificar errors i infraccions de polítiques en l'etapa de desenvolupament. Això augmenta la garantia que les definicions de recursos són correctes i segures, i fa més probable que les càrregues de treball de producció segueixin les pràctiques recomanades.

L'ecosistema d'inspecció de fitxers YAML estàtic de Kubernetes es pot dividir en les categories següents:

  • Validadors d'API. Les eines d'aquesta categoria comproven el manifest YAML amb els requisits del servidor de l'API de Kubernetes.
  • Provadors preparats. Les eines d'aquesta categoria inclouen proves preparades per a la seguretat, el compliment de les millors pràctiques, etc.
  • Validadors personalitzats. Els representants d'aquesta categoria us permeten crear proves personalitzades en diversos idiomes, per exemple, Rego i Javascript.

En aquest article descriurem i compararem sis eines diferents:

  1. kubeval;
  2. Kube-puntuació;
  3. config-lint;
  4. coure;
  5. concurs;
  6. polaris.

Bé, comencem!

Comprovació de desplegaments

Abans de començar a comparar eines, creem uns antecedents per provar-les.

El manifest següent conté una sèrie d'errors i incompliments de bones pràctiques: quants d'ells en podeu trobar?

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)

Utilitzarem aquest YAML per comparar diferents eines.

El manifest anterior base-valid.yaml i altres manifestos d'aquest article es poden trobar a Repositoris Git.

El manifest descriu una aplicació web la tasca principal de la qual és respondre amb un missatge "Hola món" al port 5678. Es pot desplegar amb l'ordre següent:

kubectl apply -f hello-world.yaml

I així, comproveu el treball:

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

Ara ves a http://localhost:8080 i confirmeu que l'aplicació funciona. Però segueix les millors pràctiques? Comprovem.

1. Kubeval

A la base kubeval La idea és que qualsevol interacció amb Kubernetes es produeix a través de la seva API REST. En altres paraules, podeu utilitzar un esquema d'API per comprovar si un determinat YAML s'ajusta a ell. Vegem-ne un exemple.

Instruccions d'instal · lació kubeval estan disponibles al lloc web del projecte.

En el moment d'escriure l'article original, estava disponible la versió 0.15.0.

Un cop instal·lat, anem a alimentar-lo amb el manifest anterior:

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

Si té èxit, kubeval sortirà amb el codi de sortida 0. Podeu comprovar-ho de la següent manera:

$ echo $?
0

Provem ara kubeval amb un manifest diferent:

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)

Pots detectar el problema a ull? Llançarem:

$ 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

El recurs no s'està verificant.

Desplegaments mitjançant la versió de l'API apps/v1, ha d'incloure un selector corresponent a l'etiqueta del pod. El manifest anterior no inclou el selector, de manera que kubeval ha informat d'un error i ha sortit amb un codi diferent de zero.

Em pregunto què passarà si ho faig kubectl apply -f amb aquest manifest?

Bé, provem:

$ 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

Aquest és exactament l'error del qual va advertir kubeval. Podeu solucionar-ho afegint un selector:

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)

L'avantatge d'eines com kubeval és que errors com aquests es poden detectar al principi del cicle de desplegament.

A més, aquestes comprovacions no requereixen accés al clúster; es poden realitzar fora de línia.

De manera predeterminada, kubeval comprova els recursos amb l'últim esquema de l'API de Kubernetes. Tanmateix, en la majoria dels casos, és possible que hàgiu de comprovar amb una versió específica de Kubernetes. Això es pot fer amb la bandera --kubernetes-version:

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

Tingueu en compte que la versió s'ha d'especificar al format Major.Minor.Patch.

Per obtenir una llista de versions per a les quals s'admet la verificació, consulteu Esquema JSON a GitHub, que kubeval utilitza per a la validació. Si heu d'executar kubeval fora de línia, descarregueu els esquemes i especifiqueu la seva ubicació local mitjançant la marca --schema-location.

A més dels fitxers YAML individuals, kubeval també pot funcionar amb directoris i stdin.

A més, Kubeval s'integra fàcilment al pipeline CI. Aquells que vulguin fer proves abans d'enviar manifests al clúster estaran encantats de saber que kubeval admet tres formats de sortida:

  1. Text simple;
  2. JSON;
  3. Prova qualsevol cosa (TAP).

I qualsevol dels formats es pot utilitzar per a una anàlisi posterior de la sortida per generar un resum dels resultats del tipus desitjat.

Un dels inconvenients de kubeval és que actualment no pot comprovar el compliment de les definicions de recursos personalitzades (CRD). Tanmateix, és possible configurar kubeval ignorar-los.

Kubeval és una gran eina per comprovar i avaluar recursos; Tanmateix, cal destacar que la superació de la prova no garanteix que el recurs compleixi les millors pràctiques.

Per exemple, utilitzant l'etiqueta latest en un contenidor no segueix les millors pràctiques. Tanmateix, kubeval no ho considera un error i no ho informa. És a dir, la verificació d'aquest YAML es completarà sense avisos.

Però què passa si voleu avaluar YAML i identificar infraccions com l'etiqueta latest? Com puc comprovar un fitxer YAML amb les millors pràctiques?

2. Kube-puntuació

Kube-puntuació analitza els manifests YAML i els avalua en comparació amb les proves integrades. Aquestes proves es seleccionen en funció de les directrius de seguretat i de les millors pràctiques, com ara:

  • Executant el contenidor com a usuari no root.
  • Disponibilitat de controls de salut de les pods.
  • Establiment de peticions i límits de recursos.

A partir dels resultats de la prova, es donen tres resultats: OK, ADVERTÈNCIA и CRÍTIC.

Podeu provar Kube-score en línia o instal·lar-lo localment.

En el moment d'escriure l'article original, l'última versió de kube-score era la 1.7.0.

Provem-ho al nostre manifest 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 passa les proves de kubeval, mentre que kube-score apunta als següents defectes:

  • Les comprovacions de preparació no estan configurades.
  • No hi ha sol·licituds ni límits per als recursos de la CPU i la memòria.
  • No s'especifiquen els pressupostos d'interrupció del pod.
  • No hi ha regles de separació (antiafinitat) per maximitzar la disponibilitat.
  • El contenidor s'executa com a root.

Tots aquests són punts vàlids sobre les mancances que s'han de solucionar per fer que el desplegament sigui més eficient i fiable.

Equip kube-score mostra informació en forma llegible pels humans, incloses totes les infraccions de tipus ADVERTÈNCIA и CRÍTIC, que ajuda molt durant el desenvolupament.

Aquells que vulguin utilitzar aquesta eina dins del pipeline CI poden habilitar una sortida més comprimida mitjançant el senyalador --output-format ci (en aquest cas, també es mostren les proves amb el resultat 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

Similar a kubeval, kube-score retorna un codi de sortida diferent de zero quan hi ha una prova que falla CRÍTIC. També podeu habilitar un processament similar per a ADVERTÈNCIA.

A més, és possible comprovar el compliment dels recursos amb les diferents versions de l'API (com a kubeval). Tanmateix, aquesta informació està codificada en el propi Kube-score: no podeu seleccionar una versió diferent de Kubernetes. Aquesta limitació pot ser un gran problema si teniu intenció d'actualitzar el vostre clúster o si teniu diversos clústers amb diferents versions de K8s.

Tingueu en compte que ja hi ha un problema amb una proposta per aprofitar aquesta oportunitat.

Podeu trobar més informació sobre kube-score a lloc web oficial.

Les proves de puntuació de Kube són una eina fantàstica per implementar les millors pràctiques, però què passa si necessiteu fer canvis a la prova o afegir les vostres pròpies regles? Per desgràcia, això no es pot fer.

Kube-score no és extensible: no hi podeu afegir polítiques ni ajustar-les.

Si necessiteu escriure proves personalitzades per verificar el compliment de les polítiques de l'empresa, podeu utilitzar una de les quatre eines següents: config-lint, copper, conftest o polaris.

3.Config-lint

Config-lint és una eina per validar fitxers de configuració YAML, JSON, Terraform, CSV i manifests de Kubernetes.

Podeu instal·lar-lo utilitzant instruccions al web del projecte.

La versió actual en el moment d'escriure l'article original és la 1.5.0.

Config-lint no té proves integrades per validar els manifests de Kubernetes.

Per dur a terme qualsevol prova, cal crear les regles adequades. Estan escrits en fitxers YAML anomenats "rulesets" (regles), i tenen la següent estructura:

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

(rule.yaml)

Estudiem-ho més de prop:

  • Camp type especifica quin tipus de configuració utilitzarà config-lint. Per als K8 manifestes això és sempre Kubernetes.
  • En camp files A més dels fitxers en si, podeu especificar un directori.
  • Camp rules destinat a establir proves d'usuari.

Suposem que voleu assegurar-vos que les imatges de Deployment sempre es baixin d'un dipòsit de confiança com ara my-company.com/myapp:1.0. Una regla de config-lint que realitza aquesta comprovació seria així:

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

Cada regla ha de tenir els atributs següents:

  • id — identificador únic de la regla;
  • severity - Pot ser FALLA, ADVERTÈNCIA и NO_COMPLIENT;
  • message — si es viola una regla, es mostra el contingut d'aquesta línia;
  • resource — el tipus de recurs al qual s'aplica aquesta regla;
  • assertions — una relació de condicions que s'avaluaran en relació amb aquest recurs.

En la regla anterior assertion anomenat every comprova que tots els contenidors del desplegament (key: spec.templates.spec.containers) utilitzar imatges de confiança (és a dir, començant per my-company.com/).

El conjunt de regles complet té aquest aspecte:

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)

Per provar la prova, desem-la com a check_image_repo.yaml. Anem a comprovar el fitxer 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 comprovació ha fallat. Ara mirem el següent manifest amb el dipòsit d'imatges correcte:

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)

Fem la mateixa prova amb el manifest anterior. No s'han trobat problemes:

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

Config-lint és un marc prometedor que us permet crear les vostres pròpies proves per validar els manifests YAML de Kubernetes mitjançant el DSL YAML.

Però, què passa si necessiteu una lògica i proves més complexes? No és YAML massa limitat per a això? Què passaria si poguéssiu crear proves en un llenguatge de programació complet?

4. Coure

Coure V2 és un marc per validar manifests mitjançant proves personalitzades (similar a config-lint).

Tanmateix, es diferencia d'aquest últim perquè no utilitza YAML per descriure proves. Les proves es poden escriure en JavaScript. Copper proporciona una biblioteca amb diverses eines bàsiques, que us ajuden a llegir informació sobre objectes de Kubernetes i informar d'errors.

Els passos per instal·lar el coure es poden trobar a documentació oficial.

2.0.1 és l'última versió d'aquesta utilitat en el moment d'escriure l'article original.

Igual que config-lint, Copper no té proves integrades. Escrivim-ne un. Deixeu-lo comprovar que els desplegaments utilitzen imatges de contenidors exclusivament de dipòsits de confiança com my-company.com.

Creeu un fitxer check_image_repo.js amb el següent contingut:

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

Ara a provar el nostre manifest base-valid.yaml, utilitzeu l'ordre 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

És evident que amb l'ajuda del coure podeu realitzar proves més complexes, per exemple, comprovar els noms de domini als manifestos d'Ingress o rebutjar pods que s'executen en mode privilegiat.

El coure té diverses funcions d'utilitat incorporades:

  • DockerImage llegeix el fitxer d'entrada especificat i crea un objecte amb els atributs següents:
    • name - nom de la imatge,
    • tag - etiqueta d'imatge,
    • registry - Registre d'imatges,
    • registry_url - protocol (https://) i registre d'imatges,
    • fqin — Ubicació completa de la imatge.
  • Funció findByName ajuda a trobar un recurs per un tipus determinat (kind) i nom (name) del fitxer d'entrada.
  • Funció findByLabels ajuda a trobar un recurs per un tipus especificat (kind) i etiquetes (labels).

Podeu veure totes les funcions de servei disponibles aquí.

Per defecte, carrega tot el fitxer YAML d'entrada en una variable $$ i el fa disponible per a la creació d'scripts (una tècnica familiar per a aquells amb experiència en jQuery).

El principal avantatge de Copper és evident: no cal dominar un llenguatge especialitzat i podeu utilitzar diverses funcions de JavaScript per crear les vostres pròpies proves, com ara interpolació de cadenes, funcions, etc.

També cal tenir en compte que la versió actual de Copper funciona amb la versió ES5 del motor JavaScript, no amb ES6.

Detalls disponibles a web oficial del projecte.

Tanmateix, si no us agrada molt JavaScript i preferiu un llenguatge dissenyat específicament per crear consultes i descriure polítiques, hauríeu de prestar atenció al concurs.

5.Concurs

Conftest és un marc per provar les dades de configuració. També és adequat per provar/verificar manifests de Kubernetes. Les proves es descriuen utilitzant un llenguatge de consulta especialitzat Rego.

Podeu instal·lar el concurs utilitzant instruccionsllistat a la pàgina web del projecte.

En el moment d'escriure l'article original, l'última versió disponible era la 0.18.2.

Similar a config-lint i coure, conftest arriba sense cap prova integrada. Provem-ho i escrivim la nostra pròpia política. Com en els exemples anteriors, comprovarem si les imatges del contenidor provenen d'una font fiable.

Crea un directori conftest-checks, i hi ha un fitxer anomenat check_image_registry.rego amb el següent contingut:

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

Ara anem a provar base-valid.yaml a través d' 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

Com era previsible, la prova va fallar perquè les imatges provenien d'una font no fiable.

Al fitxer Rego definim el bloc deny. La seva veritat es considera una violació. Si blocs deny diversos, el concurs els verifica independentment l'un de l'altre, i la veritat de qualsevol dels blocs es tracta com una violació.

A més de la sortida predeterminada, conftest admet el format JSON, TAP i taula, una característica extremadament útil si necessiteu incrustar informes en un pipeline CI existent. Podeu definir el format desitjat mitjançant la bandera --output.

Per facilitar la depuració de polítiques, el concurs té una bandera --trace. Emet un rastre de com conftest analitza els fitxers de polítiques especificats.

Les polítiques del concurs es poden publicar i compartir als registres OCI (Open Container Initiative) com a artefactes.

Equips push и pull permeten publicar un artefacte o recuperar un artefacte existent d'un registre remot. Provem de publicar la política que hem creat al registre local de Docker conftest push.

Inicieu el vostre registre Docker local:

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

En un altre terminal, aneu al directori que heu creat anteriorment conftest-checks i executeu l'ordre següent:

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

Si l'ordre ha tingut èxit, veureu un missatge com aquest:

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

Ara creeu un directori temporal i executeu-hi l'ordre conftest pull. Es descarregarà el paquet creat per l'ordre anterior:

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

Apareixerà un subdirectori al directori temporal policyque conté el nostre fitxer de polítiques:

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

Les proves es poden executar directament des del repositori:

$ 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

Malauradament, DockerHub encara no és compatible. Així que considereu-vos afortunat si feu servir Azure Container Registry (ACR) o el vostre propi registre.

El format de l'artefacte és el mateix que Obriu els paquets de Policy Agent (OPA), que us permet utilitzar conftest per executar proves dels paquets OPA existents.

Podeu obtenir més informació sobre la compartició de polítiques i altres funcions del concurs a web oficial del projecte.

6. estrella polar

L'última eina que es tractarà en aquest article és Estrella polar. (El seu anunci de l'any passat nosaltres ja traduït - aprox. transl.)

Polaris es pot instal·lar en un clúster o utilitzar-se en mode de línia d'ordres. Com haureu endevinat, us permet analitzar estàticament els manifests de Kubernetes.

Quan s'executen en mode de línia d'ordres, hi ha proves integrades disponibles que cobreixen àrees com ara la seguretat i les pràctiques recomanades (similar al kube-score). A més, podeu crear les vostres pròpies proves (com a config-lint, copper i conftest).

En altres paraules, Polaris combina els avantatges de les dues categories d'eines: amb proves integrades i personalitzades.

Per instal·lar Polaris en mode de línia d'ordres, feu servir instruccions a la pàgina web del projecte.

En el moment d'escriure l'article original, la versió 1.0.3 està disponible.

Un cop finalitzada la instal·lació, podeu executar polaris al manifest base-valid.yaml amb la següent comanda:

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

Emetrà una cadena en format JSON amb una descripció detallada de les proves realitzades i els seus resultats. La sortida tindrà la següent estructura:

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

Sortida completa disponible aquí.

Igual que kube-score, Polaris identifica problemes en àrees on el manifest no compleix les pràctiques recomanades:

  • No hi ha controls de salut per a les beines.
  • No s'especifiquen les etiquetes per a les imatges dels contenidors.
  • El contenidor s'executa com a root.
  • No s'especifiquen les sol·licituds i els límits de memòria i CPU.

A cada prova, en funció dels seus resultats, se li assigna un grau de criticitat: advertència o perill. Per obtenir més informació sobre les proves integrades disponibles, consulteu documentació.

Si no calen detalls, podeu especificar la bandera --format score. En aquest cas, Polaris sortirà un nombre que va de l'1 al 100 - puntuació (és a dir, avaluació):

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

Com més a prop estigui la puntuació de 100, més gran serà el grau d'acord. Si comproveu el codi de sortida de l'ordre polaris audit, resulta que és igual a 0.

Força polaris audit Podeu finalitzar el treball amb codi diferent de zero utilitzant dos indicadors:

  • Bandera --set-exit-code-below-score pren com a argument un valor llindar en el rang 1-100. En aquest cas, l'ordre sortirà amb el codi de sortida 4 si la puntuació està per sota del llindar. Això és molt útil quan teniu un determinat valor llindar (per exemple, 75) i necessiteu rebre una alerta si la puntuació baixa.
  • Bandera --set-exit-code-on-danger farà que l'ordre falli amb el codi 3 si falla una de les proves de perill.

Ara intentem crear una prova personalitzada que comprove si la imatge s'ha tret d'un dipòsit de confiança. Les proves personalitzades s'especifiquen en format YAML i la prova en si es descriu mitjançant l'esquema JSON.

El següent fragment de codi YAML descriu una prova nova anomenada 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/.+$

Mirem-ho més de prop:

  • successMessage — aquesta línia s'imprimirà si la prova finalitza amb èxit;
  • failureMessage — aquest missatge es mostrarà en cas de fallada;
  • category — indica una de les categories: Images, Health Checks, Security, Networking и Resources;
  • target--- determina quin tipus d'objecte (spec) s'aplica la prova. Valors possibles: Container, Pod o Controller;
  • La prova en si s'especifica a l'objecte schema utilitzant l'esquema JSON. La paraula clau d'aquesta prova és pattern s'utilitza per comparar la font de la imatge amb la necessària.

Per executar la prova anterior, heu de crear la següent configuració de 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)

Analitzem el fitxer:

  • En camp checks es prescriuen proves i el seu nivell de criticitat. Com que és desitjable rebre un avís quan es pren una imatge d'una font no fiable, establim el nivell aquí danger.
  • La prova en si checkImageRepo després registrat a l'objecte customChecks.

Desa el fitxer com a custom_check.yaml. Ara pots córrer polaris audit amb un manifest YAML que requereix verificació.

Posem a prova el nostre manifest base-valid.yaml:

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

Equip polaris audit només va executar la prova d'usuari especificada anteriorment i va fallar.

Si arregleu la imatge a my-company.com/http-echo:1.0, Polaris es completarà correctament. El manifest amb els canvis ja és repositorisde manera que podeu comprovar l'ordre anterior al manifest image-valid-mycompany.yaml.

Ara sorgeix la pregunta: com executar proves integrades juntament amb les personalitzades? Fàcilment! Només cal que afegiu els identificadors de prova integrats al fitxer de configuració. Com a resultat, tindrà la forma següent:

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)

Hi ha disponible un exemple d'un fitxer de configuració complet aquí.

Comproveu el manifest base-valid.yamlutilitzant proves integrades i personalitzades, podeu utilitzar l'ordre:

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

Polaris complementa les proves integrades amb altres personalitzades, combinant així el millor dels dos mons.

D'altra banda, la incapacitat d'utilitzar llenguatges més potents com Rego o JavaScript pot ser un factor limitant impedint la creació de proves més sofisticades.

Més informació sobre Polaris està disponible a web del projecte.

Resum

Tot i que hi ha moltes eines disponibles per inspeccionar i avaluar fitxers YAML de Kubernetes, és important tenir una comprensió clara de com es dissenyaran i executaran les proves.

Per exemple, si agafeu manifests de Kubernetes passant per un pipeline, kubeval podria ser el primer pas en aquest pipeline. Supervisaria si les definicions d'objectes s'ajusten a l'esquema de l'API de Kubernetes.

Un cop finalitzada aquesta revisió, es podria passar a proves més sofisticades, com ara el compliment de les millors pràctiques estàndard i polítiques específiques. Aquí és on kube-score i Polaris serien útils.

Per a aquells que tinguin requisits complexos i necessiten personalitzar les proves amb detall, el coure, la configuració-lint i el concurs serien adequats.

Conftest i config-lint utilitzen YAML per definir proves personalitzades, i el coure us dóna accés a un llenguatge de programació complet, cosa que la converteix en una opció força atractiva.

D'altra banda, val la pena utilitzar alguna d'aquestes eines i, per tant, crear totes les proves manualment, o preferir Polaris i afegir-hi només el que calgui? No hi ha una resposta clara a aquesta pregunta.

La taula següent ofereix una breu descripció de cada eina:

Eina
Propòsit
Limitacions
Proves d'usuari

kubeval
Valida els manifests YAML amb una versió específica de l'esquema de l'API
No es pot treballar amb CRD
No

Kube-puntuació
Analitza els manifestos de YAML amb les millors pràctiques
No es pot seleccionar la versió de l'API de Kubernetes per comprovar els recursos
No

de coure
Un marc general per crear proves de JavaScript personalitzades per a manifests YAML
No hi ha proves integrades. Poca documentació

config-lint
Un marc general per crear proves en un llenguatge específic del domini incrustat a YAML. Admet diversos formats de configuració (per exemple, Terraform)
No hi ha proves preparades. Les afirmacions i funcions integrades poden no ser suficients

concurs
Un marc per crear les vostres pròpies proves amb Rego (un llenguatge de consulta especialitzat). Permet compartir polítiques mitjançant paquets OCI
No hi ha proves integrades. He d'aprendre Rego. Docker Hub no s'admet quan es publiquen polítiques

Estrella polar
Revisa els manifestos de YAML amb les pràctiques recomanades estàndard. Us permet crear les vostres pròpies proves mitjançant l'esquema JSON
Les capacitats de prova basades en l'esquema JSON poden no ser suficients

Com que aquestes eines no depenen de l'accés al clúster de Kubernetes, són fàcils d'instal·lar. Us permeten filtrar fitxers font i proporcionar comentaris ràpids als autors de les sol·licituds d'extracció dels projectes.

PS del traductor

Llegeix també al nostre blog:

Font: www.habr.com

Afegeix comentari