interviewDeck

Your one-stop platform to prepare, practice and ace your interviews.

Loading your questions…

All Questions

Filters & tools

Docker & Kubernetes Interview Questions and Answers

23 hand-picked Docker & Kubernetes interview questions with detailed answers. Open the interactive version above to search, filter by difficulty, run code, bookmark questions and track your progress.

What is Docker and why is it used?

Docker is a containerization platform that packages an application with its dependencies (libraries, runtime, config) into a portable, isolated unit called a container. Containers share the host OS kernel but run in isolated namespaces.

Key benefits:

  • Consistency — "works on my machine" becomes "works everywhere."
  • Portability — same image runs on laptop, CI, cloud.
  • Isolation — apps don't interfere with each other.
  • Fast startup — seconds vs minutes for VMs.
  • Efficiency — lightweight compared to full VMs.

Docker components: Docker Engine (daemon), Dockerfile (build recipe), Image (read-only template), Container (running instance), Registry (Docker Hub, ECR, GCR).

docker run -d -p 8080:80 --name my-nginx nginx:alpine
docker ps
docker logs my-nginx

What is the difference between a Docker image and a container?

Image — a read-only, layered template built from a Dockerfile. Immutable snapshot of the app + dependencies. Stored in a registry (Docker Hub, ECR). Think of it as a class in OOP.

Container — a running (or stopped) instance of an image. Writable layer on top of the read-only image layers. Think of it as an object.

Relationship: one image → many containers. Stopping a container doesn't delete the image. Deleting a container removes only its writable layer.

Image layers are cached and shared — if two images use node:20-alpine as base, that layer is stored once on disk.

docker build -t myapp:1.0 .
docker run -d --name app1 myapp:1.0
docker run -d --name app2 myapp:1.0
docker images          # shows myapp:1.0 once
docker ps              # shows app1 and app2

Dockerfile best practices for production images.

Key practices for smaller, secure, fast-building images:

  • Use specific tagsnode:20.11-alpine not node:latest.
  • Prefer Alpine or distroless — smaller attack surface.
  • Order layers for cache — copy package.json before source code so dependency install is cached.
  • Combine RUN commands — fewer layers, smaller image.
  • Use .dockerignore — exclude node_modules, .git, tests.
  • Don't run as root — add USER nonroot.
  • One process per container — use Compose/K8s for multi-service apps.
  • Pin versions — reproducible builds.
  • Health checkHEALTHCHECK instruction.
  • No secrets in Dockerfile — use build args or runtime env vars.
FROM node:20.11-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production

FROM node:20.11-alpine
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
USER node
EXPOSE 3000
HEALTHCHECK CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "server.js"]

What are multi-stage Docker builds and why use them?

A multi-stage Dockerfile uses multiple FROM stages. Earlier stages compile/build; the final stage copies only the artifacts needed to run. Build tools, compilers, and source code are left behind.

Benefits:

  • Smaller images — a Go binary image can be 15 MB instead of 800 MB with the full SDK.
  • More secure — no compiler, shell, or source in production image.
  • Faster deploys — less to pull and scan.

Use COPY --from=stage-name to pull artifacts from a previous stage. Name stages with AS builder.

# Build stage
FROM golang:1.22-alpine AS builder
WORKDIR /src
COPY . .
RUN CGO_ENABLED=0 go build -o /app .

# Runtime stage — only the binary
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app /app
ENTRYPOINT ["/app"]

What is Docker Compose and when do you use it?

Docker Compose defines and runs multi-container applications from a single docker-compose.yml file. One command (docker compose up) starts all services, networks, and volumes together.

Use cases:

  • Local development — app + database + Redis + message broker.
  • Integration testing — spin up dependencies in CI.
  • Small deployments — single-host production (not for large scale — use K8s).

Key concepts: services (containers), networks (service discovery by name), volumes (persistent data), depends_on (startup order), environment / env_file.

services:
  api:
    build: .
    ports: ["8080:8080"]
    environment:
      DB_HOST: db
    depends_on: [db]
  db:
    image: postgres:16-alpine
    volumes: [pgdata:/var/lib/postgresql/data]
volumes:
  pgdata:

Docker containers vs Virtual Machines — key differences.

AspectContainerVM
IsolationProcess-level (namespaces, cgroups)Hardware-level (hypervisor)
OSShares host kernelFull guest OS per VM
StartupSecondsMinutes
SizeMBsGBs
DensityHundreds per hostTens per host
PortabilityImage runs anywhere with DockerHeavier, OS-specific

Containers are not as isolated as VMs — kernel exploits can affect the host. VMs are better for strong multi-tenant isolation. Many production setups use both: VMs as the host, containers inside.

What is Kubernetes and what problems does it solve?

Kubernetes (K8s) is an open-source container orchestration platform that automates deploying, scaling, and managing containerized applications across a cluster of machines.

Problems it solves:

  • Scheduling — places containers on nodes with available resources.
  • Self-healing — restarts crashed containers, replaces failed nodes.
  • Scaling — horizontal pod autoscaling based on CPU/memory/custom metrics.
  • Service discovery — stable DNS and load balancing for pods.
  • Rolling updates — zero-downtime deployments with rollback.
  • Config management — ConfigMaps and Secrets decoupled from images.
  • Storage orchestration — attach persistent volumes automatically.

Architecture: control plane (API server, scheduler, controller manager, etcd) + worker nodes (kubelet, kube-proxy, container runtime).

kubectl get nodes
kubectl get pods -A
kubectl cluster-info

Explain Pods, Deployments, and Services in Kubernetes.

Pod — the smallest deployable unit. One or more containers sharing network (same IP) and storage volumes. Ephemeral — pods die and are replaced, never "repaired."

Deployment — manages a ReplicaSet of identical pods. Declares desired replica count, container image, and update strategy. You almost never create pods directly — always use Deployments (or StatefulSets/DaemonSets).

Service — stable network endpoint for a set of pods. Types:

  • ClusterIP (default) — internal only, accessible within cluster.
  • NodePort — exposes on each node's IP at a static port.
  • LoadBalancer — provisions cloud LB (AWS ELB, GCP LB).
  • ExternalName — DNS CNAME to external service.

Flow: Deployment → creates ReplicaSet → creates Pods. Service → routes traffic to matching pods via label selector.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api
spec:
  replicas: 3
  selector:
    matchLabels: { app: api }
  template:
    metadata:
      labels: { app: api }
    spec:
      containers:
      - name: api
        image: myregistry/api:1.2.0
        ports: [{ containerPort: 8080 }]
---
apiVersion: v1
kind: Service
metadata:
  name: api-svc
spec:
  selector: { app: api }
  ports: [{ port: 80, targetPort: 8080 }]

ConfigMaps vs Secrets in Kubernetes.

Both decouple configuration from container images. Changes don't require rebuilding the image.

ConfigMap — non-sensitive config (app settings, feature flags, config files). Stored as plain text in etcd. Mount as env vars, files, or command-line args.

Secret — sensitive data (passwords, API keys, TLS certs). Base64-encoded in etcd (not encrypted by default — enable encryption at rest). Same consumption methods as ConfigMaps.

Consumption methods:

  • Environment variableenvFrom or valueFrom.
  • Volume mount — files appear in a directory; auto-updates on change (with sync period).

Best practice: use external secret managers (Vault, AWS Secrets Manager, Sealed Secrets) for production; K8s Secrets are convenient but not fully secure without additional hardening.

apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  LOG_LEVEL: debug
  app.properties: |
    server.port=8080
---
apiVersion: v1
kind: Secret
metadata:
  name: db-credentials
type: Opaque
data:
  password: cGFzc3dvcmQxMjM=  # base64
---
# In pod spec:
env:
- name: DB_PASSWORD
  valueFrom:
    secretKeyRef:
      name: db-credentials
      key: password

What are Kubernetes namespaces and how are they used?

Namespaces provide logical isolation within a single cluster. Resources in different namespaces are separated by name scope.

Common uses:

  • Environment separationdev, staging, prod.
  • Team isolationteam-payments, team-auth.
  • Resource quotas — limit CPU/memory per namespace.
  • RBAC scoping — grant permissions per namespace.

Default namespaces: default, kube-system (K8s components), kube-public, kube-node-lease.

Not a security boundary by itself — network policies and RBAC are needed for real isolation.

kubectl create namespace staging
kubectl apply -f deployment.yaml -n staging
kubectl get pods -n staging
kubectl config set-context --current --namespace=staging

Ingress vs LoadBalancer Service — when to use each?

