Kubernetes Deployment and Service YAML: example and generator
A Deployment and Service YAML for your container image, with replicas, port, resource limits and health checks.
A Deployment tells Kubernetes to keep a number of copies of your container running. A Service gives those copies one stable address. Fill in your image and port to get both in one file, then apply it with kubectl.
Create your config file
Type your own values. The file below updates as you type, and nothing you type leaves your browser.
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 2
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: nginx:1.27
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
---
apiVersion: v1
kind: Service
metadata:
name: myapp
spec:
type: ClusterIP
selector:
app: myapp
ports:
- port: 80
targetPort: 80How this setup works
Step-by-step setup
- Save the file above as deployment.yaml.
- Make sure kubectl points at the right cluster: kubectl config current-context.
- Apply it: kubectl apply -f deployment.yaml.
- Watch the pods start: kubectl get pods.
- Look at the service: kubectl get service myapp.
- To try it from your computer: kubectl port-forward service/myapp 8080:80, then open http://localhost:8080.
What the important lines mean
- replicas: 2 is how many copies Kubernetes keeps running.
- selector and labels must match, or the Deployment will not find its pods.
- containerPort: 80 is the port your app listens on inside the container.
- The Service sends traffic from its own port 80 to 80 on the pods.
Common errors and how to fix them
- ImagePullBackOff or ErrImagePull
- Kubernetes cannot download the image. Check the name and tag for typos, that the image exists, and for a private image add an image pull secret. Run kubectl describe pod name for the exact reason.
- CrashLoopBackOff
- The container starts and then exits. Read its log with kubectl logs pod-name (add --previous for the last crash). A wrong command, missing setting or port clash is common.
- Pending forever
- No node has enough free CPU or memory, or a volume cannot be attached. kubectl describe pod name shows the scheduling message.
- The Service has no endpoints
- The Service selector does not match the pod labels. Both use app: myapp here, so check you did not edit one of them.
- The LoadBalancer stays at <pending>
- Local clusters have no cloud load balancer. Use NodePort, port-forward, or minikube tunnel.
Frequently asked questions
- What is the difference between a Pod and a Deployment?
- A Pod is one running copy of your containers. A Deployment manages many Pods for you: it keeps the right number running, replaces failed ones and handles updates.
- Which Service type should I use?
- ClusterIP for traffic inside the cluster, NodePort for quick tests, and LoadBalancer when your cloud provider can create a public load balancer for you.
- How do I update the image?
- Change the image tag in the file and run kubectl apply again. Kubernetes starts new pods and stops the old ones gradually.
Free tools that help
- Common ports listSearch a list of common TCP and UDP port numbers: SSH 22, HTTP 80, HTTPS 443, MySQL 3306, PostgreSQL 5432 and more, with dev server ports.
Fix a problem with this setup
- Port already in useFind which program holds a port on Windows, macOS or Linux, then stop it or use another port.
More container configs
- Docker Compose for MySQL and phpMyAdminRun MySQL and the phpMyAdmin web page on your computer with one docker compose command.
- Docker Compose for PostgreSQL and pgAdminRun PostgreSQL and the pgAdmin web page on your computer with one docker compose command.
- docker-compose for MongoDBRun a local MongoDB database with a password that keeps its data.
- docker-compose for PostgreSQLRun a local PostgreSQL database that keeps its data.
- docker-compose for MySQLRun a local MySQL database in Docker with your own user, password and port, and keep the data between restarts.
- docker-compose for RedisRun Redis in Docker with a password, saved data and a memory limit.