Core Concepts · How it works

2 min read
Foundational6 min read
Rapid overview

How it works

Architecture Overview

Control Plane Components

ComponentPurpose
kube-apiserverFrontend for the Kubernetes control plane, exposes REST API
etcdConsistent, highly-available key-value store for cluster data
kube-schedulerWatches for newly created Pods and assigns nodes
kube-controller-managerRuns controller processes (Node, Job, EndpointSlice, ServiceAccount)
cloud-controller-managerLinks cluster to cloud provider's API

Node Components

ComponentPurpose
kubeletAgent that ensures containers are running in a Pod
kube-proxyNetwork proxy maintaining network rules on nodes
Container RuntimeSoftware responsible for running containers (containerd, CRI-O)

Workload Resources

Pods

The smallest deployable unit in Kubernetes.

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    ports:
    - containerPort: 80
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m"
      limits:
        memory: "128Mi"
        cpu: "500m"

Key Interview Points:

  • Pods are ephemeral - designed to be replaced, not repaired
  • Multi-container patterns: sidecar, ambassador, adapter
  • Init containers run before app containers
  • Pod lifecycle: Pending → Running → Succeeded/Failed

Deployments

Manages ReplicaSets and provides declarative updates for Pods.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25
        ports:
        - containerPort: 80

Deployment Strategies:

  • RollingUpdate (default): Gradually replaces old pods
  • Recreate: Terminates all existing pods before creating new ones

StatefulSets

For stateful applications requiring stable identities.

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: "postgres"
  replicas: 3
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:15
        volumeMounts:
        - name: data
          mountPath: /var/lib/postgresql/data
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteOnce"]
      resources:
        requests:
          storage: 10Gi

StatefulSet Guarantees:

  • Stable, unique network identifiers (pod-0, pod-1, pod-2)
  • Stable, persistent storage
  • Ordered, graceful deployment and scaling
  • Ordered, automated rolling updates

DaemonSets

Ensures all (or some) nodes run a copy of a Pod.

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd
spec:
  selector:
    matchLabels:
      name: fluentd
  template:
    metadata:
      labels:
        name: fluentd
    spec:
      tolerations:
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd
        image: fluentd:v1.16

Use Cases:

  • Log collectors (Fluentd, Filebeat)
  • Node monitoring (Prometheus node-exporter)
  • Storage daemons (Ceph, GlusterFS)

Jobs and CronJobs

apiVersion: batch/v1
kind: Job
metadata:
  name: database-migration
spec:
  ttlSecondsAfterFinished: 100
  backoffLimit: 4
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: migrate
        image: myapp:latest
        command: ["./migrate.sh"]
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: nightly-backup
spec:
  schedule: "0 2 * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: backup
            image: backup-tool:latest

Services and Networking

Service Types

TypeDescriptionUse Case
ClusterIPInternal cluster IP (default)Inter-service communication
NodePortExposes service on each Node's IP at static portDevelopment/debugging
LoadBalancerExternal load balancer (cloud provider)Production external access
ExternalNameMaps service to external DNS nameExternal service integration
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
    protocol: TCP

Ingress

HTTP/HTTPS routing to services.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-v1
            port:
              number: 80
      - path: /v2
        pathType: Prefix
        backend:
          service:
            name: api-v2
            port:
              number: 80
  tls:
  - hosts:
    - api.example.com
    secretName: tls-secret

NetworkPolicy

Control traffic flow at the IP address or port level.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-network-policy
spec:
  podSelector:
    matchLabels:
      app: api
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: database
    ports:
    - protocol: TCP
      port: 5432

Configuration and Secrets

ConfigMaps

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  DATABASE_HOST: "postgres.default.svc.cluster.local"
  LOG_LEVEL: "info"
  config.json: |
    {
      "feature_flags": {
        "new_ui": true
      }
    }

Usage Patterns:

  • Environment variables
  • Command-line arguments
  • Configuration files via volumes

Secrets

apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  username: YWRtaW4=  # base64 encoded
  password: cGFzc3dvcmQxMjM=
---
# Using in a Pod
spec:
  containers:
  - name: app
    envFrom:
    - secretRef:
        name: db-credentials
    # Or individual keys:
    env:
    - name: DB_PASSWORD
      valueFrom:
        secretKeyRef:
          name: db-credentials
          key: password

Secret Types:

  • Opaque - arbitrary user-defined data
  • kubernetes.io/tls - TLS certificates
  • kubernetes.io/dockerconfigjson - Docker registry credentials
  • kubernetes.io/service-account-token - Service account tokens

Storage

PersistentVolume and PersistentVolumeClaim

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv-storage
spec:
  capacity:
    storage: 10Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: standard
  hostPath:
    path: /data/pv
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-storage
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi
  storageClassName: standard

Access Modes:

  • ReadWriteOnce (RWO) - mounted read-write by single node
  • ReadOnlyMany (ROX) - mounted read-only by many nodes
  • ReadWriteMany (RWX) - mounted read-write by many nodes

Reclaim Policies:

  • Retain - manual reclamation
  • Delete - automatic deletion
  • Recycle - basic scrub (deprecated)

StorageClass

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-storage
provisioner: kubernetes.io/aws-ebs
parameters:
  type: gp3
  iopsPerGB: "50"
reclaimPolicy: Delete
allowVolumeExpansion: true
volumeBindingMode: WaitForFirstConsumer

Resource Management

Resource Requests and Limits

resources:
  requests:
    memory: "256Mi"
    cpu: "500m"
  limits:
    memory: "512Mi"
    cpu: "1000m"

Interview Key Points:

  • Requests: Guaranteed resources, used for scheduling
  • Limits: Maximum resources, enforced by kubelet
  • CPU is compressible (throttled), memory is not (OOMKilled)
  • QoS Classes: Guaranteed, Burstable, BestEffort

LimitRange

Enforces default limits on a namespace.

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-memory-limits
spec:
  limits:
  - default:
      memory: "512Mi"
      cpu: "500m"
    defaultRequest:
      memory: "256Mi"
      cpu: "250m"
    max:
      memory: "1Gi"
      cpu: "1"
    min:
      memory: "128Mi"
      cpu: "100m"
    type: Container

ResourceQuota

Limits aggregate resource consumption per namespace.

apiVersion: v1
kind: ResourceQuota
metadata:
  name: compute-quota
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    pods: "50"
    services: "10"
    persistentvolumeclaims: "10"

Scheduling

Node Selectors

spec:
  nodeSelector:
    disktype: ssd
    kubernetes.io/os: linux

Affinity and Anti-Affinity

spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: topology.kubernetes.io/zone
            operator: In
            values:
            - us-east-1a
            - us-east-1b
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchLabels:
              app: web
          topologyKey: kubernetes.io/hostname

Taints and Tolerations

# Taint a node
kubectl taint nodes node1 key=value:NoSchedule
# Pod toleration
spec:
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "value"
    effect: "NoSchedule"

Taint Effects:

  • NoSchedule - New pods won't be scheduled
  • PreferNoSchedule - System will try to avoid scheduling
  • NoExecute - Existing pods will be evicted

Common kubectl Commands

# Context and configuration
kubectl config get-contexts
kubectl config use-context <context-name>

# Resource management
kubectl get pods -n <namespace> -o wide
kubectl describe pod <pod-name>
kubectl logs <pod-name> -c <container-name> --previous
kubectl exec -it <pod-name> -- /bin/sh

# Debugging
kubectl get events --sort-by='.lastTimestamp'
kubectl top pods
kubectl top nodes

# Rollouts
kubectl rollout status deployment/<name>
kubectl rollout history deployment/<name>
kubectl rollout undo deployment/<name> --to-revision=2

# Scaling
kubectl scale deployment <name> --replicas=5
kubectl autoscale deployment <name> --min=2 --max=10 --cpu-percent=80

See also