YAML plays a core role in Kubernetes, serving as the primary format for declarative configuration. Understanding YAML's application in Kubernetes is crucial for container orchestration and cloud-native development.
Basic Structure of Kubernetes YAML
Standard Kubernetes Resource YAML Structure
yamlapiVersion: apps/v1 # API version kind: Deployment # Resource type metadata: # Metadata name: nginx-deployment namespace: default labels: app: nginx spec: # Specification replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80
Core YAML Fields Explained
1. apiVersion
Specifies the Kubernetes API version, different resource types may use different API versions.
yaml# Common API versions apiVersion: v1 # Core resources (Pod, Service, ConfigMap) apiVersion: apps/v1 # Application resources (Deployment, StatefulSet, DaemonSet) apiVersion: networking.k8s.io/v1 # Network resources (Ingress, NetworkPolicy) apiVersion: batch/v1 # Batch resources (Job, CronJob) apiVersion: rbac.authorization.k8s.io/v1 # RBAC resources
2. kind
Specifies the Kubernetes resource type to create.
yaml# Common resource types kind: Pod kind: Service kind: Deployment kind: StatefulSet kind: DaemonSet kind: ConfigMap kind: Secret kind: Ingress kind: PersistentVolume kind: PersistentVolumeClaim
3. metadata
Contains resource metadata such as name, namespace, labels, annotations, etc.
yamlmetadata: name: my-app # Resource name (required) namespace: production # Namespace (defaults to default) labels: # Labels (for selectors and organization) app: my-app version: v1.0 environment: production annotations: # Annotations (for storing metadata) description: "Main application" contact: "team@example.com"
4. spec
Defines the desired state of the resource, this is the most complex part and varies by resource type.
Common Kubernetes Resource YAML Examples
Pod
yamlapiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" env: - name: ENVIRONMENT value: "production" volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: nginx-config
Deployment
yamlapiVersion: apps/v1 kind: Deployment metadata: name: web-app labels: app: web-app spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: web-app image: myapp:1.0 ports: - containerPort: 8080 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5
Service
yamlapiVersion: v1 kind: Service metadata: name: web-service spec: type: ClusterIP # ClusterIP, NodePort, LoadBalancer, ExternalName selector: app: web-app ports: - protocol: TCP port: 80 # Service port targetPort: 8080 # Target Pod port name: http - protocol: TCP port: 443 targetPort: 8443 name: https
ConfigMap
yamlapiVersion: v1 kind: ConfigMap metadata: name: app-config data: # Key-value pairs database.url: "postgresql://db.example.com:5432/myapp" cache.ttl: "3600" # File format nginx.conf: | server { listen 80; server_name localhost; location / { proxy_pass http://backend:8080; } }
Secret
yamlapiVersion: v1 kind: Secret metadata: name: app-secret type: Opaque data: # Base64 encoded values username: YWRtaW4= password: cGFzc3dvcmQ= stringData: # Plain text values (auto-encoded) api-key: "your-api-key-here"
Advanced YAML Features in Kubernetes
1. Multi-document YAML
Use --- separator to define multiple resources in one file.
yaml--- apiVersion: v1 kind: ConfigMap metadata: name: app-config data: config.yaml: | key: value --- apiVersion: apps/v1 kind: Deployment metadata: name: app-deployment spec: replicas: 2 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: myapp:latest
2. Using ConfigMap and Secret
yamlapiVersion: v1 kind: Pod metadata: name: config-demo spec: containers: - name: app image: myapp:latest env: # Read environment variable from ConfigMap - name: DATABASE_URL valueFrom: configMapKeyRef: name: app-config key: database.url # Read environment variable from Secret - name: API_KEY valueFrom: secretKeyRef: name: app-secret key: api-key # Mount ConfigMap as file volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: app-config
3. Resource Limits and Requests
yamlapiVersion: v1 kind: Pod metadata: name: resource-limits spec: containers: - name: app image: myapp:latest resources: requests: memory: "256Mi" cpu: "500m" limits: memory: "512Mi" cpu: "1000m"
4. Health Checks
yamlapiVersion: v1 kind: Pod metadata: name: health-check spec: containers: - name: app image: myapp:latest livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3
YAML Best Practices
1. Use Namespaces to Organize Resources
yamlapiVersion: v1 kind: Namespace metadata: name: production --- apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: production spec: # ...
2. Use Labels and Selectors
yamlmetadata: labels: app: myapp version: v1.0 environment: production tier: backend spec: selector: matchLabels: app: myapp environment: production
3. Use Annotations to Store Metadata
yamlmetadata: annotations: description: "Main application deployment" contact: "team@example.com" git-commit: "abc123" deployment-date: "2024-01-01"
4. Use Resource Limits
yamlresources: requests: memory: "256Mi" cpu: "500m" limits: memory: "512Mi" cpu: "1000m"
Common Errors and Solutions
1. Indentation Errors
yaml# ❌ Error: Inconsistent indentation spec: containers: - name: app image: myapp:latest ports: - containerPort: 8080 - containerPort: 8443 # Inconsistent indentation # ✅ Correct: Consistent indentation spec: containers: - name: app image: myapp:latest ports: - containerPort: 8080 - containerPort: 8443
2. Type Errors
yaml# ❌ Error: Port should be number ports: - containerPort: "8080" # String # ✅ Correct: Use number ports: - containerPort: 8080
3. Missing Required Fields
yaml# ❌ Error: Missing selector apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 # Missing selector # ✅ Correct: Include selector apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 selector: matchLabels: app: myapp
Tools and Validation
kubectl Validation
bash# Validate YAML syntax kubectl apply --dry-run=client -f deployment.yaml # Validate and view generated resources kubectl apply --dry-run=server -f deployment.yaml # View differences kubectl diff -f deployment.yaml
YAML Linter
bash# Use yamllint yamllint deployment.yaml # Use kubeval kubeval deployment.yaml
Mastering Kubernetes YAML usage is crucial for cloud-native application development, providing powerful declarative configuration capabilities.