11. Kubernetes Manifest File
A Manifest File is a declarative YAML (or JSON) document that defines the desired state of a Kubernetes object. It tells Kubernetes what should exist, not how to create it step by step.
Kubernetes continuously works to make the actual cluster state match the desired state written in the manifest.
11.1 Where Manifest Files Are Used
Manifest files are used wherever Kubernetes resources must be created, updated, or managed in a repeatable and version-controlled way.
- Application deployment: Pods, Deployments, Services
- Infrastructure configuration: Namespaces, ConfigMaps, Secrets
- Automation: CI/CD pipelines applying manifests
- Disaster recovery: Recreate entire cluster state from YAML
11.2 Why Manifest Files Are Used
Imperative commands say “do this now”. Manifests say “this is how it should always be”.
- Declarative control: Desired state is always enforced
- Idempotent: Applying same file multiple times is safe
- Version control friendly: YAML stored in Git
- Auditable & reproducible: Same file → same infrastructure
What is the benefit of defining infrastructure in Manifest files?
A: It allows for Infrastructure as Code (IaC). You can version control your infrastructure (Git), audit changes, and ensure reproducibility safely.
11.3 How a Manifest Works
graph TD
User[User/CI] -->|kubectl apply| API[API Server]
API -->|Store| Etcd[(etcd)]
Control[Controller] -->|Watch| API
Control -->|Diff| State{Desired == Actual?}
State -->|No| Fix[Take Action]
Fix --> API
style API fill:#ffcc80
The manifest does not create resources directly. It flows through Kubernetes components.
- kubectl apply sends YAML to API Server
- API Server validates and stores it in etcd
- Controllers compare desired vs actual state
- Scheduler assigns Pods to Nodes
- Kubelet creates/maintains Pods
This loop runs continuously, enabling self-healing.
Does the kubectl apply command create the Pods directly?
A: No. It sends the YAML data to the API Server. The internal Kubernetes Controllers and Introduction then handle the actual creation asynchronously.
11.4 Standard Manifest Structure
Every Kubernetes manifest follows the same structural contract.
- apiVersion: Which API version to use
- kind: Type of resource
- metadata: Identity and labels
- spec: Desired state definition
What is the kind field in a K8s manifest?
A: It specifies the type of object to create, such as Pod, Deployment, Service, or ConfigMap.
11.4.1 Minimal Manifest Example
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
11.5 Common Types of Manifest Files
- Pod: Single runnable unit
- Deployment: Manages replica Pods and updates
- Service: Stable network access to Pods
- ConfigMap: Non-sensitive configuration
- Secret: Sensitive data (encoded)
- Namespace: Logical isolation
11.6 Kubectl Commands for Manifests
- kubectl apply -f file.yaml: Create or update resource declaratively
- kubectl delete -f file.yaml: Remove resource defined in manifest
- kubectl create -f file.yaml: Create resource (imperative style)
- kubectl edit resource/name: Live edit resource spec
11.7 Scaling & Rollout Commands
- kubectl scale deployment app --replicas=5: Change replica count
- kubectl rollout status deployment app: Check rollout progress
- kubectl rollout history deployment app: View revisions
- kubectl rollout undo deployment app: Roll back to previous version
11.8 Observability & Debugging Commands
- kubectl get pods: List resources
- kubectl get pods -o wide: Include node & IP details
- kubectl describe pod name: Detailed runtime info
- kubectl logs pod-name: View container logs
- kubectl exec -it pod-name -- bash: Enter container shell
11.9 Top 10 Daily-Use Kubectl Commands
| Command | What It Does |
|---|---|
| kubectl apply -f | Apply desired state from manifest |
| kubectl get all | Quick cluster resource overview |
| kubectl get pods -o wide | Pod placement and networking |
| kubectl describe | Deep inspection of resource state |
| kubectl logs | Debug application behavior |
| kubectl exec | Runtime container access |
| kubectl scale | Manual replica adjustment |
| kubectl rollout status | Track deployment progress |
| kubectl rollout undo | Recover from bad deployment |
| kubectl delete | Remove resources cleanly |
What is the difference between kubectl apply and kubectl create?
A: apply is declarative (updates existing resources if they change). create is imperative (errors out if the resource already exists).
11.10 Imperative vs Declarative
Kubernetes supports two interaction models. Understanding this distinction is mandatory for real-world DevOps.
- Imperative: You tell Kubernetes what action to perform now
- Declarative: You tell Kubernetes what final state should exist
| Aspect | Imperative | Declarative (Manifest) |
|---|---|---|
| Command | kubectl run | kubectl apply -f |
| State tracking | Manual | Automatic |
| Rollback | Difficult | Built-in |
| CI/CD suitability | Poor | Excellent |
Why is declarative (Manifest) better for CI/CD than imperative commands?
A: Because it is idempotent. You can run kubectl apply -f 100 times safely. Imperative scripts break if run twice (e.g., trying to create a resource that exists).
11.11 Labels & Selectors
Labels are key-value metadata used to logically group resources. Selectors use labels to connect components.
- Deployments select Pods
- Services select Pods
- NetworkPolicies select traffic targets
metadata:
labels:
app: web
env: prod
Without labels, Kubernetes objects cannot scale, route traffic, or self-heal effectively.
11.12 Namespaces in Manifests
Namespaces logically isolate resources within the same cluster.
- default: Normal workloads
- kube-system: Core Kubernetes components
- dev / test / prod: Environment separation
metadata:
name: backend
namespace: prod
Namespaces are mandatory for multi-team and enterprise clusters.
11.13 Validation & Dry Run
Kubernetes allows validating manifests without applying them.
- --dry-run=client: Local syntax validation
- --dry-run=server: API-level validation
kubectl apply -f app.yaml --dry-run=client
kubectl apply -f app.yaml --dry-run=server
This prevents broken deployments in production.
11.14 Version Control Best Practices for Manifests
Manifests are infrastructure source code.
- One resource per file
- Environment-wise folders (dev/test/prod)
- No secrets in plain YAML
- Git commit history = infrastructure audit log
11.15 Common Manifest Mistakes
- Wrong apiVersion
- Mismatch between labels and selectors
- Missing container ports in Services
- Using imperative commands in CI/CD
- Editing live resources instead of updating YAML
11.16 Simple Manifest Workflow
Here is the absolute simplest way to see Kubernetes Manifests in action. We will create a generic Nginx Pod.
1. Create the File
Create a file named simple-pod.yaml on your machine.
2. Add the Content
apiVersion: v1
kind: Pod
metadata:
name: my-first-pod
labels:
app: demo
spec:
containers:
- name: web-server
image: nginx:alpine
ports:
- containerPort: 80
3. Apply It
Run this command to send the manifest to the cluster:
kubectl apply -f simple-pod.yaml
4. How it Works
- apiVersion: v1 → The version of the Kubernetes API to use.
- kind: Pod → The type of resource to create.
- metadata → Names the resource
my-first-pod. - spec → The "specs" or desired state (run
nginx:alpine). - apply → The command that makes the magic happen.
