How do I create a Kubernetes manifest?
Reviewed by Prabath Thalangama · Last updated
Write a YAML object with apiVersion, kind, metadata and spec, then apply it with kubectl apply -f. This generator builds that YAML from a form for eight common kinds: Namespace, Deployment, Service, Ingress, ConfigMap, Secret, PersistentVolumeClaim and HorizontalPodAutoscaler, using their current stable API versions.
The generated objects use the stable API groups current Kubernetes releases serve: apps/v1 for Deployments, networking.k8s.io/v1 for Ingress and autoscaling/v2 for the HorizontalPodAutoscaler. Older versions such as extensions/v1beta1 Ingress were removed years ago and are a common reason copied manifests fail.
Deployments are labelled app: <name> and select pods by that label, so a Service with the same selector routes to them. The generator does not add readiness or liveness probes; add them before running the workload in production.
How do I use the manifest generator?
- Pick the kind and fill in the name, namespace and fields for that object, such as the image, replicas and resource requests for a Deployment.
- Copy the YAML into a file. Generate the related objects too (a Service for the Deployment, an Ingress for the Service) and join them with --- lines.
- Validate against your cluster with a server-side dry run, then apply it.
How to read the results
- Deployment
- apps/v1 Deployment with replicas, one container, optional ports, env vars and CPU/memory requests and limits.
- Service
- ClusterIP (internal), NodePort or LoadBalancer, selecting pods by the app label.
- Ingress
- networking.k8s.io/v1 rule for one host and path (pathType Prefix), an optional ingressClassName, and an optional TLS section naming the certificate Secret.
- HorizontalPodAutoscaler
- autoscaling/v2 scaling between min and max replicas on average CPU utilisation. It needs metrics-server and CPU requests on the target pods.
Common errors when applying manifests
no matches for kind "Ingress" in version "extensions/v1beta1"
The manifest uses a removed API version. Use networking.k8s.io/v1, which also requires pathType and the service.name / service.port.number backend format.
selector does not match template labels
spec.selector.matchLabels must match spec.template.metadata.labels exactly. The selector is immutable, so changing it on an existing Deployment means deleting and recreating it.
HPA shows <unknown> for CPU
metrics-server isn't installed, or the pods have no CPU request. Utilisation is measured against the request, so set resources.requests.cpu.
Examples and command-line equivalents
Validate and apply
kubectl apply --dry-run=server -f app.yaml
kubectl diff -f app.yaml
kubectl apply -f app.yamlGenerate a starting manifest with kubectl
kubectl create deployment web --image=nginx:1.27 --replicas=2 --dry-run=client -o yamlFrequently asked questions
How do I check a manifest before applying it?
Run kubectl apply --dry-run=server -f manifest.yaml to have the API server validate it without making changes, and kubectl diff -f manifest.yaml to see what would change.
Should I set CPU limits?
Set CPU and memory requests on every container. Memory limits protect the node; CPU limits cause throttling, so many teams set a CPU request without a CPU limit for latency-sensitive services.
ClusterIP, NodePort or LoadBalancer?
ClusterIP for traffic inside the cluster, which is the usual choice behind an Ingress. NodePort opens a port on every node. LoadBalancer asks the cloud provider for an external load balancer.