π SECTION 1 β What is Kubernetes YAML?
Kubernetes YAML is the declarative configuration language used to define how Kubernetes should create, manage, and orchestrate resources within a cluster. It serves as the primary method for specifying the desired state of Kubernetes objects, allowing the Kubernetes control plane to reconcile the current state with the desired state automatically. YAML (YAML Ain't Markup Language) is chosen for its human-readable format, which uses indentation for structure rather than brackets or braces like JSON.
Kubernetes YAML files are used to define and manage a wide array of resources, including but not limited to:
- Pods: The smallest deployable units that encapsulate one or more containers.
- Deployments: Higher-level controllers that manage ReplicaSets to ensure a specified number of Pod replicas are running.
- Services: Abstractions that define a logical set of Pods and a policy to access them, typically over a network.
- ConfigMaps: Objects that store non-confidential configuration data in key-value pairs, which can be injected into Pods as environment variables, command-line arguments, or files in volumes.
- Secrets: Similar to ConfigMaps but for sensitive data like passwords, tokens, or keys; data is base64-encoded but not encrypted by default.
- Ingress: Resources that manage external access to Services, typically HTTP/HTTPS, providing load balancing, SSL termination, and name-based virtual hosting.
- NetworkPolicies: Specifications for network isolation and traffic control between Pods, using labels to define allowed/denied flows.
- PersistentVolumes (PV): Cluster-wide storage provisions that are independent of any Pod, representing a piece of storage in the cluster.
- PersistentVolumeClaims (PVC): Requests for storage by users, which bind to suitable PVs.
- StatefulSets: Controllers for managing stateful applications, ensuring stable network identities and ordered deployment/scaling.
- DaemonSets: Ensure a copy of a Pod runs on all (or some) nodes, useful for node-level agents like logging or monitoring daemons.
Kubernetes reads YAML files via commands like kubectl apply -f file.yaml and produces API objects that are stored in etcd (the cluster's key-value store). These objects are then acted upon by various Kubernetes components, such as the API Server (validates and persists), Controller Manager (reconciles state), and Scheduler (assigns Pods to nodes). YAML supports both single-document files and multi-document files separated by ---, enabling atomic application of multiple resources.
YAML files must be valid YAML syntax; invalid files will result in API server rejection. Kubernetes supports JSON as an alternative, but YAML is preferred for readability. All fields are case-sensitive, and Kubernetes enforces schema validation based on the specified apiVersion.
π§± SECTION 2 β BASIC STRUCTURE OF A KUBERNETES YAML FILE
All Kubernetes YAML files follow this core structure, which is mandatory for all API objects. This structure ensures consistency across resources and allows the API server to parse and validate the configuration declaratively:
apiVersion: <api-group/version>
kind: <ResourceType>
metadata:
name: <resource-name>
labels:
key: value
spec:
... resource-specific fields ...
This structure is derived from the Kubernetes API conventions, where apiVersion and kind identify the schema, metadata provides identity and auxiliary data, and spec defines the desired state. Omitting any top-level field (except where optional) will cause validation errors. The status field is auto-generated by Kubernetes and should not be included in YAML filesβit's read-only and reports the observed state.
Letβs break this down in exhaustive detail, including all possible keys, their types, values, and rules.
π· 1. apiVersion
Specifies which version of the Kubernetes API youβre using. This field is required and determines the group, version, and schema validation rules applied by the API server. It follows the format <group>/<version>, where the group is optional (defaults to core for basic resources) and the version indicates stability (e.g., v1 for stable).
Rules:
- Must be a valid string matching an existing API group/version registered in the cluster.
- Use
kubectl api-versionsto list available versions. - Mismatches cause immediate rejection (e.g., "no kind 'Pod' is registered for version 'v2'").
- For custom resources (CRDs), use
<group>/<version>likeexample.com/v1alpha1. - Versions evolve:
v1beta1βv1(stable); avoid betas in production.
Common apiVersions (expanded to include more resources for completeness; this is not exhaustiveβKubernetes has 100+ kinds):
| Resource Type | apiVersion | Group Notes | Stability Level | Common Use Case |
|---|---|---|---|---|
| Pod | v1 | core (empty group) | Stable | Basic container orchestration |
| Service | v1 | core | Stable | Network abstraction |
| ConfigMap | v1 | core | Stable | Non-sensitive config |
| Secret | v1 | core | Stable | Sensitive data storage |
| PersistentVolume | v1 | core | Stable | Cluster storage provision |
| PersistentVolumeClaim | v1 | core | Stable | Storage requests |
| Namespace | v1 | core | Stable | Logical isolation |
| LimitRange | v1 | core | Stable | Resource quota enforcement |
| ResourceQuota | v1 | core | Stable | Namespace resource limits |
| Deployment | apps/v1 | apps | Stable | Stateless app scaling |
| ReplicaSet | apps/v1 | apps | Stable | Pod replica management |
| StatefulSet | apps/v1 | apps | Stable | Stateful app orchestration |
| DaemonSet | apps/v1 | apps | Stable | Node-level daemons |
| Job | batch/v1 | batch | Stable | One-off tasks |
| CronJob | batch/v1 | batch | Stable | Scheduled tasks |
| Ingress | networking.k8s.io/v1 | networking.k8s.io | Stable | HTTP routing |
| NetworkPolicy | networking.k8s.io/v1 | networking.k8s.io | Stable | Pod network isolation |
| HorizontalPodAutoscaler | autoscaling/v2 | autoscaling | Stable | Scaling based on metrics |
| VerticalPodAutoscaler | autoscaling.k8s.io/v1 | autoscaling.k8s.io | Beta | Vertical scaling |
| Role | rbac.authorization.k8s.io/v1 | rbac.authorization.k8s.io | Stable | Namespace RBAC |
| ClusterRole | rbac.authorization.k8s.io/v1 | rbac.authorization.k8s.io | Stable | Cluster-wide RBAC |
| ServiceAccount | v1 | core | Stable | Pod identity for auth |
Values Types: String only. Invalid formats (e.g., numbers, booleans) cause parse errors.
π· 2. kind
Defines the type of object being created. This is a required string that, combined with apiVersion, uniquely identifies the resource schema. Kubernetes uses this to route the request to the appropriate API endpoint.
Rules:
- Case-sensitive; must match exactly (e.g., "Pod", not "pod").
- Use
kubectl api-resourcesto list all kinds and their shorthand. - Custom resources use CRD-defined kinds.
- Invalid kinds return "the server could not find the requested resource".
Examples (expanded list for completeness):
kind: Pod # Atomic container group
kind: Service # Network endpoint abstraction
kind: Deployment # ReplicaSet manager for updates
kind: ReplicaSet # Direct Pod replica controller
kind: StatefulSet # Ordered, stable Pod replicas
kind: DaemonSet # Per-node Pod replicas
kind: Job # Finite completion task
kind: CronJob # Scheduled Jobs
kind: ConfigMap # Key-value config store
kind: Secret # Encoded sensitive data
kind: Ingress # External HTTP access
kind: NetworkPolicy # Egress/ingress rules
kind: PersistentVolume # Storage provision
kind: PersistentVolumeClaim # Storage binding request
kind: Namespace # Virtual cluster partition
kind: Role # RBAC permissions in namespace
kind: ServiceAccount # Pod auth identity
Values Types: String only. Must be a registered kind in the apiVersion.
π· 3. metadata
Contains identifiers and auxiliary data about the object. This is required (though some fields are optional), and it's used for discovery, selection, and tracking. Metadata is immutable in parts (e.g., name after creation) and cluster-wide unique within namespaces.
Full Structure:
metadata:
name: <string> # Required: Unique identifier
generateName: <string> # Optional: Prefix for auto-generated name
namespace: <string> # Optional: Default to 'default'
uid: <string> # Auto-generated, read-only
resourceVersion: <string> # Auto-generated, for optimistic concurrency
generation: <integer> # Auto-incremented on spec changes
creationTimestamp: <string> # Auto-generated ISO8601 timestamp
deletionTimestamp: <string> # Set during graceful deletion
deletionGracePeriodSeconds: <integer> # Optional: Seconds before hard delete
labels: <map[string]string> # Optional: Key-value tags for selection
annotations: <map[string]string> # Optional: Non-identifying metadata
ownerReferences: <array> # Optional: Garbage collection links
finalizers: <array[string]> # Optional: Hooks before deletion
managedFields: <array> # Auto-generated: Managed field tracking
Detailed Field Breakdown:
| Field | Type | Required? | Possible Values | Meaning & Rules |
|---|---|---|---|---|
| name | string | Yes (unless generateName) | Alphanumeric + '-', '.' (63 chars max, DNS-1123 compliant) | Unique name within namespace. Immutable after creation. Use for kubectl get <name>. |
| generateName | string | No | Alphanumeric + '-', '.' (prefix, up to 63 chars) | If name omitted, auto-generates <generateName>-<random> (e.g., "myapp-abc123"). Useful for temp resources. |
| namespace | string | No | Valid namespace name (DNS-1123: lowercase alphanumeric + '-') | Logical isolation scope. Defaults to 'default'. Must exist or creation fails. |
| uid | string | No (auto) | UUID string (e.g., "a1b2c3d4-...") | Unique cluster-wide ID. Read-only. |
| resourceVersion | string | No (auto) | Opaque string (e.g., "12345") | ETag for concurrency control. Use in kubectl apply --server-side for updates. |
| generation | integer | No (auto) | Non-negative int (starts at 1) | Counts spec changes. Used for status reconciliation. |
| creationTimestamp | string | No (auto) | RFC3339 (e.g., "2025-11-28T10:00:00Z") | Object creation time. |
| deletionTimestamp | string | No (auto) | RFC3339 | Marks for deletion; triggers finalizers. |
| deletionGracePeriodSeconds | integer | No | Non-negative int (default 30) | Time to wait for graceful shutdown before force delete. |
| labels | map[string]string | No | Keys: DNS-1123 labels (63 chars); Values: strings (63 chars, no ':' in key) | Semantic tags (e.g., {"app": "nginx", "env": "prod"}). Used by selectors, GC. Keys unique per object. |
| annotations | map[string]string | No | Keys: arbitrary strings (up to 508 chars total per entry); Values: strings | Non-controlling metadata (e.g., {"description": "My app", "build/version": "v1.2"}). Not for selection. Total size < 1MB per object. |
| ownerReferences | array of objects | No | Each: {apiVersion: string, kind: string, name: string, uid: string, controller: bool, blockOwnerDeletion: bool} | Links child to parent (e.g., Pod owned by ReplicaSet). Enables cascading delete. |
| finalizers | array[string] | No | Strings like "kubernetes.io/pv-protection" | Blocks deletion until handler completes (e.g., PV release). Custom finalizers possible. |
| managedFields | array of objects | No (auto) | Each: {manager: string, operation: string, apiVersion: string, time: string, fieldsType: string, fieldsV1: object} | Tracks which manager (e.g., "kubectl") modified fields. For conflict resolution. |
Rules: Metadata fields are validated at creation/update. Labels/annotations keys must not start with special prefixes like "kubernetes.io/". Use kubectl label for post-creation updates.
π· 4. spec
This is the heart of the YAML β the declarative description of the desired state for the resource. It is required for most kinds and contains type-specific fields. The spec is reconciled by controllers to match reality, reported in status.
General Rules:
- Fields are nested objects, arrays, strings, ints, bools, or enums.
- Optional fields default to cluster values (e.g., restartPolicy: Always for Pods).
- Immutable fields (e.g., Deployment selector) cannot change without recreation.
- Validation: Schema-enforced (e.g., ports must be 1-65535).
- Every βkindβ has its own spec structure, detailed in Section 3. Examples:
- Deployment:
spec.replicas(int),spec.selector(LabelSelector),spec.template(PodTemplateSpec),spec.strategy(DeploymentStrategy). - Service:
spec.selector(map[string]string),spec.type(enum: ClusterIP/NodePort/LoadBalancer/ExternalName/Headless),spec.ports(array of ServicePort). - Pod:
spec.containers(array of Container),spec.volumes(array of Volume),spec.restartPolicy(enum: Always/OnFailure/Never),spec.activeDeadlineSeconds(int),spec.terminationGracePeriodSeconds(int),spec.dnsPolicy(enum: ClusterFirst/None/Default),spec.serviceAccountName(string),spec.securityContext(PodSecurityContext),spec.initContainers(array of Container),spec.ephemeralContainers(array of EphemeralContainer),spec.tolerations(array of Toleration),spec.affinity(Affinity),spec.schedulerName(string),spec.priorityClassName(string),spec.priority(int),spec.preemptionPolicy(enum: PreemptLowerPriority/Never),spec.enableServiceLinks(bool),spec.hostname(string),spec.subdomain(string),spec.nodeSelector(map[string]string),spec.runtimeClassName(string),spec.readinessGates(array of PodReadinessGate). - Ingress:
spec.rules(array of IngressRule),spec.tls(array of IngressTLS),spec.defaultBackend(IngressBackend),spec.ingressClassName(string).
- Deployment:
Spec fields vary by kind; see Section 3 for exhaustive breakdowns. Use kubectl explain <kind>.spec for CLI documentation.
π£ SECTION 3 β FULL BREAKDOWN OF COMMON KUBERNETES RESOURCES
This section provides exhaustive details for each resource, including ALL possible keys in spec (and metadata where relevant), their types, possible values, defaults, validation rules, and interactions. Examples are minimal to complex.
1οΈβ£ POD YAML FULL GUIDE
Pods represent running processes in the cluster. They are rarely created directly (use controllers like Deployments). Pods have phases: Pending, Running, Succeeded, Failed, Unknown.
Minimal Pod:
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: app
image: nginx:latest
ports:
- containerPort: 80
POD KEY FIELDS EXPLAINED (EXHAUSTIVE)
The spec for Pod includes:
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| containers | array[Container] | Yes | Min 1, max ~250 per Pod (cluster limit) | List of main containers. Each: name (string, unique, DNS-1123), image (string, e.g., "nginx:1.21"), imagePullPolicy (enum: IfNotPresent/Always/Never, default: IfNotPresent), command (array[string]), args (array[string]), workingDir (string), ports (array[ContainerPort]: name(string), containerPort(int 1-65535), protocol(enum TCP/UDP/SCTP)), env (array[EnvVar]: name(string), value(string), valueFrom{configMapKeyRef/secretKeyRef/fieldRef/resourceFieldRef}), envFrom (array[EnvFromSource]: configMapRef/secretRef/prefix(string)), resources {requests/limits: map{cpu(string e.g. "100m"), memory(string e.g. "128Mi"), ephemeral-storage(string), storage(string)}}, resizePolicy (array[ContainerResizePolicy]: resourceName(enum: Screen/Unknown), restartPolicy(enum Always/Never)), securityContext (ContainerSecurityContext: allowPrivilegeEscalation(bool), capabilities{add/drop array[string]}, privileged(bool), runAsUser(int), runAsGroup(int), runAsNonRoot(bool), seccompProfile{type(enum Localhost/RuntimeDefault/Unconfined), localhostProfile(string)}, apparmorProfile{type(string)}, selinuxOptions{user/role/type/level string}, windowsOptions{hostProcess(bool), gmsaCredentialSpec(string), gmsaCredentialSpecLogPath(string), runAsUserName(string)}, readOnlyRootFilesystem(bool), procMount(enum DefaultProcMount/ProcIsntMount)}, volumeMounts (array[VolumeMount]: name(string), mountPath(string), readOnly(bool), mountPropagation(enum HostToContainer/Bidrectional/None), subPath(string), subPathExpr(string), mountPropagation(bool? Wait, enum), filesystemType(string? Experimental)}, livenessProbe (Probe: exec{command array}, httpGet{path/port/host/scheme(string)}, tcpSocket{port}, grpc{port/service}, initialDelaySeconds(int), periodSeconds(int 1-300 default 10), timeoutSeconds(int 1-300 default 1), successThreshold(int 1-), failureThreshold(int 1-), terminationGracePeriodSeconds(int)}, readinessProbe (same as liveness), startupProbe (same, for slow starts), lifecycle {postStart/preStop: Handler{exec/httpGet/tcpSocket/grpc}}, stdin(bool), stdinOnce(bool), tty(bool), terminationMessagePath(string), terminationMessagePolicy(enum File/FallbackToLogsOnError), shareProcessNamespace(bool). |
| initContainers | array[Container] | No | Same as containers | Run sequentially before main containers. Share volumes/network but fail Pod if any fails. Use for setup (e.g., DB init). |
| ephemeralContainers | array[EphemeralContainer] | No | Similar to Container but name optional, targetContainerPath(string) for debug | Dynamic debugging containers (kubectl debug). Experimental in some versions. |
| volumes | array[Volume] | No | Various sources: emptyDir{medium(enum Memory), sizeLimit(string)}, hostPath{path(string), type(enum Directory/DirectoryOrCreate/BlockDevice/CharDevice/Socket/File/DirectoryOrCreate? Wait enum: Directory/DirectoryOrCreate/BlockDevice/CharDevice/Socket/File), storageClassName? No for hostPath}, persistentVolumeClaim{claimName(string), readOnly(bool)}, secret{secretName(string), items array{key/path/mode(int)}}, configMap{same}, projected{sources array: downwardAPI{fields array{fieldRef/metadata}}, secret/configMap/serviceAccountToken{...}, defaultMode(int)}, awsElasticBlockStore/nfs/iscsi/glusterfs/rbd/csi/flexVolume/photonPersistentDisk/azureDisk/vsphereVolume/quobyte/downwardAPI/emptyDir/hostPath/local/persistentVolumeClaim... (full list in API) | Pod-wide storage. Names unique. Some volumes Pod-lifecycle bound (emptyDir), others persistent. CSI for custom drivers. |
| restartPolicy | enum | No | Always (default), OnFailure, Never | Controls container restarts on exit. Always for long-running, Never for Jobs. |
| terminationGracePeriodSeconds | int | No | 30 (default), 0-3600? | Seconds to wait for shutdown before SIGKILL. Per-container override possible. |
| activeDeadlineSeconds | int | No | Positive int | Max Pod runtime; kills after. For runaway tasks. |
| dnsPolicy | enum | No | ClusterFirst (default), Default, None | DNS resolution: ClusterFirst uses cluster DNS, None requires spec.dnsConfig. |
| dnsConfig | PodDNSConfig | No (if dnsPolicy=None) | {nameservers array[string IPs], searches array[string domains], options array{DNSOption: name/value string}} | Custom DNS when policy=None. |
| serviceAccountName | string | No | Valid ServiceAccount or "default" | Pod's identity for API access. |
| serviceAccount | string | No (deprecated) | Same | Alias for serviceAccountName. |
| automountServiceAccountToken | bool | No | true (default) | Mounts token volume if true. |
| nodeSelector | map[string]string | No | Node labels (e.g., {"disktype": "ssd"}) | Restricts scheduling to matching nodes. |
| nodeName | string | No | Exact node name | Binds to specific node (overrides scheduler). |
| hostNetwork | bool | No | false | Uses host's network namespace. |
| hostPID | bool | No | false | Shares host PID namespace. |
| hostIPC | bool | No | false | Shares host IPC namespace. |
| shareProcessNamespace | bool | No | false | All containers share PID namespace. |
| securityContext | PodSecurityContext | No | {runAsUser/int, runAsGroup, runAsNonRoot/bool, supplementalGroups array[int], fsGroup/int (GID for volumes), fsGroupChangePolicy enum Always/OnRootMismatch, sysctls array{Sysctl: name/value string}, seLinuxOptions{user/role/type/level string}, windowsOptions{...}, fsGroup (int)} | Pod-level security (overrides container). fsGroup sets ownership on volumes. Sysctls unsafe, namespaced only. |
| imagePullSecrets | array[LocalObjectReference] | No | {name: string (Secret name)} | Secrets for private registries. |
| hostname | string | No | DNS-1123 label | Pod's hostname (requires hostNetwork=false). |
| subdomain | string | No | DNS-1123 subdomain | Pod's subdomain for full DNS (e.g., pod.subdomain.ns.svc.cluster.local). |
| affinity | Affinity | No | {nodeAffinity: NodeAffinity (requiredDuringSchedulingIgnoredDuringExecution/requiredDuringSchedulingIgnoredDuringExecution/preferred... with NodeSelectorTerms array{NodeSelectorRequirement: matchExpressions array{key op(values) string, values array string}, matchFields same}, podAffinity/AntiAffinity: PodAffinityTerm{labelSelector, topologyKey string, namespaces array, topologyKey string}}, preferredDuringSchedulingIgnoredDuringExecution array{weight int 1-100, preference Term}} | Scheduling preferences/requirements based on nodes/Pods. TopologyKey e.g. "kubernetes.io/hostname". |
| tolerations | array[Toleration] | No | {key string, operator enum Exists/Equal, value string, effect enum NoExecute/NoSchedule, tolerationSeconds int} | Allows scheduling on tainted nodes. Effect matches TaintEffect. |
| schedulerName | string | No | "default-scheduler" | Custom scheduler. |
| priorityClassName | string | No | Valid PriorityClass | QoS class for preemption. |
| priority | int | No | -1 to INT_MAX? | Direct priority (if no class). |
| preemptionPolicy | enum | No | PreemptLowerPriority (default) | Allows/denies preemption. |
| readinessGates | array[PodReadinessGate] | No | {conditionType string} | Custom readiness conditions. |
| runtimeClassName | string | No | Valid RuntimeClass | Container runtime selector (e.g., for gVisor). |
| enableServiceLinks | bool | No | true | Injects legacy env vars for Services. Deprecated. |
| topologySpreadConstraints | array[TopologySpreadConstraint] | No | {maxSkew int, topologyKey string, whenUnsatisfiable enum DoNotSchedule/ScheduleAnyway, labelSelector LabelSelector} | Spreads Pods across topologies (e.g., zones). |
FULL POD YAML (COMPLEX)
apiVersion: v1
kind: Pod
metadata:
name: demo-pod
namespace: default
labels:
app: demo
version: v1
annotations:
description: "Complex demo Pod with all fields"
scheduler.alpha.kubernetes.io/critical-path: "true" # Example annotation
ownerReferences:
- apiVersion: apps/v1
kind: ReplicaSet
name: demo-rs
uid: a1b2c3d4-...
controller: true
blockOwnerDeletion: true
spec:
restartPolicy: Always
terminationGracePeriodSeconds: 60
activeDeadlineSeconds: 3600
dnsPolicy: ClusterFirst
dnsConfig:
nameservers:
- 8.8.8.8
searches:
- mydomain.com
options:
- name: ndots
value: "2"
serviceAccountName: demo-sa
automountServiceAccountToken: true
nodeSelector:
disktype: ssd
nodeName: node-1
hostNetwork: false
hostPID: false
hostIPC: false
shareProcessNamespace: false
securityContext:
runAsUser: 1000
runAsGroup: 3000
runAsNonRoot: true
supplementalGroups: [2000]
fsGroup: 2000
fsGroupChangePolicy: "Always"
sysctls:
- name: kernel.shm_rmid_forced
value: "0"
seLinuxOptions:
level: "s0:c1,c2"
imagePullSecrets:
- name: private-reg-secret
hostname: demo-host
subdomain: demo-sub
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/os
operator: In
values:
- linux
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
preference:
matchExpressions:
- key: example.com/zone
operator: In
values:
- antarctica
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchLabels:
security: s1
topologyKey: topology.kubernetes.io/zone
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- s2
topologyKey: topology.kubernetes.io/zone
tolerations:
- key: "example-key"
operator: "Exists"
effect: "NoSchedule"
- key: "example-key2"
value: "example-value2"
operator: "Equal"
effect: "NoExecute"
tolerationSeconds: 300
schedulerName: my-scheduler
priorityClassName: high-priority
priority: 1000000
preemptionPolicy: PreemptLowerPriority
readinessGates:
- conditionType: "example.com/custom-ready"
runtimeClassName: my-runtime
enableServiceLinks: false
topologySpreadConstraints:
- maxSkew: 1
topologyKey: topology.kubernetes.io/zone
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: demo
initContainers:
- name: init-myservice
image: busybox:1.35
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
volumeMounts:
- name: workdir
mountPath: /work-dir
env:
- name: MY_NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
resources:
requests:
memory: "64Mi"
limits:
memory: "128Mi"
containers:
- name: main
image: nginx:1.21
imagePullPolicy: Always
command: ["/bin/sh"]
args: ["-c", "while true; do echo hello; sleep 30; done"]
workingDir: /app
ports:
- name: http
containerPort: 80
protocol: TCP
env:
- name: ENVIRONMENT
value: "production"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
envFrom:
- configMapRef:
name: app-config
- secretRef:
name: env-secret
- prefix: MY_
configMapRef:
name: special-config
resources:
requests:
cpu: "250m"
memory: "64Mi"
limits:
cpu: "500m"
memory: "128Mi"
resizePolicy:
- resourceName: Screen
restartPolicy: Always
securityContext:
allowPrivilegeEscalation: false
capabilities:
add: ["NET_BIND_SERVICE"]
drop: ["ALL"]
privileged: false
runAsUser: 1001
runAsNonRoot: true
readOnlyRootFilesystem: true
seccompProfile:
type: RuntimeDefault
apparmorProfile:
type: "example.com/profile"
volumeMounts:
- name: data
mountPath: /usr/share/nginx/html
readOnly: true
mountPropagation: HostToContainer
subPath: html
subPathExpr: "$(POD_NAME)"
livenessProbe:
httpGet:
path: /healthz
port: 80
host: localhost
scheme: HTTP
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
successThreshold: 1
failureThreshold: 3
terminationGracePeriodSeconds: 10
readinessProbe:
tcpSocket:
port: 80
initialDelaySeconds: 5
periodSeconds: 5
startupProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5
failureThreshold: 30
lifecycle:
postStart:
exec:
command: ["/bin/sh", "-c", "echo Hello > /usr/share/message"]
preStop:
httpGet:
path: /prestop
port: 8080
stdin: true
stdinOnce: true
tty: true
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: FallbackToLogsOnError
volumes:
- name: data
emptyDir:
medium: Memory
sizeLimit: 500Mi
- name: secret-volume
secret:
secretName: db-secret
items:
- key: username
path: my-group/my-user
mode: 0644
- name: config-volume
configMap:
name: app-config
items:
- key: special.key
path: ./local/path
mode: 0755
defaultMode: 0640
- name: projected-volume
projected:
sources:
- secret:
name: conditional-secret
items:
- key: friendly-data
path: friendly-data.txt
- downwardAPI:
items:
- path: "labels"
fieldRef:
fieldPath: metadata.labels
- path: "cpu_limit"
resourceFieldRef:
containerName: test-container
resource: limits.cpu
- configMap:
name: kube-root-ca.crt
items:
- key: root-ca.crt
path: ca-bundle.crt
defaultMode: 0644
- name: pv-volume
persistentVolumeClaim:
claimName: my-pvc
readOnly: false
- name: host-volume
hostPath:
path: /var/log
type: DirectoryOrCreate
Additional Notes: Pods are ephemeral; use controllers for management. SecurityContext fields interact (e.g., runAsNonRoot implies runAsUser !=0). Volumes can be projected for multi-source mounts. Probes support exec, HTTP, TCP, gRPC handlers.
2οΈβ£ DEPLOYMENT YAML FULL GUIDE
Deployments manage replicas, rolling updates, rollback, etc., by creating and updating ReplicaSets. They are for stateless apps.
Basic Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
DEPLOYMENT KEY FIELDS (EXHAUSTIVE)
spec fields:
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| replicas | int | No | 1- (default 1), 0 allowed for scale-to-zero | Desired Pod count. Negative invalid. |
| selector | LabelSelector | Yes | {matchLabels map[string]string, matchExpressions array{key string, operator enum In/NotIn/Exists/DoesNotExist, values array string}} | Must match template.labels exactly for creation; immutable. |
| template | PodTemplateSpec | Yes | Full Pod spec (metadata + spec) | Blueprint for Pods. Labels must match selector. |
| strategy | DeploymentStrategy | No | {type enum RollingUpdate/Recreate (default RollingUpdate), rollingUpdate {maxUnavailable int/str (default 25%), maxSurge int/str (default 25%)}, recreate? No extra} | Update method. RollingUpdate: concurrent Pod changes. maxUnavailable: Pods unavailable during update. |
| revisionHistoryLimit | int | No | 10 (default) | Retained old ReplicaSets for rollbacks. 0 disables. |
| minReadySeconds | int | No | 0 (default) | Seconds Pod must be ready before counting as available. |
| progressDeadlineSeconds | int | No | 600 (default) | Timeout for rollout; marks failed if exceeded. |
| paused | bool | No | false | Pauses updates until unpaused. |
Full Complex Example (abridged for length; includes all):
apiVersion: apps/v1
kind: Deployment
metadata:
name: complex-deploy
labels:
app: complex
spec:
replicas: 5
minReadySeconds: 10
revisionHistoryLimit: 5
progressDeadlineSeconds: 300
paused: false
selector:
matchLabels:
app: complex
matchExpressions:
- key: tier
operator: In
values: [frontend]
template:
metadata:
labels:
app: complex
tier: frontend
spec:
# Full Pod spec as above
containers:
- name: app
image: myapp:v1
# ... all container fields
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 20%
maxSurge: 1
Notes: Rollback with kubectl rollout undo. Strategy Recreate kills all before new. Selector immutability prevents label changes without delete/recreate.
3οΈβ£ SERVICE YAML FULL GUIDE
Services expose Pods to network via stable IP/endpoint. Types determine accessibility.
SERVICE TYPES (EXHAUSTIVE):
- ClusterIP (default, internal only): Virtual IP in cluster.
- NodePort: Exposes on node ports (30000-32767 default range).
- LoadBalancer: Provisions external LB (cloud-specific; MetalLB for bare-metal).
- ExternalName: Maps to external DNS (CNAME, no selectors/ports).
- Headless (ClusterIP=None): Returns Pod IPs directly (for stateful discovery).
ClusterIP
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: nginx
ports:
- port: 80
targetPort: 80
NodePort
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080 # Optional, auto 30000-32767
LoadBalancer
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80
loadBalancerIP: 1.2.3.4 # Optional external IP
ExternalName
spec:
type: ExternalName
externalName: my.database.example.com
# No ports/selector
SERVICE KEY FIELDS (EXHAUSTIVE)
spec fields:
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| type | enum | No | ClusterIP (default), NodePort, LoadBalancer, ExternalName | Exposure method. ExternalName ignores ports. |
| selector | map[string]string | No (for ExternalName) | Pod labels to endpoint | Dynamic endpoints. Changes tracked. Headless: none. |
| ports | array[ServicePort] | No | Each: name(string optional), port(int 1-65535), targetPort(int/str/name), protocol(enum TCP/UDP/SCTP default TCP), appProtocol(string) | Service port to Pod port mapping. Multiple allowed. targetPort can reference containerPort name. |
| clusterIP | string | No (auto) | "None" for headless, auto IPv4/IPv6, or static | Manual IP (admin only). Immutable except to None. |
| clusterIPs | array[string] | No (auto) | IPv4/IPv6 IPs | For dual-stack. |
| externalName | string | No (for ExternalName) | Valid DNS name | CNAME target. |
| externalTrafficPolicy | enum | No | Cluster (default), Local | Local: preserves source IP, may route suboptimally. |
| healthCheckNodePort | int | No (auto for LoadBalancer) | 1-65535 | Dedicated port for LB health checks. |
| loadBalancerIP | string | No | Valid IP | Requested external IP. |
| loadBalancerSourceRanges | array[string] | No | CIDRs (e.g., "10.0.0.0/8") | Allowed source IPs for LB. |
| externalIPs | array[string] | No | Node-external IPs | Binds Service to specific IPs. |
| ipFamily | enum | No | IPv4 (default), IPv6, PreferDualStack | IP family preference. |
| ipFamilies | array[enum] | No (auto) | IPv4/IPv6 | For dual-stack. |
| sessionAffinity | enum | No | None (default), ClientIP | Sticky sessions by client IP. |
| sessionAffinityConfig | SessionAffinityConfig | No (if affinity=ClientIP) | {clientIP: {timeoutSeconds int 1-86400 default 10800}} | Session timeout. |
| publishNotReadyAddresses | bool | No | false | Includes not-ready Pods in endpoints. |
| topologyKeys | array[string] | No | Topology keys (e.g., "topology.kubernetes.io/zone") | Client IP preference for topology-aware routing. |
Full Complex Example (abridged):
apiVersion: v1
kind: Service
metadata:
name: complex-svc
annotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"
spec:
type: LoadBalancer
selector:
app: complex
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
appProtocol: http
- name: metrics
port: 8080
targetPort: 8080
protocol: UDP
clusterIP: None # Headless
externalTrafficPolicy: Local
healthCheckNodePort: 32000
loadBalancerIP: 203.0.113.1
loadBalancerSourceRanges: ["10.0.0.0/8"]
externalIPs: ["203.0.113.10"]
ipFamily: PreferDualStack
ipFamilies: [IPv4, IPv6]
sessionAffinity: ClientIP
sessionAffinityConfig:
clientIP:
timeoutSeconds: 7200
publishNotReadyAddresses: true
topologyKeys:
- "topology.kubernetes.io/zone"
- "*"
Notes: Services watch selector for endpoint updates. Use kubectl expose for quick creation. For multi-port, specify name for clarity.
4οΈβ£ CONFIGMAP FULL GUIDE
Used to store non-secret configuration as key-value pairs. Can be consumed as env vars, files, or volumes. Data is plain text.
Full Structure:
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
DB_HOST: mysql
DB_PORT: "3306"
config.json: '{"key":"value"}' # Multi-line OK
binaryData: # Optional, base64 for binary
key: dmFsdWU= # base64 "value"
immutable: true # Optional, prevents updates
KEY FIELDS (EXHAUSTIVE)
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| data | map[string]string | No | Keys: alphanumeric + '-', '_' (253 chars); Values: strings (<1MB total) | Plain text key-values. Preferred for text. |
| binaryData | map[string]string | No | Same keys; Values: base64-encoded bytes | For non-text (e.g., images). Decoded on use. |
| immutable | bool | No | false (default) | If true, cannot update/delete; faster caching. Metadata immutable too. |
Notes: Create with kubectl create configmap. Consume in Pod: envFrom, volume (projeced/configMap). No validation on values.
5οΈβ£ SECRET FULL GUIDE
Used to store passwords/keys (Base64 encoded). Types for specific uses; data not encrypted at rest (use etcd encryption).
Full Structure:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque # Enum
data:
username: YWRtaW4= # base64 "admin"
password: cGFzc3dvcmQ= # base64 "password"
stringData: # Optional, plain text (auto base64'd)
username: admin
immutable: true
KEY FIELDS (EXHAUSTIVE)
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| type | enum | No | Opaque (default), kubernetes.io/service-account-token, kubernetes.io/dockerconfigjson, bootstrap.kubernetes.io/token, kubernetes.io/tls, kubernetes.io/ssh-auth, Opaque (generic) | Hints usage (e.g., tls for certs). Affects validation. |
| data | map[string]string | No | Keys: alphanumeric + '-', '_' (253); Values: base64 (<1MB total) | Encoded sensitive data. |
| stringData | map[string]string | No | Same keys; Plain strings (converted to data on save) | Convenience; not persisted. |
| immutable | bool | No | false | Like ConfigMap; prevents updates. |
Types Details:
- Opaque: Generic.
- kubernetes.io/service-account-token: Auto-created for SAs, with token/CA/namespace.
- kubernetes.io/dockerconfigjson: For .dockercfg ({auths: {registry: {username, password, ...}}}).
- kubernetes.io/tls: {tls.crt, tls.key}.
- bootstrap.kubernetes.io/token: For bootstrap (token-id, token-secret, etc.).
Notes: Base64 reversible; use external encryption. Consume like ConfigMap but for secrets. kubectl create secret generic.
6οΈβ£ INGRESS YAML FULL GUIDE
Ingress exposes HTTP/HTTPS using hostname rules. Requires Ingress Controller (e.g., NGINX).
Full Structure:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: web-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx # Optional
defaultBackend:
service:
name: fallback-svc
port:
number: 80
tls: # Optional
- hosts:
- demo.local
secretName: tls-secret
rules:
- host: demo.local
http:
paths:
- path: /
pathType: Prefix # Enum: Prefix/Exact/ImplementationSpecific
backend:
service:
name: nginx-service
port:
number: 80
resource: # Alternative to service
apiVersion: apps/v1
kind: Deployment
name: nginx-deploy
KEY FIELDS (EXHAUSTIVE)
spec fields:
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| ingressClassName | string | No | Valid IngressClass | Selects controller (e.g., "nginx"). |
| defaultBackend | IngressBackend | No | {service {name/port}, resource {apiVersion/kind/name}} | Catch-all for unmatched requests. |
| tls | array[TLS] | No | Each: {hosts array[string], secretName string} | HTTPS; secret type kubernetes.io/tls. Multiple SNI. |
| rules | array[HTTPIngressRuleValue] | No | Each: {host string (optional), http {paths array[HTTPIngressPath]}} | Host-based routing. Nil host = all hosts. |
HTTPIngressPath:
- path: string
- pathType: enum Prefix (matches prefix), Exact (exact match), ImplementationSpecific (controller-defined)
- backend: IngressBackend (service {name, port {number/name}}, resource for weighted)
Notes: Annotations controller-specific (e.g., rate limits). Paths ordered; first match wins. Use kubectl annotate for extras.
7οΈβ£ PERSISTENT VOLUMES (PV)
PV is cluster storage, provisioned statically or dynamically (via StorageClass).
Full Structure:
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
capacity:
storage: 1Gi
# Other: cpu? No, storage only
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain # Enum
storageClassName: standard
mountOptions: ["ro", "soft"] # Array string
nodeAffinity: # VolumeNodeAffinity
required:
nodeSelectorTerms:
- matchFields: [...] # Like nodeSelector
volumeMode: Filesystem # Enum Filesystem/Block
pvPhase: Available # Read-only, enum
# Driver-specific:
hostPath:
path: /data/pv1
type: DirectoryOrCreate
# Or awsElasticBlockStore, gcePersistentDisk, nfs, etc. (50+ drivers)
KEY FIELDS (EXHAUSTIVE)
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| capacity | map[string]Quantity | Yes | {storage: string e.g. "1Gi"/"1000GiB"} | Requested size; Quantity is decimal + unit (Ki/Mi/Gi/Ti, or bytes). |
| accessModes | array[enum] | No | ReadWriteOnce (RWO, single node RW), ReadOnlyMany (ROX, multi node RO), ReadWriteMany (RWX, multi RW), ReadWriteOncePod (RWOP, single Pod RW) | Compatibility; multiple possible but intersected on bind. |
| persistentVolumeReclaimPolicy | enum | No | Retain (default for static), Recycle (unsafe, deprecated), Delete (for dynamic) | Post-release: Retain (manual), Delete (cloud destroy). |
| storageClassName | string | No | "" (no class) or class name | For dynamic provisioning/selectors. |
| mountOptions | array[string] | No | FS mount flags (e.g., "ro,vers=3") | Per-volume mounts. |
| volumeMode | enum | No | Filesystem (default), Block | Block: raw device, no FS. |
| nodeAffinity | VolumeNodeAffinity | No | {required: NodeSelector (terms)} | Restricts binding to nodes. |
| # Driver fields (mutually exclusive) | One driver source required. Examples: | |||
| hostPath | HostPathVolumeSource | No | {path string, type enum Directory/DirectoryOrCreate/File/BlockDevice/CharDevice/Socket} | Local node path; ephemeral. |
| nfs | NFSVolumeSource | No | {server string, path string, readOnly bool} | Network FS. |
| persistentVolumeClaim | No, PV not from PVC. | |||
| csi | CSIVolumeSource | No | {driver string, volumeAttributes map, nodePublishSecretRef, volumeHandle string, readOnly bool, fsType string, controllerPublishSecretRef, controllerExpandSecretRef, ... (full CSI spec)} | Custom Storage Interface. |
Notes: PVs are cluster-scoped. Phase: Available/Pending/Bound/Released/Failed. Use StorageClass for dynamic.
8οΈβ£ PERSISTENT VOLUME CLAIM (PVC)
PVC requests storage; binds to PV.
Full Structure:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: standard
volumeMode: Filesystem
selector: # Optional
matchLabels:
disk: ssd
volumeName: my-pv # Bind to specific PV
dataSource: # For snapshots/clones
name: snapshot-1
kind: VolumeSnapshot
apiGroup: snapshot.storage.k8s.io
KEY FIELDS (EXHAUSTIVE)
| Field | Type | Required? | Possible Values/Defaults | Meaning & Rules |
|---|---|---|---|---|
| accessModes | array[enum] | No | RWO/ROX/RWX/RWOP | Requested; must match PV. |
| resources | ResourceRequirements | No | {requests {storage Quantity}, limits {storage Quantity}} | Min/max storage. limits optional. |
| storageClassName | string | No | "" or class | Selects PV class. |
| volumeMode | enum | No | Filesystem/Block | Requested mode. |
| selector | LabelSelector | No | Matches PV labels | Filters PVs. |
| volumeName | string | No | PV name | Binds to exact PV. |
| dataSource | TypedLocalObjectReference | No | {kind string, name string, apiGroup string} | Clone from snapshot/volume (e.g., CSI). |
Notes: Namespace-scoped. Status.phase: Pending/Bound. Delete PVC releases PV per reclaim policy.
π₯ SECTION 4 β KEY YAML RULES
β Indentation matters
Use spaces, not tabs (2 or 4 spaces common; consistent). Misindentation causes parse errors (e.g., key under wrong level).
β Lists start with -
Example:
containers:
- name: nginx # Array item
image: nginx
- name: sidecar
Nested lists: - - for deeper.
β Order of top-level keys MUST be:
The order is flexible in YAML (not enforced), but conventional and recommended for readability:
apiVersion: # First
kind: # Second
metadata: # Third
spec: # Fourth (status omitted)
API server ignores order, but tools like kubectl apply --prune assume it.
β Strings can be quoted or unquoted
value: "abc" # Quoted: preserves spaces, allows ':'
value: abc # Unquoted: fine for simple
value: 'single' # Single: literal
value: \| multi\n line # Block literal
Special: ~ for null, true/false bools, 123 int, 3.14 float auto-detected.
β Multi-document YAML uses ---
---
apiVersion: v1
kind: ConfigMap
metadata:
name: cm1
---
apiVersion: v1
kind: Secret
metadata:
name: sec1
kubectl apply -f dir/ processes all. End with optional ....
Additional Rules:
- Comments:
# This is a comment(line-based). - Anchors/Aliases:
&anchor/*anchorfor reuse (advanced). - No duplicate keys (last wins, but invalid in K8s).
- Total file size <1MB practical.
- Validate:
kubectl apply --dry-run=client -f file.yaml.
π SECTION 5 β SYMBOL MEANINGS IN YAML
| Symbol | Meaning | Example | Notes |
|---|---|---|---|
: |
key-value pair | key: value | Colon + space separates. |
- |
list item | - item1 - item2 |
Dash + space; indentation defines level. |
# |
comment | # Ignored | From # to EOL; no block comments. |
| `\ | ` | literal multiline text (preserves newlines) | key: \ |
> |
folded multiline text (folds to single line, newlines to space) | key: > line1 line2 |
Chops newlines; useful for logs. |
{} |
empty object/map | {} | Empty dict. |
[] |
empty list/array | [] | Empty array. |
~ |
null value | key: ~ | Explicit null. |
& |
anchor (reference) | &name value | Define alias target. |
* |
alias (reference) | *name | Reuse anchored value. |
! |
tag (custom type) | !str "123" | Rarely used in K8s. |
Advanced: Flow style {key: value, list: [1,2]} compact, but block preferred for readability.
π§ SECTION 6 β API OBJECT FLOW IN KUBERNETES
When you apply YAML (kubectl apply -f file.yaml or kubectl create --save-config):
- Client (kubectl): Validates YAML syntax, sends to API Server (with auth). β
- Kube API Server: Authenticates (RBAC), authorizes, validates schema (apiVersion/kind/spec), admits (webhooks), persists to etcd as JSON. β
- etcd: Stores object with metadata (uid, timestamps). Watchers notify. β
- Controller Manager: Reconciles (e.g., Deployment controller creates ReplicaSet β Pods). Loops: watch β diff desired/actual β act. β
- Scheduler: Assigns unbound Pods to nodes (filters: nodeSelector/tolerations; scores: affinity). β
- Kubelet (on node): Pulls Pod spec via API, runs containers (via CRI like containerd), reports status (probes, events). Mounts volumes, runs initContainers. β
- Status Updates: Kubelet β API β etcd. Controllers update observed state.
Error Flows: Validation fails β 400 Bad Request. Quotas β 429. Network issues β retries. Use kubectl describe for events.
Advanced Components: Cloud Controller Manager for cloud resources; Custom Controllers for CRDs.
π SECTION 7 β FULL BEST PRACTICES
β Always use labels
labels:
app.kubernetes.io/name: myapp # Standard prefix
app.kubernetes.io/version: v1.2.3
app.kubernetes.io/component: frontend
app.kubernetes.io/part-of: ecommerce
app.kubernetes.io/managed-by: helm
Follow semantic labeling (app.kubernetes.io/*). Use for all selectors.
β Donβt hardcode nodePort unless needed
Let Kubernetes auto-assign (type: NodePort). Reserve ranges via kube-apiserver flags.
β Use resources: for CPU/RAM limits
resources:
requests:
cpu: "100m" # 0.1 core
memory: "128Mi"
limits:
cpu: "200m"
memory: "256Mi"
Requests for scheduling; limits for OOMKill/cgroup. Set limits > requests for Burstable QoS.
β Use livenessProbe & readinessProbe
- Liveness: Restart if unhealthy (e.g., HTTP 200 on /healthz).
- Readiness: Exclude from Service if not ready (e.g., DB connection check).
- Startup: For slow starts (higher failureThreshold).
β Put multiple objects in one YAML using ---
Atomic apply; order-independent (API serializes).
β Additional Best Practices
- Namespaces: Isolate tenants; use ResourceQuota/LimitRange.
- RBAC: Least privilege; use Roles over ClusterRoles.
- Probes: timeoutSeconds >0; periodSeconds balanced (not too frequent).
-
Updates: Use
kubectl applyfor declarative;--recordfor history. -
Validation:
--dry-run=serverbefore apply. - Security: Non-root containers; no hostNetwork; PodSecurityStandards.
- Storage: Use StorageClasses; RWX for shared.
- Scaling: HPA for horizontal; VPA for vertical.
- Monitoring: Labels for Prometheus scraping.
- Helm/Kustomize: For templating; avoid raw YAML in prod.
- Immutable ConfigMaps/Secrets: Set immutable: true for caching.
- Affinity/Anti-Affinity: Spread across AZs; co-locate related.
- Taints/Tolerations: Dedicate nodes (e.g., GPU).
- Finalizers: Custom cleanup (e.g., webhook sync).
π― FINAL SUMMARY (COMPLETE MENTAL MODEL OF K8s YAML)
Every Kubernetes YAML has these 4 parts:
apiVersion β tells Kubernetes which API to use (e.g., apps/v1; schema enforcer)
kind β tells Kubernetes what youβre creating (e.g., Deployment; routes to handler)
metadata β name, labels, namespace (identity/selectors; e.g., app: nginx for matching)
spec β details for the object (the big part; desired state, e.g., replicas: 3, template Pod spec)
Every service type eventually routes traffic to Pods using selector labels:
LoadBalancer (external cloud IP) # Provisions LB
β (forwards to NodePorts or directly)
NodePort (30000-32767 on nodes) # Exposes on cluster nodes
β (proxies internally)
ClusterIP (virtual cluster IP) # Internal service discovery
β (endpoints watch Pods)
Pod IP (ephemeral, via selector) # Direct to matching labeled Pods
Headless Services return A/AAAA records for Pods.
Deployments create Pods (via ReplicaSets; handle updates/rollbacks)
Pods run containers (with env, volumes, probes; ephemeral units)
Services expose Pods (stable endpoints; types for access levels)
Ingress exposes Services (L7 routing, TLS termination)
ConfigMaps & Secrets configure Pods (injected data; separate concerns)
PVs/PVCs give Pods storage (decoupled persistence; dynamic provisioning)
NetworkPolicies secure traffic (default allow β explicit deny; label-based)
StatefulSets for ordered/stateful (stable identities: pod-0, pod-1)
DaemonSets for node agents (monitoring, logging)
Jobs/CronJobs for batch (completion-based)
This model scales: Controllers watch β Act β Status loop. Declarative wins over imperative.
π Done!
This is the COMPLETE, FULL, ALL-IN-ONE guide to Kubernetes YAML β covering all syntax, rules, keywords, meanings, and examples in exhaustive detail, with every key, value type, enum, and interaction documented.
Top comments (0)