In this article we take a more in-depth look at YAML files. We’ll look at the “anatomy” of a manifest and why labels are the secret sauce that holds everything together.
1. The Four Pillars of a Manifest
Every Kubernetes object (Deployment, Service, ConfigMap, etc.) requires four mandatory fields:
- apiVersion: Which version of the Kubernetes API you’re talking to (e.g.,
apps/v1). - kind: What you want to create (e.g.,
Deployment). - metadata: Data that identifies the object, like its
nameandlabels. - spec: The “Desired State.” This is where you tell Kubernetes exactly how you want your application to look.
2. The Deployment
A Deployment doesn’t just run pods; it manages them. Here is a production-ready example:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app-deployment
labels:
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
app: web-server # This MUST match the labels in the template below
template:
metadata:
labels:
app: web-server
spec:
containers:
- name: nginx-container
image: nginx:1.25
ports:
- containerPort: 80
resources: # Best Practice: Define resource needs
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- Selectors & Labels: This is the “glue.” The Deployment uses the
selectorto find and manage the pods it owns. If you change a pod’s label manually, the Deployment will lose track of it and immediately start a new one to maintain the replica count! - Resources:
requestsare what the pod is guaranteed;limitsare the maximum it can consume.
3. The Service (Networking)
Because Pods are ephemeral (they can die and restart with new IPs), you need a stable entry point.
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
selector:
app: web-server # This links the service to the pods defined above
ports:
- protocol: TCP
port: 80 # The port the Service listens on
targetPort: 80 # The port inside the Container
type: ClusterIP # Internal-only (default)
- Common Service Types:
- ClusterIP: Accessible only inside the cluster. Great for databases.
- NodePort: Opens a specific port on every Node. Good for quick testing.
- LoadBalancer: Provisions a real load balancer (in cloud environments) to make your app reachable from the internet.
Pro Tip: Use kubectl apply -f file.yaml --dry-run=client to check your YAML for syntax errors before actually deploying it.