Kubeconform is a Kubernetes manifest validation tool. Incorporate it into your CI, or use it locally to validate your Kubernetes configuration!
It is inspired by, contains code from and is designed to stay close to
Kubeval, but with the following improvements:
high performance: will validate & download manifests over multiple routines, caching
downloaded files in memory
configurable list of remote, or local schemas locations, enabling validating Kubernetes
custom resources (CRDs) and offline validation capabilities
uses by default a self-updating fork of the schemas registry maintained
by the kubernetes-json-schema project - which guarantees
up-to-date schemas for all recent versions of Kubernetes.
<details><summary><h4>Speed comparison with Kubeval</h4></summary><p>
Running on a pretty large kubeconfigs setup, on a laptop with 4 cores:
$ time kubeconform -ignore-missing-schemas -n 8 -summary preview staging production
Summary: 50714 resources found in 35139 files - Valid: 27334, Invalid: 0, Errors: 0 Skipped: 23380
real 0m6,710s
user 0m38,701s
sys 0m1,161s
$ time kubeval -d preview,staging,production --ignore-missing-schemas --quiet
[... Skipping output]
real 0m35,336s
user 0m0,717s
sys 0m1,069s
</p></details>
<details><summary>Converting an OpenAPI file to a JSON Schema</summary>
<p>
</p>
</details>
Kubeconform relies on a fork of kubernetes-json-schema
that is more meticulously kept up-to-date, and contains schemas for all recent versions of Kubernetes.
Limits of Kubeconform validation
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. Those server-side validations are not covered by Kubeconform (examples: #65, #122, #142). You can use a 3rd-party tool or the kubectl --dry-run=server command to fill the missing (validation) gap.
Installation
If you are a Homebrew user, you can install by running:
$ brew install kubeconform
If you are a Windows user, you can install with winget by running:
winget install YannHamon.kubeconform
You can also download the latest version from the release page.
Another way of installation is via Golang's package manager:
# With a specific version tag
$ go install github.com/yannh/kubeconform/cmd/kubeconform@v0.4.13
# Latest version
$ go install github.com/yannh/kubeconform/cmd/kubeconform@latest
Usage
$ kubeconform -h
Usage: kubeconform [OPTION]... [FILE OR FOLDER]...
-cache string
cache schemas downloaded via HTTP to this folder
-debug
print debug information
-exit-on-error
immediately stop execution when the first error is encountered
-h show help information
-ignore-filename-pattern value
regular expression specifying paths to ignore (can be specified multiple times)
-ignore-missing-schemas
skip files with missing schemas instead of failing
-insecure-skip-tls-verify
disable verification of the server's SSL certificate. This will make your HTTPS connections insecure
-kubernetes-version string
version of Kubernetes to validate against, e.g.: 1.18.0 (default "master")
-n int
number of goroutines to run concurrently (default 4)
-output string
output format - json, junit, pretty, tap, text (default "text")
-reject string
comma-separated list of kinds or GVKs to reject
-schema-location value
override schemas location search path (can be specified multiple times)
-skip string
comma-separated list of kinds or GVKs to ignore
-strict
disallow additional properties not in schema or duplicated keys
-summary
print a summary at the end (ignored for junit output)
-v show version information
-verbose
print results for all resources (ignored for tap and junit output)
Usage examples
Validating a single, valid file
$ kubeconform fixtures/valid.yaml
$ echo $?
0
Validating a single invalid file, setting output to json, and printing a summary
When the -schema-location parameter is not used, or set to default, kubeconform will default to downloading
schemas from https://github.com/yannh/kubernetes-json-schema. Kubeconform however supports passing one, or multiple,
schemas locations - HTTP(s) URLs, or local filesystem paths, in which case it will lookup for schema definitions
in each of them, in order, stopping as soon as a matching file is found.
if the -schema-location value ends with .json - Kubeconform assumes the value is a Go templated
string that indicates how to search for JSON schemas.
the -schema-location value of default is an alias for https://raw.githubusercontent.com/yannh/kubernetes-json-schema/master/{{.NormalizedKubernetesVersion}}-standalone{{.StrictSuffix}}/{{.ResourceKind}}{{.KindSuffix}}.json.
Here are the variables you can use in -schema-location:
NormalizedKubernetesVersion - Kubernetes Version, prefixed by v
StrictSuffix - "-strict" or "" depending on whether validation is running in strict mode or not
ResourceKind - Kind of the Kubernetes Resource
ResourceAPIVersion - Version of API used for the resource - "v1" in "apiVersion: monitoring.coreos.com/v1"
Group - the group name as stated in this resource's definition - "monitoring.coreos.com" in "apiVersion: monitoring.coreos.com/v1"
KindSuffix - suffix computed from apiVersion - for compatibility with Kubeval schema registries
CustomResourceDefinition (CRD) Support
Because Custom Resources (CR) are not native Kubernetes objects, they are not included in the default schema.
If your CRs are present in Datree's CRDs-catalog, you can specify this project as an additional registry to lookup:
# Look in the CRDs-catalog for the desired schema/s
$ kubeconform -schema-location default -schema-location 'https://raw.githubusercontent.com/datreeio/CRDs-catalog/main/{{.Group}}/{{.ResourceKind}}_{{.ResourceAPIVersion}}.json' [MANIFEST]
If your CRs are not present in the CRDs-catalog, you will need to manually pull the CRDs manifests from your cluster and convert the OpenAPI.spec to JSON schema format.
Kubeconform uses JSON schemas to validate Kubernetes resources. For Custom Resource, the CustomResourceDefinition
first needs to be converted to JSON Schema. A Go tool is provided to convert these CustomResourceDefinitions
to JSON schema. Build it from the openapi2jsonschema-go/ directory and use it as follows:
$ cd openapi2jsonschema-go && make local-build
$ ./bin/openapi2jsonschema https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-for-k8s/master/config/crd/bases/sagemaker.aws.amazon.com_trainingjobs.yaml
JSON schema written to trainingjob_v1.json
By default, the file name output format is {kind}_{version}. The FILENAME_FORMAT environment variable can be used to change the output file name (Available variables: kind, group, fullgroup, version):
$ export FILENAME_FORMAT='{kind}-{group}-{version}'
$ ./bin/openapi2jsonschema https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-for-k8s/master/config/crd/bases/sagemaker.aws.amazon.com_trainingjobs.yaml
JSON schema written to trainingjob-sagemaker-v1.json
$ export FILENAME_FORMAT='{kind}-{fullgroup}-{version}'
$ ./bin/openapi2jsonschema https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-for-k8s/master/config/crd/bases/sagemaker.aws.amazon.com_trainingjobs.yaml
JSON schema written to trainingjob-sagemaker.aws.amazon.com-v1.json
After converting your CRDs to JSON schema files, you can use kubeconform to validate your CRs against them:
# If the resource Kind is not found in default, also lookup in the schemas/ folder for a matching file
$ kubeconform -schema-location default -schema-location 'schemas/{{ .ResourceKind }}{{ .KindSuffix }}.json' fixtures/custom-resource.yaml
ℹ️ Datree's CRD Extractor is a utility that can be used instead of this manual process.
OpenShift schema Support
You can validate Openshift manifests using a custom schema location. Set the OpenShift version (v3.10.0-4.1.0) to validate
against using -kubernetes-version.
Kubeconform publishes Docker Images to Github's new Container Registry (ghcr.io). These images
can be used directly in a Github Action, once logged in using a Github Token.
Note on pricing: Kubeconform relies on Github Container Registry which is currently in Beta. During that period,
bandwidth is free. After that period,
bandwidth costs might be applicable. Since bandwidth from Github Packages within Github Actions is free, I expect
Github Container Registry to also be usable for free within Github Actions in the future. If that were not to be the
case, I might publish the Docker image to a different platform.
Gitlab-CI
The Kubeconform Docker image can be used in Gitlab-CI. Here is an example of a Gitlab-CI job: