Kubernetes YAML Generator
Build a Deployment, Service, Ingress, ConfigMap, Secret, StatefulSet, CronJob, PVC or HPA and copy the manifest. It writes the production fields most generators leave out, and explains each one.
Resource
Stateless workloads. The one you want most of the time.
Metadata
Container
Ports
Environment
Production defaults
Output
payments-api-deployment.yaml
# A Deployment owns a ReplicaSet, which owns the Pods. Edit this, never the
# ReplicaSet.
apiVersion: apps/v1
kind: Deployment
metadata:
name: payments-api
namespace: default
labels:
app: payments-api
spec:
replicas: 3
# the selector must match the Pod template labels, and it is immutable after
# creation.
selector:
matchLabels:
app: payments-api
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
template:
metadata:
labels:
app: payments-api
spec:
# a numeric UID, because runAsNonRoot cannot verify a username.
securityContext:
runAsNonRoot: true
runAsUser: 10001
fsGroup: 10001
containers:
- name: payments-api
image: nginx:1.27
ports:
- containerPort: 8080
env:
- name: LOG_LEVEL
value: info
- name: APP_ENV
value: production
# requests are what the scheduler reserves; limits are what the
# kernel enforces.
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
# readiness gates traffic; liveness restarts the container. Do not
# point liveness at a dependency.
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
Or generate it with kubectl
kubectl create deployment payments-api --image=nginx:1.27 --replicas=3 \
--namespace=default --dry-run=client -o yaml--dry-run=client -o yaml prints the manifest without creating anything. It is the fastest way to get a skeleton, though it omits probes, resources and security context, which is why this generator adds them.
How to use the Kubernetes YAML generator
Five steps, about three minutes. The form on the left drives the manifest on the right, and nothing is sent anywhere: the YAML is built in your browser.
Pick the resource you need
Choose from the ten kinds on the left. If you are deploying an application that can run anywhere, that is a
Deployment. If each copy needs its own identity and its own disk, such as a database, it is aStatefulSet. AServicegives those Pods a stable address, and anIngressputs a hostname in front of the Service. The blurb under the buttons says what each one is for.Fill in the name, image and ports
The name becomes
metadata.nameand theapplabel everything else selects on. The image should be pinned to a tag or a digest, neverlatest. Container port is what your process listens on inside the Pod; service port is what callers connect to. They do not have to match, and usually should not.Leave the production defaults on
Resource requests and limits, both probes, and the non-root security context are switched on for a reason: a Pod with no requests is evicted first when a node runs short, and a Pod with no readiness probe takes traffic before it can serve it. Adjust the CPU and memory numbers to your workload rather than turning the block off.
Read the comments, then copy
Every block in the output carries a comment explaining what it does and what breaks without it. Once the manifest makes sense, use Copy YAML, or Download to save it as a file named after the resource. Turn off "Explain the fields in comments" when you want the bare manifest for a repository.
Apply it and watch the rollout
Save the file and run
kubectl apply -f payments-api-deployment.yaml, thenkubectl rollout status deployment/payments-apito see whether it actually came up. If the rollout hangs, it is almost always the new Pods failing their readiness probe rather than Kubernetes being stuck.
The Kubernetes YAML fields that actually cause problems
A manifest is mostly boilerplate plus about ten decisions. These are the ten, with the failure each one causes when it is wrong.
apiVersion
Which API group and version this object belongs to.
It differs per kind and changes between releases. Deployments are apps/v1, Services and ConfigMaps are v1, Ingress is networking.k8s.io/v1, and HPA is autoscaling/v2. Using the wrong one produces "no matches for kind", which reads like the object does not exist.
metadata.namespace
Which namespace the object lives in.
Secrets and ConfigMaps never cross namespaces. A Service in one namespace will never select Pods in another, no matter how the labels match.
spec.selector
Which Pods this object acts on, by label.
On a Deployment it is immutable after creation, so getting it wrong means deleting and recreating. On a Service, Kubernetes never validates it: a selector matching nothing is created happily and routes nowhere.
resources.requests
What the scheduler reserves for the container.
The scheduler counts requests, not usage, so a node at 5% CPU can still refuse your Pod. With no requests at all the Pod is BestEffort and is the first thing evicted when a node runs short.
resources.limits
The ceiling the kernel enforces.
CPU and memory behave differently. Over the CPU limit the container is throttled; over the memory limit it is OOMKilled with exit code 137. That asymmetry catches almost everyone once.
readinessProbe
Whether the Pod should receive traffic right now.
Failing readiness removes the Pod from the Service endpoints. It does not restart anything, which is the point: a Pod that is briefly busy stops getting traffic rather than being killed.
livenessProbe
Whether the container is wedged and should be restarted.
Never point it at a dependency. A liveness probe that checks the database will restart your entire fleet the moment the database has a bad minute, turning a degraded dependency into a full outage.
securityContext.runAsUser
The UID the container process runs as.
Use a number, not a username. Kubernetes cannot verify that a name maps to a non-root user, so runAsNonRoot: true with a username fails at admission.
strategy.rollingUpdate
How many Pods may be down or extra during a rollout.
maxUnavailable: 0 keeps full capacity through a deploy but needs room on the cluster for the surge. A rollout that hangs is almost always new Pods failing readiness, not Kubernetes being stuck.
accessModes
How many nodes may mount a volume, and how.
ReadWriteOnce is per node, not per Pod. Two Pods on the same node can share it; two Pods on different nodes cannot. ReadWriteMany needs a filesystem service such as EFS, which most block storage cannot do.
Generating Kubernetes YAML with kubectl instead
Every generated manifest above shows its kubectl equivalent. The flag that makes it work is --dry-run=client -o yaml, which builds the object and prints it rather than sending it to the cluster.
kubectl create deployment payments-api --image=nginx:1.27 \
--replicas=3 --dry-run=client -o yaml > deployment.yaml
kubectl create service clusterip payments-api --tcp=80:8080 \
--dry-run=client -o yaml > service.yamlIt is the fastest way to a skeleton and worth knowing. What it will not give you is probes, resource requests, a security context or a rolling update strategy, all of which you then add by hand. That gap is the reason this generator exists.
Kubernetes YAML questions people actually ask
What is the fastest way to create a Kubernetes YAML file?
Either use this generator, or run kubectl with a dry run: kubectl create deployment api --image=nginx --dry-run=client -o yaml. The kubectl route is quickest for a skeleton but emits only the minimum, with no probes, no resource requests and no security context. This generator adds those, because a manifest without requests is the one that gets evicted first and a manifest without probes is the one that serves traffic before it is ready.
What is the minimum a Kubernetes Deployment YAML needs?
Four things: apiVersion apps/v1, kind Deployment, a metadata.name, and a spec containing a selector and a Pod template whose labels match that selector. Everything else has a default. That minimum will run, but it will run as root, with no resource requests and no health checks, which is why the generator does not offer it as the default.
Why does my manifest fail with "no matches for kind"?
The apiVersion is wrong for that kind, or the resource is a CRD that is not installed. Deployments are apps/v1, Services and ConfigMaps are v1, Ingress is networking.k8s.io/v1, CronJob is batch/v1, and HorizontalPodAutoscaler is autoscaling/v2. Run kubectl api-resources to see what the cluster actually accepts.
Can I generate Kubernetes YAML from a Docker Compose file?
Kompose converts a compose file into manifests, and it is a reasonable starting point rather than an answer. It maps services to Deployments and Services, but it cannot infer probes, resource requests, or whether something needs a StatefulSet, so the output still needs the production fields adding by hand.
Should each Kubernetes resource be its own YAML file?
Either works. Separate files are easier to review and to apply selectively; a single file with resources separated by --- keeps a small application together. What matters more is that they are in version control and applied with kubectl apply -f, so the cluster converges on what the file says rather than on what somebody typed.
Is the YAML this generator produces safe for production?
It is a sound starting point rather than a finished artefact. It sets resource requests and limits, both probes, a non-root security context with dropped capabilities, and a rolling update strategy that keeps full capacity. What it cannot know is your actual resource profile, your real health endpoints, your NetworkPolicies, your PodDisruptionBudget or your affinity rules. Treat it as the first eighty per cent.