Enmilocalfunciona

Thoughts, stories and ideas.

DevSecOps - Herramientas de automatización de análisis de código estático y aplicación de buenas prácticas en Kubernetes

Publicado por Manuel García de Vinuesa Gómez el

DevOpsDevSecOpsKubernetesToolsBest PracticesAutomatizaciónCalidadAnálisis de Código Estático

Introducción

En el siguiente artículo vamos a revisar distintas herramientas que nos van a permitir introducir capacidades de validación tanto técnica como funcional sobre nuestro código estático de Kubernetes, es decir, validar que los componentes que vamos a desplegar en nuestro clúster estén acordes con la especificación de Kubernetes e incluso cumplan una serie de buenas prácticas y recomendaciones a la hora de definirlos.

cabecera - Enmilocalfunciona - DevSecOps - 1400x400px.jpg

La idea tras esto es añadir validaciones tempranas a nuestros circuitos de despliegue, así como dar robustez y seguridad a nuestra solución antes de que esta sea desplegada. Estas capacidades se integran dentro lo que se conoce como DevSecOps, en concreto en SAST (static application security testing) ya que en muchos casos dichas políticas nos incrementan la seguridad de nuestros componentes.

Este tipo de herramientas se engloban en tres (cuatro) grandes grupos:

  1. Validaciones basadas en API, es decir, validan que los objetos definidos cumplan la especificación o esquemas de los propios objetos. Así como control de versiones deprecadas.
  2. Validaciones basadas en reglas predefinidas, las herramientas, siguiendo un criterio subjetivo, aunque consensuado con el mercado o la comunidad, han definido una serie de reglas o checks que deben pasar nuestros objetos.
  3. Creación de test o reglas customizables, dichas herramientas nos dan la capacidad de crear reglas específicas sobre nuestras fuentes de código estático.
  4. Combinación de alguna de las anteriores, existen algunas herramientas que nos ofrecen capacidades combinadas de las anteriores.

Criterios de comparación

Hay muchísimas herramientas que nos van a permitir realizar estas validaciones, elegir la que más se adapte a nuestras necesidades dependerá del caso de uso, pero también de otras variables. En este post vamos a intentar dar una visión completa de unas cuantas. Como curiosidad, en el proyecto de Kubetools Github puedes encontrar un listado de herramientas similar en el apartado de seguridad.

Pero antes de esto, lo primero que vamos a definir son los criterios que vamos a usar para comparar y poder elegir la herramienta que más se adapte a nuestras necesidades.

  • Licencia, en este caso vamos a buscar solo herramientas OpenSource, pero existen stacks asociados al mundo de DevOps que nos pueden ofrecer dichas capacidades, eso sí, a un coste.

  • Al hablar de Open Source, tenemos que evaluar sí o sí el soporte que puede recibir dicha herramienta de la comunidad, en este caso lo que vamos a medir son los siguientes valores englobados en "Community Support":

    github.png

    • Número de estrellas en el repositorio de github, cómo de popular es la herramienta
    • Estadísticas de trabajo sobre dicho repositorio, para evaluar si es un proyecto que sigue vivo, está en stand-by... en este caso:
      • Número de forks

      • Número de Watchs

      • Número de ficheros modificados en el último mes.

        pulso.png

  • Instalación, lo fácil o difícil que es tenerlo instalado en local o en nuestros circuitos de CI/CD. Así como el soporte multiplataforma.

  • Tipo de herramienta (API o Reglas) y número de las mismas.

  • Capacidad de integración con distintas herramientas y extensibilidad, por ejemplo, si nuestro código de kubernetes se gestiona mediante helm o kustomize o si queremos crear nuestras propias reglas.

  • Usabilidad y feedback, como de sencillo es ejecutar dicha herramienta y como nos muestra los resultados.

Código a validar

A la hora de realizar las pruebas, las realizaremos siempre sobre el mismo código, añadiendo o modificando ciertos componentes con el objetivo de validar cada una de las herramientas.