LoadBalancer Service — provisions a cloud load balancer (one per Service). Each external service gets its own LB IP/DNS. Simple but expensive at scale (one LB per service).

Ingress — a single entry point (one LB) that routes HTTP/HTTPS traffic to multiple backend Services based on host name and path rules. Requires an Ingress Controller (nginx, Traefik, AWS ALB Ingress Controller).

FeatureLoadBalancerIngress
ProtocolsTCP/UDP (L4)HTTP/HTTPS (L7)
RoutingOne service per LBPath/host-based routing
TLS terminationAt cloud LBAt Ingress controller
CostOne LB per serviceOne LB for many services

Typical pattern: Ingress for HTTP APIs + web apps; LoadBalancer for non-HTTP (databases, gRPC with L4, MQTT).

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: app-ingress
spec:
  ingressClassName: nginx
  rules:
  - host: api.example.com
    http:
      paths:
      - path: /v1
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port: { number: 80 }

Liveness probe vs Readiness probe — what's the difference?

Both are health checks kubelet runs against containers, but they trigger different actions:

Liveness probe — "Is the container alive?" If it fails, kubelet restarts the container. Use when the app can deadlock or get stuck but the process is still running.

Readiness probe — "Is the container ready to serve traffic?" If it fails, the pod is removed from Service endpoints (no traffic) but NOT restarted. Use during startup (waiting for DB connection) or temporary overload.

Startup probe (bonus) — disables liveness/readiness until it passes. For slow-starting apps so liveness doesn't kill them during boot.

Probe types: httpGet, tcpSocket, exec (run command). Configure initialDelaySeconds, periodSeconds, failureThreshold.

livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 15
  periodSeconds: 10
readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5

How do rolling updates work in Kubernetes?

When you change a Deployment spec (e.g., new image tag), Kubernetes performs a rolling update — gradually replacing old pods with new ones with zero downtime (if configured correctly).

Strategy settings (spec.strategy.rollingUpdate):

  • maxSurge — how many extra pods above desired count during update (e.g., 25% or 1).
  • maxUnavailable — how many pods can be down during update (e.g., 0 for zero-downtime).

Process: create new ReplicaSet → scale up new pods → wait for readiness → terminate old pods → repeat until complete.

Rollback: kubectl rollout undo deployment/api — reverts to previous ReplicaSet. kubectl rollout history shows revisions.

Alternatives: Recreate (kill all, then start new — downtime), Blue/Green (switch Service selector), Canary (via Argo Rollouts or service mesh).

spec:
  replicas: 4
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    spec:
      containers:
      - name: api
        image: myregistry/api:2.0.0  # change triggers rollout

# Monitor:
kubectl rollout status deployment/api
kubectl rollout undo deployment/api

What is Horizontal Pod Autoscaler (HPA)?

HPA automatically scales the number of pod replicas in a Deployment (or ReplicaSet, StatefulSet) based on observed metrics.

Default metrics: CPU and memory utilization. With metrics-server installed, HPA compares current usage against targets.

Custom metrics: requests per second (via Prometheus adapter), queue depth, any metric from monitoring system.

Key fields:

  • minReplicas / maxReplicas — scaling bounds.
  • targetCPUUtilizationPercentage — e.g., 70% means scale up when average CPU across pods exceeds 70% of requested CPU.

Requirements: resource requests must be set on containers (HPA needs them to calculate utilization). Install metrics-server in the cluster.

Related: VPA (Vertical — adjusts requests/limits), Cluster Autoscaler (adds/removes nodes).

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Resource requests and limits in Kubernetes.

Every container should define requests and limits for CPU and memory:

Request — guaranteed resources reserved for the container. Scheduler uses requests to place pods on nodes with enough capacity.

Limit — maximum resources the container can use. Exceeding memory limit → OOMKilled. Exceeding CPU limit → throttled (not killed).

QoS classes (affects eviction priority):

  • Guaranteed — requests = limits for all containers. Last to be evicted.
  • Burstable — requests < limits. Default for most apps.
  • BestEffort — no requests/limits. First evicted under pressure.

CPU: 500m = 0.5 core. Memory: 256Mi, 1Gi.

resources:
  requests:
    cpu: 250m
    memory: 256Mi
  limits:
    cpu: 500m
    memory: 512Mi

Container networking basics in Docker and Kubernetes.

Docker networking:

  • bridge (default) — containers on same host communicate via virtual bridge. Port mapping (-p 8080:80) for external access.
  • host — container uses host network directly (no isolation).
  • overlay — multi-host networking (Docker Swarm).
  • none — no networking.

Kubernetes networking model:

  • Every pod gets a unique IP (flat network — no NAT between pods).
  • All pods can communicate without NAT (by default).
  • Agents on each node (kubelet + CNI plugin) configure networking.

CNI plugins (Container Network Interface): Calico, Flannel, Cilium, Weave — implement pod networking, IP allocation, and optionally network policies.

Network Policies — firewall rules for pods (allow/deny traffic by label, namespace, port). Default: all traffic allowed. Requires a CNI that supports policies (Calico, Cilium).

# NetworkPolicy: only allow frontend → api on port 8080
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: api-allow-frontend
spec:
  podSelector:
    matchLabels: { app: api }
  ingress:
  - from:
    - podSelector:
        matchLabels: { app: frontend }
    ports:
    - port: 8080

Why use Kubernetes for microservices?

Microservices introduce operational complexity — many small services to deploy, scale, monitor, and network. Kubernetes addresses this:

  • Independent scaling — scale the payment service to 10 replicas without touching the auth service.
  • Independent deployment — deploy one service without redeploying the entire monolith.
  • Service discovery — services find each other by DNS, no hardcoded IPs.
  • Resilience — self-healing restarts, health checks, pod disruption budgets.
  • Resource efficiency — bin-pack many services onto shared nodes.
  • Declarative config — GitOps: entire infra state in version-controlled YAML.
  • Portability — same manifests run on AWS EKS, GCP GKE, Azure AKS, on-prem.

Trade-offs: steep learning curve, operational overhead, overkill for small teams (<5 services). Alternatives: Docker Compose (dev), managed PaaS (Heroku, Cloud Run), ECS/Fargate.

OpenShift basics — Routes and Builds.

OpenShift is Red Hat's enterprise Kubernetes distribution with additional security, developer tools, and integrated CI/CD.

Routes — OpenShift's equivalent of Ingress. Exposes a Service externally with a hostname under the cluster domain (e.g., myapp.apps.cluster.example.com). Handles edge TLS termination. Simpler than configuring Ingress + cert-manager for basic cases.

oc expose svc/myapp --hostname=myapp.apps.cluster.example.com

Builds — built-in CI for creating container images from source:

  • Source-to-Image (S2I) — push source code, OpenShift builds the image using a builder image (no Dockerfile needed).
  • Docker build — build from Dockerfile in the repo.
  • Pipeline build — Jenkins pipeline integration.

Other OpenShift extras: Security Context Constraints (SCC), Projects (namespaces with extra isolation), built-in ImageStreams, oc CLI (wraps kubectl).

apiVersion: route.openshift.io/v1
kind: Route
metadata:
  name: myapp
spec:
  to:
    kind: Service
    name: myapp-svc
  port:
    targetPort: 8080
  tls:
    termination: edge

How does Jenkins CI/CD deploy to Kubernetes?

Typical pipeline flow:

  1. Checkout — clone source from Git.
  2. Build & Test — compile, run unit/integration tests.
  3. Build imagedocker build or Kaniko (no Docker daemon needed).
  4. Push image — tag with build number + git SHA, push to registry (ECR, GCR, Harbor).
  5. Deploy to K8s — update manifest image tag and apply, or use Helm upgrade.
  6. Verify — wait for rollout, run smoke tests.

Deployment methods:

  • kubectl apply — sed/envsubst to replace image tag in YAML.
  • Helm upgradehelm upgrade --install --set image.tag=$BUILD_NUMBER.
  • ArgoCD / Flux — GitOps: Jenkins commits manifest change, ArgoCD syncs.
  • Kubernetes plugin — dynamic Jenkins agents as K8s pods.
pipeline {
  agent any
  environment {
    IMAGE = "myregistry/api:${BUILD_NUMBER}"
  }
  stages {
    stage('Build') { steps { sh 'mvn package' } }
    stage('Docker') {
      steps {
        sh 'docker build -t $IMAGE .'
        sh 'docker push $IMAGE'
      }
    }
    stage('Deploy') {
      steps {
        sh 'kubectl set image deployment/api api=$IMAGE -n production'
        sh 'kubectl rollout status deployment/api -n production'
      }
    }
  }
}

How does persistent storage work in Kubernetes?

Containers are ephemeral — data in a container filesystem is lost when the pod dies. For databases, file uploads, and logs, use Persistent Volumes.

Key resources:

  • PV (PersistentVolume) — cluster-level storage resource (NFS, cloud disk, local SSD). Provisioned by admin or dynamically via StorageClass.
  • PVC (PersistentVolumeClaim) — pod's request for storage (size, access mode). Binds to a matching PV.
  • StorageClass — defines provisioner (e.g., gp3 on AWS EBS, standard on GCE). Enables dynamic provisioning.

Access modes: ReadWriteOnce (one node), ReadOnlyMany, ReadWriteMany (NFS, EFS).

Mount in pod via volumes and volumeMounts. PVC is referenced by name.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pg-data
spec:
  accessModes: [ReadWriteOnce]
  storageClassName: gp3
  resources:
    requests:
      storage: 20Gi
---
# In pod spec:
volumes:
- name: data
  persistentVolumeClaim:
    claimName: pg-data
containers:
- name: postgres
  volumeMounts:
  - name: data
    mountPath: /var/lib/postgresql/data

How do you troubleshoot a failing pod in Kubernetes?

Systematic debugging approach:

  1. Check pod statuskubectl get pods. Look for CrashLoopBackOff, ImagePullBackOff, Pending, OOMKilled.
  2. Describe podkubectl describe pod <name>. Events section shows scheduling failures, probe failures, volume mount errors.
  3. Check logskubectl logs <pod> or kubectl logs <pod> --previous for crashed container.
  4. Exec into containerkubectl exec -it <pod> -- /bin/sh to inspect filesystem, test connectivity.
  5. Check eventskubectl get events --sort-by=.lastTimestamp.
  6. Port-forwardkubectl port-forward pod/<name> 8080:8080 for local testing.

Common issues: wrong image tag (ImagePullBackOff), missing ConfigMap/Secret, insufficient resources (Pending), failed liveness probe (restart loop), app error (CrashLoopBackOff), OOM (increase memory limit).

kubectl get pods -n production
kubectl describe pod api-7d8f9-xk2lp -n production
kubectl logs api-7d8f9-xk2lp -n production --previous
kubectl exec -it api-7d8f9-xk2lp -n production -- sh
kubectl top pods -n production  # resource usage

Docker volumes and persistent data.

Container filesystems are ephemeral. Docker provides mechanisms for data that survives container restarts:

Volumes — managed by Docker, stored on host at /var/lib/docker/volumes/. Best choice for persistent data. Can be shared between containers. Work with volume drivers for remote storage (NFS, cloud).

Bind mounts — map a host directory into the container. Good for dev (live code reload) but tied to host path.

tmpfs mounts — stored in host memory. Fast, not persisted. For secrets or temp data.

In Compose: named volumes persist across docker compose down (unless -v flag). Bind mounts for source code in dev.

# Named volume
docker run -d -v pgdata:/var/lib/postgresql/data postgres:16

# Bind mount (dev)
docker run -v $(pwd)/src:/app/src myapp

# Compose
volumes:
  pgdata:  # named volume, managed by Docker

Blue-green vs canary deployment? And how does environment promotion (dev → QA → prod) work?

  • Blue-green — two full environments; deploy to the idle one (green), test it, then switch all traffic at once (LB/router flip). Instant rollback = flip back. Cost: double infrastructure; watch DB migrations that must serve both versions.
  • Canary — release to a small slice (5% of pods/users), watch error rates and latency, then ramp 25→50→100%. Limits blast radius; needs good metrics and often sticky routing.
  • Rolling (K8s default) — replace pods gradually; simplest, but no traffic-percentage control.

Promotion: build the image once, tag it, and promote the same immutable artifact through dev → QA → prod; only externalized config (ConfigMaps/Secrets/profiles) differs per environment. Rebuilding per environment invalidates all prior testing.

# canary with plain k8s: two deployments, one service selector
# app-stable: replicas 9,  labels app=api
# app-canary: replicas 1,  labels app=api, track=canary  -> ~10% traffic
# service selects app=api (both) — promote by scaling canary up, stable down