Skip to content

Formatters & Code

Kubernetes Deployment + Service

K8s Deployment + Service manifest in one file.

Runs in your browser
Kubernetes manifest · web.yaml
lines: 48chars: 831size: 831 B
live

Understanding K8s Deployments

Three nested objects, one running app.

What a Deployment, a ReplicaSet and a Pod actually are, and why the YAML you ship has all three nested inside one another.

Three layers, three concerns.

A Pod is the smallest deployable unit — one or more containers that share a network and storage namespace. A ReplicaSet is a controller that maintains a target number of identical Pods. A Deployment is a higher-level controller that manages ReplicaSets across rolling updates. You write the Deployment; Kubernetes creates the ReplicaSet, which creates the Pods. Most of the YAML you'll see in tutorials and templates is the Pod spec nested inside the Deployment's template field — the same Pod spec you'd write standalone, but governed by the layers above.

The Service is the front door.

Pods are ephemeral. Each restart gets a new IP; nothing in your application should ever hardcode one. A Service is the stable network entity that load-balances across Pods matching a selector. ClusterIP gives you a cluster-internal address; NodePort opens a host port; LoadBalancer asks the cloud for an external IP. The Deployment- plus-Service pair is the unit you deploy almost every workload as — Service points at Pods via labels, Deployment guarantees enough Pods exist.

Selectors and labels are the glue.

Every K8s controller binds to its workload by label selector, not by name. The Deployment's spec.selector.matchLabels must match the labels in the Pod template; the Service's selector must match the same labels. Get this wrong and the Deployment will refuse to apply (selector mismatch), or worse, the Service will select nothing and routing will silently break. A reasonable default is to label everything with app: <name> and use that as the selector everywhere.

A worked Deployment.

The shape: apiVersion: apps/v1 kind: Deployment metadata: { name: web, labels: { app: web } } spec: replicas: 3 selector: { matchLabels: { app: web } } template: metadata: { labels: { app: web } } spec: containers: - name: web image: myapp:1.0 ports: [{ containerPort: 3000 }] resources: requests: { cpu: "100m", memory: "128Mi" } limits: { cpu: "500m", memory: "256Mi" } A typical companion Service routes external traffic to it. Three Pods, each running the same image, behind one Service IP.

The required fields

apiVersion / kind / metadata / spec

K8s rejects manifests missing any of the four top-level required fields.

apps/v1 + "Deployment" + name + spec

= A minimal valid Deployment

Resources: requests and limits.

Requests are what the scheduler reserves for the Pod; the cluster won't place it on a node that doesn't have the requested capacity. Limits are the cap — exceed them and the container is throttled (CPU) or killed (memory). Setting them too low causes OOMKills under load; setting them too high causes scheduler crowding and wasted capacity. A reasonable starting point is "request what the app uses at idle, limit at a sane peak". Tune from observed metrics, not from guesses.

Probes — liveness vs readiness.

Two different checks. A readiness probe says "this Pod is ready to receive traffic" — when it fails, the Pod gets removed from Service load balancing; recovering, it rejoins. A liveness probe says "this Pod is alive at all" — when it fails, Kubernetes restarts the container. The classic mistake is setting an aggressive liveness probe on an app that takes a while to start: the probe trips during startup, Kubernetes restarts the container, the new container takes a while to start, the probe trips again, infinite loop. Use startupProbe for slow boots; reserve liveness for genuine "process is wedged" cases.

Rolling updates.

The Deployment's default strategy is RollingUpdate with maxSurge: 25% and maxUnavailable: 25%. Bump the image and K8s rolls the change out one Pod at a time, waiting for readiness, never dropping below 75 % capacity. For zero-downtime deploys the readiness probe has to actually mean what it says; for stateful apps you may want StatefulSet instead, which orders Pod startup and shutdown.

Frequently asked questions

Quick answers.

What resources are included in the output?

The generator produces a `Deployment` and a `Service` resource separated by a YAML document divider (`---`). This allows you to define both the pod replication logic and the network access in a single file.

Is my configuration sent to a server?

No. The manifest generation happens locally in your browser. No data regarding your image names, environment variables, or port settings ever leaves your device.

Does this support custom annotations?

This tool focuses on the core specification including labels, ports, and environment variables. For complex configurations like ingress or persistent volumes, use this output as a starting template and modify it as needed.

What service types are supported?

You can choose between `ClusterIP` for internal traffic, `NodePort` for external access via a static port, or `LoadBalancer` for cloud-based external access.

People also search for

Related tools

More in this room.

See all in Formatters & Code