Dicho código se ha generado con helm con el objetivo de facilitar la generación de diferentes componentes básicos que puede llevar cualquier elemento a desplegar en un clúster.

helm create example-chart

El comando nos generará la siguiente estructura

helm_output.png

El contenido de dichos ficheros no es código final de kubernetes, sino una plantilla parametrizable, ejemplo:

{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
  name: {{ include "example-chart.serviceAccountName" . }}
  labels:
    {{- include "example-chart.labels" . | nindent 4 }}
  {{- with .Values.serviceAccount.annotations }}
  annotations:
    {{- toYaml . | nindent 4 }}
  {{- end }}
{{- end }}

Si no tienes conocimiento de helm, no te preocupes, lo único que hemos generado es una plantilla base con la que se creará el código definitivo, la potencia de helm es que nos va a permitir parametrizar dichas plantillas, aplicarle su propio ciclo de vida y gestionar releases asociadas a ellas, pero en este artículo no va a ser necesario saber prácticamente nada de esta herramienta.

Para generar el contenido asociado a dicha plantilla bastaría con ejecutar:

helm template example-chart/ --output-dir ./k8

Dicho comando puede ser parametrizado con valores que aplicarán reglas dentro de la plantilla, dichos valores pueden ser informados a través de un fichero o de la propia línea de comandos. En nuestro caso vamos a parametrizar el comando para que nos genere todos los componentes posibles.

helm template example-chart/ --set-string ingress.enabled=true --set-string autoscaling.enabled=true --output-dir ./k8

Y ahora sí tendríamos el código estático de kubernetes completo, ejemplo:

helm_output_2.png
---
# Source: example-chart/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: release-name-example-chart
  labels:
    helm.sh/chart: example-chart-0.1.0
    app.kubernetes.io/name: example-chart
    app.kubernetes.io/instance: release-name
    app.kubernetes.io/version: "1.16.0"
    app.kubernetes.io/managed-by: Helm

Además, al trabajar con helm nos va a ayudar a conocer si las herramientas que vamos a evaluar soportan este tipo de integraciones.

Dicho código generado lo podéis descargar de aquí.

Herramientas

KubeVal y ahora KubeConform

Dichas herramientas se agruparían en Validaciones basadas en API

Herramienta Tipo Web Github Licencia Stars Watchs Commits
KubeVal API/Schema Validator https://www.kubeval.com/ https://github.com/instrumenta/kubeval Apache License, Version 2.0 3.1k 27 0 (desmantenido)
KubeConform API/Schema Validator https://github.com/yannh/kubeconform Apache License, Version 2.0 1.5k 4 5

KubeVal ha sido una herramienta muy popular en lo que se refiere a las validaciones de código estático, pero es un proyecto que actualmente está desmantenido. En el propio proyecto nos derivan a kubeconform como heredero natural.

En este caso no vamos a evaluar Kubeval y nos vamos a centrar en kubeconform. Tal y como ellos mismos describen es una herramienta de validación de los ficheros manifest de kubernetes. Esta herramienta es interesante ya que nos va a permitir validar schemas básicos de Kubernetes (Deployment, Service...) junto con CRD (Custom Resources Definitions) y además nos garantiza que siempre vamos a trabajar con las ultimas versiones de dichos schemas.

Limitaciones
Ellos mismos explican cual es su principal limitación:

Kubeconform, similar to kubeval, only validates manifests using the official Kubernetes OpenAPI specifications. The Kubernetes controllers still perform additional server-side validations that are not part of the OpenAPI specifications

Instalación
Diferentes capacidades de instalación, con soporte a Windows, Linux y macOS. Ofrece imagen docker para su ejecución. En el caso de usar Linux o macOS siempre es recomendable usar Homebrew

brew install kubeconform

Para más información revisar:

Uso
A nivel de comandos es bastante sencilla e intuitiva, podemos validar archivo a archivo o lanzarlo con un folder que contenga los ficheros de kubernetes.

manu@AT-5CD2144YCB:/mnt/c/Dev/github/mgvinuesa/kubefiles-checks-comparative$ kubeconform -summary -verbose  k8/
k8/example-chart/templates/service.yaml - Service release-name-example-chart is valid
k8/example-chart/templates/ingress.yaml - Ingress release-name-example-chart is valid
k8/example-chart/templates/hpa.yaml - HorizontalPodAutoscaler release-name-example-chart failed validation: could not find schema for HorizontalPodAutoscaler
k8/example-chart/templates/serviceaccount.yaml - ServiceAccount release-name-example-chart is valid
k8/example-chart/templates/deployment.yaml - Deployment release-name-example-chart is valid
Summary: 5 resources found in 5 files - Valid: 4, Invalid: 0, Errors: 1, Skipped: 0

En la salida anterior podemos ver un error,

k8/example-chart/templates/hpa.yaml - HorizontalPodAutoscaler release-name-example-chart failed validation: could not find schema for HorizontalPodAutoscaler

Ya que no encuentra el schema del objeto HorizontalPodAutoscaler, este error puede ocurrir por dos causas, el objeto (Kind+Version) que estamos definiendo no es core de Kubernetes (o la versión ya no existe). O necesitamos añadir un CDR.

En nuestro caso es la primera opción, ya que el HorizontalPodAutoscaler está definido como v2beta1 pero ya está disponible la versión v2.

Aplicando el cambio, y lanzando de nuevo el comando, encontramos un nuevo error:

manu@AT-5CD2144YCB:/mnt/c/Dev/github/mgvinuesa/kubefiles-checks-comparative$ kubeconform -summary -verbose  k8/
k8/example-chart/templates/service.yaml - Service release-name-example-chart is valid
k8/example-chart/templates/ingress.yaml - Ingress release-name-example-chart is valid
k8/example-chart/templates/serviceaccount.yaml - ServiceAccount release-name-example-chart is valid
k8/example-chart/templates/hpa.yaml - HorizontalPodAutoscaler release-name-example-chart is invalid: problem validating schema. Check JSON formatting: jsonschema: '/spec/metrics/0/resource' does not validate with https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/master-standalone/horizontalpodautoscaler-autoscaling-v2.json#/properties/spec/properties/metrics/items/properties/resource/required: missing properties: 'target'
k8/example-chart/templates/deployment.yaml - Deployment release-name-example-chart is valid
Summary: 5 resources found in 5 files - Valid: 4, Invalid: 1, Errors: 0, Skipped: 0

La definición no cumple la especificación, incluso nos ofrece un enlace para que revisemos la API, aunque siempre será más sencillo revisar la documentación oficial: https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/horizontal-pod-autoscaler-v2/#HorizontalPodAutoscalerSpec

En este caso al subir la versión debemos cambiar la definición de las métricas de esto:

  metrics:
    - type: Resource
      resource:
        name: cpu
        targetAverageUtilization: 80

A

  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          avergage: 80

IMPORTANTE: El código en el github está corregido. Por lo que es recomendable revisar los commits si quieres usarlo de base.

Como ya hemos explicado, el uso de CRD es compatible con kubeconform, por lo que podríamos validar los schemas. En nuestro caso vamos a incluir un ServiceMonitor para una posible integración con Prometheus.

La posible plantilla de helm podría ser algo parecido a esto:

{{- if or  (eq .Values.autoScaled.requestSecond.enabled true) (eq .Values.autoScaled.cxfSecond.enabled true) }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: {{ include "app.fullname" . }}
  namespace: "{{ .Values.namespace }}"
  labels:
    release: {{ .Values.prometheus.release }}
    app.kubernetes.io/name: {{ include "app.name" . }}
    helm.sh/chart: {{ include "app.chart" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}
     
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "app.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  endpoints:
  - port: http
    path: '/actuator/prometheus'
    interval: 10s
    honorLabels: true
{{- end }}

Para lanzar el comando,

helm template example-chart/ --set-string ingress.enabled=true --set-string autoscaling.enabled=true --set-string serviceMonitor.create=true --output-dir --debug k8/

Si volvemos lanzar kubeconform, nos volverá a dar el error relativo al schema no encontrado, pero en este caso viene dado porque es un CDR y no le informamos de la localización del schema.

k8/example-chart/templates/servicemonitor.yaml - ServiceMonitor release-name-example-chart failed validation: could not find schema for ServiceMonitor

Para incorporar el schema, modificamos el comando informándole de la ubicación del mismo, en este caso nos apoyamos en el proyecto https://github.com/datreeio/CRDs-catalog y añadimos los siguientes parámetros al comando

-schema-location default -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json'

IMPORTANTE, hay que añadir "default" en primera opción para que siga cogiendo las definiciones por defecto. Generando en este caso una respuesta correcta.

manu@AT-5CD2144YCB:/mnt/c/Dev/github/mgvinuesa/kubefiles-checks-comparative$ kubeconform -summary -verbose  -schema-location default -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json'  k8/
k8/example-chart/templates/service.yaml - Service release-name-example-chart is valid
k8/example-chart/templates/ingress.yaml - Ingress release-name-example-chart is valid
k8/example-chart/templates/hpa.yaml - HorizontalPodAutoscaler release-name-example-chart is valid
k8/example-chart/templates/serviceaccount.yaml - ServiceAccount release-name-example-chart is valid
k8/example-chart/templates/deployment.yaml - Deployment release-name-example-chart is valid
k8/example-chart/templates/servicemonitor.yaml - ServiceMonitor release-name-example-chart is valid
Summary: 6 resources found in 6 files - Valid: 6, Invalid: 0, Errors: 0, Skipped: 0

Conclusión

Kubeconform es una herramienta práctica para validar la composición de nuestros ficheros de kubernetes, lo más interesante es la capacidad de incluir CRDs en nuestras validaciones. Es sencilla de usar. Por contra podríamos considerar que no tiene integración nativa con herramientas que generan código de kubernetes como helm y kustomize, aunque en el primer caso si que hay desarrollado "extraoficialmente" un plugin de helm para integrarlo. Aun así, el paso previo (uso de helm template por ejemplo) no supone ninguna limitación.

Y por supuesto, debería ser complementada con otras herramientas de validación de buenas prácticas.

Kube-score

KubeScore se agruparía en Validaciones de reglas predefinidas

Herramienta Tipo Web Github Licencia Stars Watchs Commits
KubeScore Built-in rules https://kube-score.com/ https://github.com/zegl/kube-score MIT License 2.4k 22 6

Otra herramienta bastante popular, de hecho, Azure la recomienda dentro de sus prácticas de DevSecOps. Una herramienta muy sencilla que nos permite hacer una revisión rápida de un conjunto de buenas prácticas definidas por la propia aplicación.

Instalación

Como las anteriores, herramienta sencilla de instalar, y con soporte a Windows, Linux y macOS. Además, ofrece imagen docker para ejecutarla.

Para más información ver:

Uso
Sigue la dinámica de kubeconform, la ejecución es muy sencilla:

kube-score score k8/example-chart/templates/*yaml

Es interesante saber que permite la inyección de la información por stdin y nos permite ejecutar la validación con helm sin tener que volcar su contenido en un directorio:

helm template example-chart/ | kube-score score -

En este caso es importante revisar la lista de validaciones que se incluyen y que se lanzarán contra nuestro código, algunas de ellas son opcionales y tendríamos la capacidad de activarlas dentro de nuestro scan.

En este caso y a fecha de publicación existen 33 reglas, de las cuales 6 son opcionales y aplican a objetos como Deployment (Pod), Service, Ingress StatefulSet, NetworkPolicy, HPA...

Con el ejemplo de nuestro código aparecerían todas las siguientes recomendaciones a aplicar para mejorar nuestro código (lanzamos todas, incluidas las opcionales):

kubescore_output.png

No entra parte del objetivo de este blog analizar una a una las vulnerabilidades, pero siempre hay que considerar que son buenas prácticas subjetivas y que en algunos casos puede o no tener sentido aplicarlas.

Como particularidad interesante, podemos anotar nuestros recursos para ignorar las validaciones (por supuesto también desde línea de comandos)

annotations:
    kube-score/ignore: service-type

Y forzar validaciones que a dia de hoy son opcionales

annotations:
    kube-score/enable: container-seccomp-profile

Conclusiones
kube-score es una herramienta muy sencilla y práctica para aplicar dentro de nuestros circuitos, es fácil de comprender y usar y se podría considerar un quick-win dentro de nuestro proyecto. Al igual que kubeconform debe ser complementada, en este caso por una herramienta de validación de schema.

Como contra, no permite definir reglas customizadas, por lo que en cuanto nuestro proyecto trabaje con CRDs o queramos aplicar ciertas reglas más complejas se nos puede quedar corto. Por supuesto dependerá del caso de uso pero como punto de partida es una herramienta que merece la pena evaluar.

Kube-linter

KubeLinter se agruparía en Validaciones de reglas predefinidas

Herramienta Tipo Web Github Licencia Stars Watchs Commits
KubeLinter Built-in rules https://docs.kubelinter.io/ https://github.com/stackrox/kube-linter Apache 2.0 2.6k 35 13

Como la propia descripción de la herramienta dice:

KubeLinter analyzes Kubernetes YAML files and Helm charts, and checks them against a variety of best practices, with a focus on production readiness and security.

La principal diferencia con kube-score, es que: as well as create your own custom checks, depending on the policies you want to follow within your organization. Y además te suele ofrecer la solución al problema con ejemplos.

Instalación

Sigue la dinámica de las anteriores, soporte Linux, macOS y Windows. Imagen docker y además ofrece su propia Github Action stackrox/kube-linter-action@v1.

Para más información:

Uso
Kube-Linter es una herramienta más completa y "compleja" que kube-score, lo interesante de inicio es comparar las reglas o validaciones que lanza sobre el mismo código para comparar y poder evaluar qué herramienta tiene más sentido de usar en nuestro proyecto.

En este caso, deberemos lanzar kube-linter contra el Chart de helm o contra el código generado, la salvedad es que contra el Chart de helm no permite aun el uso de parametrización a través de "values", por lo que se queda un poco coja esta capacidad, aquí está el issue que pide dicha opción para la herramienta.

helm template example-chart/ --output-dir /tmp/chart -f values XXXXX; kube-linter lint /tmp/chart

kubeslinter_output.png

En este caso detecta 6 errores o mejoras frente a los 8 (+1 warning) de kubescore, antes de hacer la comparativa vamos a revisar el número total de checks que realiza kube-linter, para ello podemos ejecutar.

kube-linter checks list

O visitar la página https://docs.kubelinter.io/#/generated/checks. Existen 53 reglas (20 más que kubescore) de las cuales 26 son opcionales.

Dichas reglas abarcan más objetos que kube-score incluso ciertos CRD como ServiceMonitor.

Uso avanzado
Kube-linter ofrece ciertas capacidades de configuración que añaden a la herramienta cierta versatilidad, no llega a permitir crear cualquier tipo de validación, pero si ofrece una serie de "templates" que podemos parametrizar para validar nuestro código estático de una manera más personal.

Por ejemplo, si queremos validar que nuestros ficheros contengan una determinada anotación o una determinada label podemos añadir el siguiente bloque de código a un fichero de configuración, el cual usaremos en el momento de validar.

customChecks:
- name: "required-label-app"
  template: "required-label"
  params:
    key: "company"

Al lanzar el comando

kube-linter lint --config kubelinter-config.yaml ...

Aparecen las nuevas validaciones referidas a la nueva regla basada en la template, de required-label

custom_checks.png

Para ver todas las templates podéis visitar: https://docs.kubelinter.io/#/generated/templates o ejecutar el comando kube-linter templates list.

Conclusiones

Kube-Linter es un producto más potente que kube-score, lo que más me ha gustado es el concepto de templates, ya que nos permite personalizar nuestras validaciones. Además, ofrece un conjunto más amplio de reglas.

Kubevious

Kubevious es una suite, por lo que nos va a ofrecer distintas capacidades, de hecho no sólo ofrece un CLI, sino incluso un dashboard donde agrupar toda la información obtenida. En este artículo nos vamos a centrar en el CLI ya que es la herramienta que incluiríamos en nuestro stack de CICD.

Herramienta Tipo Web Github Licencia Stars Watchs Commits
Kubevious Mix https://kubevious.io/ https://github.com/kubevious/kubevious Apache 2.0 1.5k 18 0

De inicio, simplemente con visitar su página web, podemos ver que nos encontramos con un producto más sofisticado que los anteriores, más completo y con mejor imagen de marca, de hecho, ofrece versiones de pago, en este post vamos a validar la opción open-source.

kubeovious_pricing.png

Instalación
En este caso vamos a instalar el cliente de kubevious, para ello podemos seguir las instrucciones alojadas en su github

En nuestro caso lo que nos interesa es el soporte multiplataforma (Linux, macOS y Windows) y la capacidad de usarlo como contenedor con Docker, que también lo tiene.

Al igual que Kube-linter ofrece su propia definición de GitHub Action y de Drone para la integración en circuitos de CICD.

Uso

Como hemos comentado, es una suite, es decir, ofrece las siguientes capacidades:

  • Best Practices Validation (algo similar a kube-score y kube-linter)
  • Manifest Validation y CRDs and Custom Resources (algo similar a kubeconform)

Es decir, puede servir para unificar las anteriores herramientas en una sola, además a nivel de integración ofrece soporte nativo a Helm y Kustomize e incluso comentan que capacidades de validación sobre objetos instalados ya en un clúster.

Lint
Lint es la opción de validación de tipo kubeval o kubeconform, es decir, que los ficheros cumplan la API definida.

kubevious lint ./k8/example-chart/templates/

kubeovois_lint.png

A priori Kubevious da soporte a CRDs pero al contrario que kubeconform no permite introducir las definiciones de ninguna manera, por lo que por ejemplo nos hemos encontrado con que el ServiceMonitor de monitoring.coreos.com/v1 (algo básico para por ejemplo prometheus) no es capaz de validarlo.

kubeovois_lint_error.png

Esto limita algo el uso de este cliente en clústers con ciertos CRDS menos conocidos o incluso customizados. Ya que para validar CRDs que no contenga la herramienta debemos incluir el CRD de manera local.

kubevious lint k8/example-chart/templates/ CRD/monitoring.coreos.com/servicemonitors.yaml

Guard
Guard es la opción de kubevious que nos permite realizar las validaciones semánticas de nuestros ficheros junto con el "linteo" del contenido, es decir, revisar una serie de reglas y aplicar buenas prácticas además de realizar la validación a nivel de API.

Las reglas que ofrece las podemos encontrar aquí.

Para ello:

kubevious guard ./k8/example-chart/templates/

Nuestra sorpresa aparece cuando no saltan ninguna regla que tanto kube-linter como kube-score han detectado.

kubeovois_guard.png

Logicamente las reglas es algo subjetivo, pero que no haya detectado reglas como runAsNonRoot o límites de recursos de inicio rompe nuestras expectativas con el producto que parecía muy completo.

Las reglas que lanza kubevious las podemos encontrar en: https://github.com/kubevious/rules-library

Uso avanzado

Validación contra cluster de kubernetes
Una característica interesante de la herramienta es la capacidad de integrarse con un clúster de K8 y validar los recursos que están desplegados en el mismo. Para ello hay que usar --live-k8s como parámetro y de manera opcional informar de la configuración de conexión del cluster con --kubeconfig.

Por poner una pega, parece que kubevious busca siempre el primer contexto del fichero config, cuando realmente pueden existir más de uno si no has configurado un contexto por fichero.

kubevious guard --live-k8s --kubeconfig /home/manu/.kube/config

✖ Could not connect to Kubernetes cluster. contexts[0].context.cluster is missing

En mi caso el primer contexto era un contexto obsoleto mal formado, pero lo lógico es que se basara en revisar cual es el current-context. Una vez solucionado el problema:

kubevious_live.png

Genera errores con los manifest de kubevious, puede ser debido a la versión (mi cluster es 1.28.3 y kubevious por defecto trabaja con la 1.25.2 (un poco obsoleta). De hecho si forzamos la versión 1.28.3 da error en el lint

kubevious lint k8/example-chart/templates/  --detailed --k8s-version=1.28.3

⚠️  Could not find requested Kubernetes Version: 1.28.3
ℹ️  Linting against Kubernetes Version: 1.25.2

Creación de reglas customizables
Kubevious permite crear reglas customizables (o eso se intuye de su documentación), que pueden subsanar el problema comentado en el punto anterior. El problema es que tanto en la documentación del CLI, como en el help del comando no ofrece como incluirlas.

Options:
  --ignore-unknown                  Ignore unknown resources. Use when manifests include CRDs and not using --live-k8s option.
  --ignore-non-k8s                  Ignore non-k8s files.
  --skip-apply-crds                 Skips CRD application.
  --stream                          Also read manifests from stream.
  --k8s-version <version>           Target Kubernetes version. Do not use with --live-k8s option.
  --live-k8s                        Lint against live Kubernetes cluster. Allows validation of CRDs. Do not use with --k8s-version option.
  --kubeconfig <path>               Optionally set the path to the kubeconfig file. Use with --live-k8s option.
  --k8s-skip-tls-verify             Skips TLS certificate verification when connecting to live K8s. Has effects when using with --live-k8s option.
  --include-remote-targets          Include remote Kubernetes manifests in target rules. Use with --live-k8s option.
  --skip-local-rules                Skip validation of rules passed to the CLI.
  --skip-remote-rules               Skip validation of rules that are already in the K8s cluster. Only used wth --live-k8s flag.
  --namespace <namespace>           Optionally specify namespace to process.
  --namespaces [namespace...]       Or specify multiple namespaces to process.
  --skip-cluster-scope              Skip processing clustered manifests and rules.
  --skip-community-rules            Skip community rules library.
  --skip-rules [name...]            Rules to skip.
  --only-rules [name...]            Names of rules to process.
  --skip-rule-categories [name...]  Rule categories to skip.
  --only-rule-categories [name...]  Rule categorie to process.
  --gitignore <path>                Path to .gitignore file to filter out input patterns.
  --ignore-patterns [patterns...]   File patters to ignore.
  --detailed                        Detailed output.
  --json                            Output command result in JSON.
  -h, --help                        display help for command

Conclusiones
Creo que la potencia de kubevious no está en el CLI, sino en el dashboard que ofrece y que otros autores hablan muy bien de el, como por ejemplo:

https://codefresh.io/blog/kubevious-kubernetes-dashboard/
https://www.airplane.dev/blog/kubevious

Desde mi punto de vista, existen mejores alternativas opensource que abarcan correctamente su cometido. Por lo que preferiría montar un circuito con una combinación kubeconform + kubelinter que usar kubevious. Aun así creo que para otro artículo podríamos echarle un vistazo al dashboard.

Kubeaudit

Kubeaudit es una herramienta de Shopify, por lo que me ha parecido interesante incluirla, está pensada para realizar validaciones funcionales, es decir, reglas predefinidas, aunque ofrece un ligero control a nivel de API (Control de versiones).

Herramienta Tipo Web Github Licencia Stars Watchs Commits
Kubeaudit Mix https://github.com/Shopify/kubeaudit MIT license 1.7k 402 2

Instalación
Siguiendo los mismos pasos que las anteriores, soporte multiplataforma, Docker y como punto interesante un plugin para kubectl.

Uso
La herramienta tiene capacidad de ejecutarse en tres modos:

  • Manifest, es decir, validación de archivos en local, que sería el caso que estamos buscando.
  • Remoto, conectarse a un clúster y realizar las validaciones.

La herramienta es diferente al resto, ya que las reglas están definidas por comandos, es decir, para la regla de limites se debe lanzar kubeaudit limit para la regla de nonroot se debe lanzar kubeaudit nonoroot teniendo la opción de lanzarlas todas con all, Ejemplo:

kubeaudit all -f k8/example-chart/templates/*yaml

Devolviendo la salida con los Warnings y los Errores

kubeaudit.png

Si queremos customizar la selección debemos optar por usar fichero de configuración, tal y como se explica aquí.

Las reglas posibles son:

  apparmor       Audit containers running without AppArmor
  asat           Audit pods using an automatically mounted default service account
  capabilities   Audit containers not dropping ALL capabilities
  hostns         Audit pods with hostNetwork, hostIPC or hostPID enabled
  image          Audit containers not using a specified image:tag
  limits         Audit containers exceeding a specified CPU or memory limit
  mounts         Audit containers that mount sensitive paths
  netpols        Audit namespaces that do not have a default deny network policy
  nonroot        Audit containers allowing for root user
  privesc        Audit containers that allow privilege escalation
  privileged     Audit containers running as privileged
  rootfs         Audit containers not using a read only root filesystems
  seccomp        Audit containers running without Seccomp

La potencia de esta herramienta radica en la opción de autofix, que como ellos mismos dicen:

Automagically make a manifest secure

Si lanzamos dicho comando:

git.png

Nos modifica los ficheros para que cumplan las reglas que ha detectado como error.

Conclusiones
Aunque el autofix es algo interesante y diferente frente a otras herramientas, no creo que kubeaudit ofrezca valor añadido sobre kubelinter o kubescore.

La principal ventaja que le veo es que a nivel de soporte, está avalada por una gran compañia, por lo que quizás siga en desarrollo y no se pare (como ha pasado con Kubeval)

Conclusiones

Podríamos seguir analizando herramientas, de hecho, el objetivo inicial de este artículo era evaluar también herramientas que nos permitieran definir nuestras propias validaciones como pueden ser:

  • Conftest , os dejo este post de Medium donde se explica su funcionamiento.
  • Polaris, esta herramienta es una suite que además te permite crear tus propias reglas.

A nivel de comparativa nos aparece la siguiente tabla final:

Herramienta Tipo Web Github Licencia Stars Watchs Commits
KubeVal API/Schema https://www.kubeval.com/ https://github.com/instrumenta/kubeval Apache License, Version 2.0 3.1k 27 0 (desmantenido)
KubeConform API/Schema https://github.com/yannh/kubeconform Apache License, Version 2.0 1.5k 4 5
KubeScore Built-in rules https://kube-score.com/ https://github.com/zegl/kube-score MIT License 2.4k 22 6
KubeLinter Built-in rules https://docs.kubelinter.io/ https://github.com/stackrox/kube-linter Apache 2.0 2.6k 35 13
Kubevious Mix https://kubevious.io/ https://github.com/kubevious/kubevious Apache 2.0 1.5k 18
Kubeaudit Mix https://github.com/Shopify/kubeaudit MIT license 1.7k 402 2

Sin extenderme más, creo que las mejores opciones son una combinación de kubeconform + kubelinter, siendo kubescore otra opción perfectamente válida para añadir a nuestro circuito de CICD.

Lo principal es buscar una herramienta que se adapte a nuestro caso de uso (Customización, CRDs...) muchas de ellas incluyen añadidos, que aunque puedan ser interesantes, conexión a cluster, autofix... no entran dentro de la categoría DevSecOps en el circuito SAST ya que se pretende una detección temprana de los errores.