Kustomize OpenAPI validation allows you to catch schema errors in your Kubernetes manifests before they are applied to the cluster, acting as a powerful pre-flight check.
Let’s see it in action. Imagine you have a Deployment manifest that’s missing a required field, like spec.replicas.
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
You’ve also got Kustomize set up to manage this. Now, instead of just running kubectl apply -k ., you can add a validation step.
The core idea is that Kustomize can leverage the OpenAPI schema that the Kubernetes API server uses to validate resources. By default, kubectl and kustomize build don’t perform this deep schema validation; they primarily check for syntax errors or basic structural issues. OpenAPI validation checks if your manifest conforms to the semantic definition of a Kubernetes resource.
Here’s how you’d typically integrate it. First, ensure you have a recent version of kubectl (v1.20+ is a good baseline, though newer is always better) which includes the OpenAPI validation feature.
The command to perform this validation is kustomize build . --openapi-schema <path_to_schema>.
The <path_to_schema> is the crucial part. Kustomize needs access to the OpenAPI schema of the Kubernetes API. You can obtain this in several ways:
-
Download from a running cluster: This is the most accurate method as it reflects the exact API version and features enabled on your cluster.
kubectl get --raw 'https://<your-k8s-api-server-address>/openapi/v2' > openapi.jsonReplace
<your-k8s-api-server-address>with the actual address of your Kubernetes API server (e.g.,kubernetes.default.svc.cluster.localif running inside the cluster, or your cluster’s external API endpoint). -
Use the schema embedded in
kubectl:kubectlitself downloads and caches the OpenAPI schema. You can point Kustomize to this cached file. The location varies by OS andkubectlversion, but it’s often in a path like~/.kube/cache/discovery/v1/apis/<group>/<version>/openapi.json. A more robust way to find it is often to inspect the output ofkubectl cluster-info dumpor related commands, or to query the discovery API directly. -
Use a known-good schema file: You can find publicly available OpenAPI schema files for specific Kubernetes versions online. However, this is less ideal as it might not match your cluster’s exact configuration.
Once you have your openapi.json file (let’s assume you downloaded it to ./openapi.json), you run the validation:
kustomize build . --openapi-schema ./openapi.json
If your deployment.yaml has the missing spec.replicas field, this command will fail with an error similar to:
Error: validation errors:
* "": spec.replicas must be an integer
The output clearly indicates that spec.replicas is expected to be an integer, but it was not found (or was null, depending on the schema’s required fields).
To fix this, you’d add the replicas field to your deployment.yaml:
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-nginx-deployment
spec:
replicas: 3 # Added this line
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
Running kustomize build . --openapi-schema ./openapi.json again would now succeed, meaning your manifest conforms to the OpenAPI schema.
The mental model here is that kustomize build is now not just assembling your YAML, but it’s also performing a rigorous check against the Kubernetes API’s own definition of what a Deployment (or any other resource) should look like. It’s like having the Kubernetes API server’s validation logic run locally on your development machine.
This process is incredibly valuable for catching "typos" in your resource definitions, ensuring required fields are present, and verifying that data types are correct. It prevents a whole class of errors that would otherwise only be discovered when kubectl apply fails, often with less informative error messages. You control the fidelity of the validation by the accuracy of the OpenAPI schema you provide.
What most people don’t realize is that the OpenAPI schema is a rich, structured document that describes not just the fields, but also their types, formats, constraints (like minimum/maximum values for integers), and whether they are optional or mandatory. Kustomize, when provided with this schema, uses it to perform a deep, semantic analysis of your generated manifests, going far beyond simple YAML parsing.
After successfully validating your manifests against the OpenAPI schema, the next logical step in your CI/CD pipeline would be to perform a dry-run apply using kubectl apply --dry-run=server -k . to see how the API server would interpret your validated resources.