In Kubernetes operational management, defining manifests has historically swung between two extremes. On one hand, YAML, the de facto standard, offers human readability but is inherently fragile due to its reliance on indentation and data typing ambiguity. On the other hand, JSON, preferred by machines for its strict structure, lacks support for comments and forces a monolithic object definition, making it difficult to maintain in complex environments managed by tools like Helm or Kustomize.
With the arrival of Kubernetes 1.35, a solution that unifies the best features of both formats is consolidated: KYAML.
What is KYAML?
KYAML is not a new language, but the standardized adoption of YAML’s flow style. Its syntax is characterized by the explicit use of delimiters:
- Objects: Encapsulated in curly braces
{}. - Arrays: Defined using brackets
[]. - Typing: Requires that all string values be delimited by double quotes (
"").
This approach eliminates parsing ambiguity without sacrificing developer ergonomics.
Technical and Operational Benefits
Adopting KYAML directly impacts the stability of CI/CD pipelines and the developer experience (DevEx):
- Structural Integrity: By using delimited blocks (
{}and[]), the manifest becomes immune to indentation errors. Logical structure prevails over visual structure, eliminating critical failures caused by stray whitespace during copy-paste operations. - Documentation Capability: Unlike JSON, KYAML retains YAML’s ability to include comments (
#). This is vital for documenting infrastructure decisions (e.g., requests/limits, magic numbers) directly in the code. - Type Safety: The requirement for quotes for strings mitigates implicit type coercion errors (like the well-known case of the country code “NO” interpreted as boolean
falsein YAML 1.1).
Maturity and Adoption State
The transition to KYAML is designed to be transparent and low-friction:
- Backward Compatibility:
kubectlprocesses KYAML natively, as it complies with the existing YAML specification. - No Extension Changes: Files maintain the
.yamlextension, facilitating integration with current linting and validation tools. - Native Support in v1.35: Kubernetes 1.35 introduces explicit support in the CLI. It is now possible to serialize existing objects to the new format using
kubectl ... -o kyaml. - IDE Support: Modern editors like VSCode or Cursor interpret the syntax correctly, although visual differentiation (syntax highlighting) between keys and values still has room for improvement in the extension ecosystem.
Practical Implementation: YAML vs. KYAML
Below, we contrast the definition of a Deployment object in both formats. These examples are available in the reference repository erase-una-vez-k8s/encodings.
Classic Format (Block Style)
Dependent on indentation and verticality:
# manifest fragment in YAML format (Block Style)
apiVersion: apps/v1
kind: Deployment
metadata:
name: erase-una-vez-2-prod
labels:
app: erase-una-vez-2
env: prod
tier: frontend
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 25%
selector:
matchLabels:
app: erase-una-vez-2
template:
metadata:
labels:
app: erase-una-vez-2
spec:
containers:
- name: server
image: ghcr.io/mmorejon/erase-una-vez-2:v0.5.0
ports:
- containerPort: 8000
name: http
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
KYAML Format (Flow Style)
Structured, compact, and with explicit typing:
# manifest fragment in KYAML format (Flow Style)
apiVersion: "apps/v1"
kind: "Deployment"
metadata: {
name: "erase-una-vez-2-prod",
labels: { app: "erase-una-vez-2", env: "prod", tier: "frontend" }
}
spec: {
replicas: 3,
strategy: {
type: "RollingUpdate",
rollingUpdate: { maxUnavailable: 1, maxSurge: "25%" }
},
selector: {
matchLabels: { app: "erase-una-vez-2" }
},
template: {
metadata: {
labels: { app: "erase-una-vez-2" }
},
spec: {
containers: [
{
name: "server",
image: "ghcr.io/mmorejon/erase-una-vez-2:v0.5.0",
ports: [{ containerPort: 8000, name: "http" }],
resources: {
requests: { cpu: "100m", memory: "128Mi" },
limits: { cpu: "500m", memory: "256Mi" }
}
}
]
}
}
}
KYAML in Practice
First, you need a cluster with version 1.35. You can use the erase-una-vez-k8s repository to spin up a compatible local cluster in seconds (approximately 40 seconds).
git clone https://github.com/mmorejon/erase-una-vez-k8s.git
cd erase-una-vez-k8s
./bash/cluster.sh create
Ensure you are using version 1.35 of kubectl:
kubectl version --client
Client Version: v1.35.0
Kustomize Version: v5.7.1
Once you have the cluster, send the KYAML format manifest to your cluster:
kubectl apply --filename https://raw.githubusercontent.com/mmorejon/erase-una-vez-k8s/refs/heads/main/encodings/kyaml/deployment.yaml
deployment.apps/erase-una-vez-2-prod created
Verify that the deployment has been created correctly:
kubectl get deployment erase-una-vez-2-prod
NAME READY UP-TO-DATE AVAILABLE AGE
erase-una-vez-2-prod 3/3 3 3 21s
Take this opportunity to export the manifest in KYAML format:
kubectl get deployment erase-una-vez-2-prod -o kyaml
KYAML represents the next logical step in the maturity of Kubernetes configuration: the precision machines demand with the flexibility humans need.
comments powered by Disqus