Appendix D: Resource Manifests Reference
Copy-paste ready YAML manifests for the most common Kubernetes resource types.
Pod
apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: default
labels:
app: my-app
version: "1.0"
spec:
containers:
- name: main
image: nginx:1.25
ports:
- containerPort: 80
env:
- name: ENV_VAR
value: "hello"
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
livenessProbe:
httpGet:
path: /health
port: 80
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 80
initialDelaySeconds: 5
periodSeconds: 5
restartPolicy: Always
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
namespace: default
labels:
app: my-app
spec:
replicas: 3
selector:
matchLabels:
app: my-app # must match template.metadata.labels
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: my-app
image: my-app:v1
ports:
- containerPort: 8080
resources:
requests:
cpu: "100m"
memory: "128Mi"
limits:
cpu: "500m"
memory: "256Mi"
Service (ClusterIP)
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: default
spec:
type: ClusterIP # default type
selector:
app: my-app # must match pod labels
ports:
- name: http
port: 80 # service port (what clients call)
targetPort: 8080 # container port (what the app listens on)
protocol: TCP
Service (NodePort)
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80
targetPort: 8080
nodePort: 30080 # 30000-32767 range; omit to auto-assign
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls-secret
ConfigMap
apiVersion: v1
kind: ConfigMap
metadata:
name: my-config
namespace: default
data:
DATABASE_HOST: "postgres-service"
DATABASE_PORT: "5432"
app.properties: |
server.port=8080
log.level=INFO
Secret
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: default
type: Opaque
stringData: # stringData auto-encodes to base64
DB_PASSWORD: "my-secure-password"
API_KEY: "abc123secret"
PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
namespace: default
spec:
accessModes:
- ReadWriteOnce
storageClassName: standard
resources:
requests:
storage: 10Gi
StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: my-database
spec:
serviceName: my-database-headless # must match headless service
replicas: 3
selector:
matchLabels:
app: my-database
template:
metadata:
labels:
app: my-database
spec:
containers:
- name: db
image: postgres:15
ports:
- containerPort: 5432
volumeMounts:
- name: data
mountPath: /var/lib/postgresql/data
volumeClaimTemplates: # PVC created per pod
- metadata:
name: data
spec:
accessModes: [ReadWriteOnce]
storageClassName: standard
resources:
requests:
storage: 20Gi
DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: my-log-agent
namespace: kube-system
spec:
selector:
matchLabels:
app: log-agent
template:
metadata:
labels:
app: log-agent
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
operator: Exists
effect: NoSchedule
containers:
- name: agent
image: fluent/fluent-bit:2.1
volumeMounts:
- name: varlog
mountPath: /var/log
volumes:
- name: varlog
hostPath:
path: /var/log
Job
apiVersion: batch/v1
kind: Job
metadata:
name: my-batch-job
spec:
completions: 1
parallelism: 1
backoffLimit: 3
template:
spec:
restartPolicy: OnFailure
containers:
- name: worker
image: my-worker:v1
command: ["python", "process_batch.py"]
CronJob
apiVersion: batch/v1
kind: CronJob
metadata:
name: my-cronjob
spec:
schedule: "0 2 * * *" # 2 AM daily
concurrencyPolicy: Forbid # don't run if previous still running
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
jobTemplate:
spec:
template:
spec:
restartPolicy: OnFailure
containers:
- name: job
image: my-worker:v1
command: ["python", "nightly_task.py"]
HorizontalPodAutoscaler
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-deployment
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
NetworkPolicy
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api-service # policy applies to these pods
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend # only allow from frontend pods
ports:
- protocol: TCP
port: 8080
ServiceAccount with RBAC
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-service-account
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-sa-pod-reader
namespace: default
subjects:
- kind: ServiceAccount
name: my-service-account
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io