InterviewHack.ai
Empezar gratis
Blog/Kubernetes Interview Questions — 40 with Real Answers

Kubernetes Interview Questions — 40 with Real Answers

September 16, 2026

kubernetesdevops-engineer

40 Kubernetes interview questions asked at top tech companies: pods, deployments, services, ingress, RBAC, HPA, persistent volumes. Answers with kubectl commands and YAML.

Kubernetes Interview Questions — 40 with Real Answers

If you are interviewing for a DevOps engineer, platform engineer, SRE, or backend engineering role at any company running cloud-native infrastructure, you will be asked Kubernetes questions. Not trivia — working questions that separate engineers who have operated clusters under pressure from engineers who have only read the docs.

This guide covers 40 questions organized by topic, each with the answer an experienced engineer would give, the YAML or kubectl command you should be ready to write on a whiteboard, and what the interviewer is actually testing.


Cluster Architecture

1. Explain the Kubernetes control plane. What happens when you run kubectl apply?

The control plane consists of four main components: the API server (single entry point for all REST operations), etcd (distributed key-value store that is the cluster's source of truth), the scheduler (assigns pods to nodes based on resource requests and constraints), and the controller manager (runs reconciliation loops for Deployments, ReplicaSets, etc.).

When you run kubectl apply -f deployment.yaml:

  1. 1kubectl sends a PATCH or PUT request to the API server with your manifest.
  2. 2The API server authenticates, authorizes (RBAC), and validates the object, then persists it to etcd.
  3. 3The Deployment controller (inside controller manager) detects the new/changed Deployment and creates or updates a ReplicaSet.
  4. 4The ReplicaSet controller creates Pod objects in etcd.
  5. 5The scheduler watches for unscheduled pods, picks a node, and writes the node name into the pod's spec.
  6. 6The kubelet on the chosen node watches for pods assigned to it, pulls images, and starts containers via the container runtime (containerd or CRI-O).

What interviewers test: whether you understand declarative reconciliation versus imperative commands. The cluster always moves toward desired state — nothing runs commands, everything reacts to state changes in etcd.


2. What is the difference between a kubelet and kube-proxy?

The kubelet runs on every node and is responsible for managing the pod lifecycle: it watches for pods assigned to its node, ensures containers are running and healthy, reports node and pod status back to the API server, and enforces liveness/readiness probes.

kube-proxy runs on every node and is responsible for network rules. It watches for Service and Endpoint objects and programs iptables (or IPVS) rules so that traffic sent to a ClusterIP or NodePort gets forwarded to the correct pod IPs. In modern clusters using a CNI plugin like Cilium, kube-proxy is often replaced entirely.

What interviewers test: whether you conflate node-level compute management with node-level networking.


Pods

3. What is a Pod and when would you run multiple containers in one?

A Pod is the smallest deployable unit in Kubernetes. It is a group of one or more containers that share the same network namespace (same IP, same loopback), the same IPC namespace, and optionally the same PID namespace. Containers in a pod communicate over localhost.

You run multiple containers in a pod only when tight coupling is required. The canonical patterns are:

  • Sidecar: a helper container that enhances the main container (e.g., Envoy proxy, log shipper like Fluent Bit).
  • Init container: runs to completion before the main container starts (e.g., wait for a database to be ready, seed configuration).
  • Ambassador: proxies outbound traffic from the main container to an external service.
yaml
apiVersion: v1
kind: Pod
metadata:
  name: app-with-sidecar
spec:
  initContainers:
    - name: wait-for-db
      image: busybox:1.35
      command: ['sh', '-c', 'until nc -z db-service 5432; do sleep 2; done']
  containers:
    - name: app
      image: myapp:1.0
      ports:
        - containerPort: 8080
    - name: log-forwarder
      image: fluent/fluent-bit:2.1
      volumeMounts:
        - name: varlog
          mountPath: /var/log
  volumes:
    - name: varlog
      emptyDir: {}

What interviewers test: understanding of pod networking, and whether you know init containers are not sidecars (init containers terminate; sidecars run alongside the main process).


4. How do liveness and readiness probes differ? What happens if each fails?

A readiness probe gates traffic. If it fails, the pod is removed from the Endpoints list for its Service — new traffic stops being sent to it, but the pod keeps running. This is for "not ready to serve" situations: warming up a cache, loading a large model, waiting for a dependency.

A liveness probe gates restart. If it fails, the kubelet kills and restarts the container (subject to restartPolicy). This is for "stuck" situations: deadlocked goroutines, crashed-but-not-exited processes.

A startup probe is a third type: it delays liveness/readiness checks until the container passes startup. Critical for slow-starting apps to avoid premature liveness kills.

yaml
livenessProbe:
  httpGet:
    path: /healthz
    port: 8080
  initialDelaySeconds: 10
  periodSeconds: 10
  failureThreshold: 3

readinessProbe:
  httpGet:
    path: /ready
    port: 8080
  initialDelaySeconds: 5
  periodSeconds: 5
  failureThreshold: 2

startupProbe:
  httpGet:
    path: /healthz
    port: 8080
  failureThreshold: 30
  periodSeconds: 10

Common mistake: setting initialDelaySeconds too low for liveness probes, causing a restart loop on slow-starting apps. Use startup probes instead.


5. What are resource requests and limits? What happens when a container exceeds its memory limit?

Requests are what the scheduler uses for placement — it reserves that amount of CPU/memory on the node. Limits are the runtime enforcement ceiling.

  • CPU: limits are enforced via CPU throttling (cgroups). The container is not killed; it is slowed.
  • Memory: limits are enforced by the Linux OOM killer. If a container exceeds its memory limit, the kernel sends SIGKILL (OOM kill), and Kubernetes restarts it.
yaml
resources:
  requests:
    cpu: "250m"
    memory: "256Mi"
  limits:
    cpu: "1"
    memory: "512Mi"

A container without limits runs as Burstable or BestEffort class. BestEffort pods (no requests or limits) are the first to be evicted under node memory pressure.

What interviewers test: QoS classes (Guaranteed = requests equal limits; Burstable = requests set but not equal to limits; BestEffort = no requests or limits) and their eviction priority.


Deployments and ReplicaSets

6. What is the difference between a Deployment and a ReplicaSet?

A ReplicaSet ensures that a specified number of pod replicas are running at any time. It has no concept of rollouts or history.

A Deployment manages ReplicaSets. It provides declarative updates with rollout strategies (RollingUpdate, Recreate), rollback capability, and pause/resume. When you update a Deployment's pod template, it creates a new ReplicaSet and scales it up while scaling the old one down (for RollingUpdate).

You almost never create ReplicaSets directly. You create Deployments.

bash
# Check rollout status
kubectl rollout status deployment/my-app

# View rollout history
kubectl rollout history deployment/my-app

# Roll back to previous version
kubectl rollout undo deployment/my-app

# Roll back to a specific revision
kubectl rollout undo deployment/my-app --to-revision=2

What interviewers test: the layered abstraction. A Deployment is a controller for ReplicaSets, which is a controller for Pods.


7. How does a RollingUpdate strategy work? What do maxSurge and maxUnavailable control?

During a rolling update, Kubernetes incrementally replaces old pods with new ones.

  • maxUnavailable: how many pods can be unavailable at once (absolute number or percentage). Set to 0 to guarantee full capacity during the rollout — but this requires maxSurge > 0.
  • maxSurge: how many pods above the desired replica count can temporarily exist. Allows spinning up new pods before killing old ones.
yaml
spec:
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  replicas: 4

With replicas: 4, maxSurge: 1, maxUnavailable: 0: Kubernetes spins up 1 new pod (5 total), waits for it to pass readiness, then terminates 1 old pod (back to 4). Repeats until all pods are on the new version.

Common mistake: leaving both at the default (25%) without thinking about it. For latency-sensitive services, set maxUnavailable: 0.


8. How do you perform a canary deployment in Kubernetes without a service mesh?

A simple label-selector trick: have two Deployments with the same pod label that your Service selects on, but in different proportions.

yaml
# Service selects on app: my-app
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-stable
spec:
  replicas: 9
  selector:
    matchLabels:
      app: my-app
      version: stable
  template:
    metadata:
      labels:
        app: my-app
        version: stable
    spec:
      containers:
        - name: app
          image: myapp:1.0
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-canary
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
      version: canary
  template:
    metadata:
      labels:
        app: my-app
        version: canary
    spec:
      containers:
        - name: app
          image: myapp:1.1

The Service selects app: my-app — 10% of traffic goes to the canary pod. Once validated, promote the canary to stable and scale down the old deployment.

For header-based or cookie-based canaries, you need an Ingress controller (like nginx) or a service mesh (Istio/Linkerd).


StatefulSets and DaemonSets

9. When do you use a StatefulSet instead of a Deployment?

Use a StatefulSet when pods need:

  1. 1Stable network identities: pods get predictable names (app-0, app-1, app-2) and DNS entries (app-0.my-service.namespace.svc.cluster.local).
  2. 2Stable persistent storage: each pod gets its own PersistentVolumeClaim that survives pod restarts and rescheduling.
  3. 3Ordered startup/shutdown: pods start in order (0 → 1 → 2) and terminate in reverse order.

Use cases: databases (Postgres, MySQL, Cassandra), message brokers (Kafka, ZooKeeper), Elasticsearch clusters.

yaml
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

What interviewers test: understanding of why stateful workloads cannot use Deployments — pod identity must be stable across restarts because peers reference each other by hostname.


10. What is a DaemonSet and when would you use one?

A DaemonSet ensures that exactly one pod runs on every node (or every node matching a node selector). When nodes are added to the cluster, the DaemonSet controller automatically schedules a pod on them.

Use cases:

  • Log collection agents (Fluent Bit, Filebeat) — need access to host log paths
  • Metrics collection (node-exporter) — need host network metrics
  • Security agents (Falco, Datadog agent) — need kernel-level access
  • CNI plugins and kube-proxy themselves are often managed as DaemonSets
yaml
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: node-exporter
  namespace: monitoring
spec:
  selector:
    matchLabels:
      name: node-exporter
  template:
    metadata:
      labels:
        name: node-exporter
    spec:
      hostNetwork: true
      hostPID: true
      containers:
        - name: node-exporter
          image: prom/node-exporter:v1.6.1
          ports:
            - containerPort: 9100
              hostPort: 9100
          securityContext:
            privileged: true

Common mistake: confusing DaemonSets with Deployments with replicas: N where N equals node count. A DaemonSet is node-aware; a Deployment is not.


Services and Networking

11. What are the four Service types and when do you use each?

  • ClusterIP (default): exposes the service on a cluster-internal IP. Only reachable within the cluster. Use for inter-service communication.
  • NodePort: exposes the service on every node's IP at a static port (30000–32767). Externally reachable but bypasses load balancing. Useful for development or baremetal clusters without a cloud load balancer.
  • LoadBalancer: provisions an external load balancer in the cloud provider (AWS NLB/ALB, GCP LB, Azure LB). The standard way to expose services externally in cloud environments.
  • ExternalName: maps the service to a DNS name (e.g., db.example.com). No proxying; returns a CNAME. Useful for pointing cluster services to external resources.
yaml
apiVersion: v1
kind: Service
metadata:
  name: my-app
spec:
  type: LoadBalancer
  selector:
    app: my-app
  ports:
    - port: 80
      targetPort: 8080

What interviewers test: why you would NOT use LoadBalancer for every service (cost: each LoadBalancer provisions a cloud resource). Use ClusterIP + Ingress for most HTTP workloads.


12. What is a headless service and why would you use it?

A headless service has clusterIP: None. Instead of returning a single virtual IP, DNS queries for the service return the individual pod IPs directly. This enables clients to do their own load balancing or to connect to specific pods by name.

StatefulSets require a headless service so that each pod gets a stable DNS record: pod-name.service-name.namespace.svc.cluster.local.

yaml
apiVersion: v1
kind: Service
metadata:
  name: cassandra
spec:
  clusterIP: None
  selector:
    app: cassandra
  ports:
    - port: 9042

What interviewers test: the distinction between virtual-IP-based services (kube-proxy programs iptables rules) and headless services (pure DNS).


13. What is an Ingress and how does it differ from a Service?

A Service operates at Layer 4 (TCP/UDP) — it routes by IP and port. An Ingress operates at Layer 7 (HTTP/HTTPS) — it routes by hostname and path, terminates TLS, and can apply middleware (rate limiting, auth).

An Ingress object is just a configuration spec. It requires an Ingress controller (nginx-ingress, Traefik, Kong, AWS ALB controller) to actually implement the rules.

yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: tls-secret
  rules:
    - host: app.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

What interviewers test: that you know Ingress needs a controller, and that you understand TLS termination at the Ingress level (not the pod level).


ConfigMaps and Secrets

14. How do you inject configuration into a pod? What are the tradeoffs between env vars and volume mounts?

Two mechanisms: environment variables and volume mounts.

Environment variables:

yaml
envFrom:
  - configMapRef:
      name: app-config
  - secretRef:
      name: app-secrets

Environment variables are set at container start — a ConfigMap update does NOT propagate to running pods without a restart.

Volume mount:

yaml
volumes:
  - name: config-vol
    configMap:
      name: app-config
volumeMounts:
  - name: config-vol
    mountPath: /etc/config

Volume-mounted ConfigMaps are updated automatically (with a ~1 minute kubelet sync delay). Useful for apps that watch config files (nginx, feature flags).

Tradeoffs:

  • Env vars: simpler, but immutable at runtime and leak through process inspection (/proc/PID/environ)
  • Volumes: dynamic updates, but file path coupling and slightly more complex

What interviewers test: knowing the update semantics. Many engineers assume ConfigMap env vars hot-reload — they do not.


15. How are Secrets different from ConfigMaps? Are Secrets actually secure?

Functionally, Secrets are nearly identical to ConfigMaps — same injection mechanisms, same volume mount behavior. The differences:

  • Secrets are base64-encoded (NOT encrypted by default) in etcd.
  • Kubernetes marks them as sensitive: they are not shown in kubectl describe by default, they are stored in tmpfs on nodes (not written to disk), and RBAC should restrict access.

Are they secure? Not by default. Anyone with kubectl get secret -n production RBAC access can base64-decode them. Real Secret security requires:

  1. 1etcd encryption at rest (EncryptionConfiguration with AES-GCM or KMS provider)
  2. 2External secret managers: AWS Secrets Manager + External Secrets Operator, HashiCorp Vault + Vault Agent Injector, or GCP Secret Manager.
  3. 3RBAC: least-privilege access to secrets per namespace.
bash
# Create a secret imperatively (avoid storing in shell history)
kubectl create secret generic db-creds \
  --from-literal=username=admin \
  --from-literal=password='S3cur3P@ss'

# Inspect (base64 decode to see plaintext)
kubectl get secret db-creds -o jsonpath='{.data.password}' | base64 -d

What interviewers test: that you know base64 is encoding, not encryption, and that you can describe a production-grade secrets management approach.


RBAC and Security

16. Explain Kubernetes RBAC. What are the four key objects?

RBAC (Role-Based Access Control) controls who can do what to which resources.

  • Role: namespaced. Grants permissions within a namespace.
  • ClusterRole: cluster-wide. Grants permissions across all namespaces or on non-namespaced resources (nodes, PersistentVolumes).
  • RoleBinding: binds a Role or ClusterRole to subjects (users, groups, ServiceAccounts) within a namespace.
  • ClusterRoleBinding: binds a ClusterRole to subjects cluster-wide.
yaml
# Role: allows reading pods in "staging" namespace
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: staging
  name: pod-reader
rules:
  - apiGroups: [""]
    resources: ["pods", "pods/log"]
    verbs: ["get", "list", "watch"]
---
# Bind it to a ServiceAccount
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-binding
  namespace: staging
subjects:
  - kind: ServiceAccount
    name: ci-runner
    namespace: staging
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
bash
# Test if a ServiceAccount can perform an action
kubectl auth can-i list pods --namespace=staging \
  --as=system:serviceaccount:staging:ci-runner

What interviewers test: least-privilege principle, the difference between Role and ClusterRole, and whether you know kubectl auth can-i for debugging.


17. What is a PodSecurityContext and what security settings should you always configure?

securityContext at the pod or container level controls Linux security settings for the running process.

yaml
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        capabilities:
          drop:
            - ALL

Key settings for hardening:

  • runAsNonRoot: true — prevents running as root (UID 0)
  • allowPrivilegeEscalation: false — prevents sudo or SUID binaries
  • readOnlyRootFilesystem: true — forces write operations to explicit volumes
  • capabilities: drop: ALL — removes all Linux capabilities (add back only what you need)
  • seccompProfile: RuntimeDefault — restricts syscalls to a safe default profile

What interviewers test: whether you know Pod Security Admission (PSA) policies (Privileged, Baseline, Restricted) and that simply not running as root is not sufficient hardening.


18. What is a NetworkPolicy and how do you deny all traffic by default?

NetworkPolicies are firewall rules for pods. They require a CNI plugin that supports them (Calico, Cilium, Weave) — vanilla kubenet does not enforce them.

A default-deny policy:

yaml
# Deny all ingress and egress in the namespace
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default-deny-all
  namespace: production
spec:
  podSelector: {}
  policyTypes:
    - Ingress
    - Egress

Then explicitly allow what is needed:

yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-api-to-db
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: api
      ports:
        - protocol: TCP
          port: 5432

What interviewers test: understanding that NetworkPolicies are additive (empty policy = deny nothing; podSelector: {} + policyTypes: [Ingress] with no ingress rules = deny all ingress). And that without a supporting CNI, they are silently ignored.


Horizontal Pod Autoscaler

19. How does the HPA work? What metrics can it scale on?

The HPA controller queries the Metrics API every 15 seconds (default). Based on current versus target utilization, it calculates a new desired replica count:

desiredReplicas = ceil(currentReplicas × (currentMetric / desiredMetric))
yaml
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 20
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 60
    - type: Resource
      resource:
        name: memory
        target:
          type: AverageValue
          averageValue: 400Mi
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "100"

Metric sources (autoscaling/v2):

  • Resource: CPU and memory from metrics-server
  • Pods: custom metrics per pod (via custom metrics API adapter)
  • Object: metrics from a Kubernetes object (e.g., Ingress requests/second)
  • External: metrics from outside the cluster (e.g., SQS queue depth via KEDA)

What interviewers test: the prerequisite (metrics-server must be installed), scale-down cooldown (5 minutes by default to avoid flapping), and the difference between HPA (pod count) and VPA (pod resource size).


20. What is the difference between HPA and VPA? Can you use them together?

HPA (Horizontal Pod Autoscaler): scales by adding/removing pod replicas. Best for stateless, horizontally-scalable workloads.

VPA (Vertical Pod Autoscaler): adjusts resource requests/limits of existing pods. Requires evicting and restarting pods to apply new resource values. Best for workloads that do not scale horizontally (single-instance databases, batch jobs).

Can you use them together? Partially. Never run HPA on CPU/memory and VPA simultaneously — they fight each other. You can run HPA on a custom metric (like requests/second) with VPA handling CPU/memory sizing.

bash
# Check HPA status
kubectl get hpa -n production
kubectl describe hpa my-app-hpa -n production

# Common issue: HPA shows <unknown>/60% for CPU
# Root cause: missing metrics-server OR missing resource requests on pods

PersistentVolumes

21. Explain the PV/PVC lifecycle. What is a StorageClass?

Three objects:

  • PersistentVolume (PV): cluster-level resource representing actual storage (an NFS share, an EBS volume, a Ceph RBD). Created statically by admins or dynamically by a provisioner.
  • PersistentVolumeClaim (PVC): namespace-level request for storage. Specifies size and access mode. Binds to a matching PV.
  • StorageClass: defines a provisioner and parameters. Enables dynamic provisioning — when a PVC is created, the StorageClass provisions a PV automatically.
yaml
# StorageClass (admin creates once)
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: fast-ssd
provisioner: ebs.csi.aws.com
parameters:
  type: gp3
  iops: "3000"
reclaimPolicy: Delete
volumeBindingMode: WaitForFirstConsumer
---
# PVC (developer creates)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: app-data
spec:
  storageClassName: fast-ssd
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi
---
# Pod using the PVC
volumes:
  - name: data
    persistentVolumeClaim:
      claimName: app-data

Access modes:

  • ReadWriteOnce (RWO): one node at a time (most block storage)
  • ReadOnlyMany (ROX): many nodes, read-only
  • ReadWriteMany (RWX): many nodes, read-write (NFS, EFS, CephFS)

Reclaim policies:

  • Delete: PV and underlying storage are deleted when PVC is deleted (default for dynamic provisioning)
  • Retain: PV is kept after PVC deletion; admin must manually clean up
  • Recycle: deprecated

What interviewers test: that you understand WaitForFirstConsumer binding mode — it delays PV provisioning until a pod is scheduled, ensuring the volume is created in the same AZ as the pod.


Helm

22. What is Helm and what problem does it solve?

Helm is a package manager for Kubernetes. It bundles related Kubernetes manifests into a chart — a versioned, parameterizable unit. It solves:

  • Templating: avoid duplicating YAML across environments with {{ .Values.replicaCount }}
  • Versioning: charts have versions; releases can be rolled back
  • Lifecycle management: helm install, helm upgrade, helm rollback, helm uninstall
bash
# Add a repo and install
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install my-postgres bitnami/postgresql \
  --namespace db \
  --set auth.postgresPassword=secret \
  --set primary.persistence.size=50Gi

# Override with a values file (preferred over --set for production)
helm install my-postgres bitnami/postgresql \
  --namespace db \
  -f values-production.yaml

# Check deployed releases
helm list -A

# Upgrade
helm upgrade my-postgres bitnami/postgresql -f values-production.yaml

# Rollback to revision 1
helm rollback my-postgres 1

What interviewers test: awareness of Helm's templating gotchas (whitespace handling, toYaml with indent), and the existence of helm template for rendering manifests locally to debug them.


23. What is the structure of a Helm chart?

my-chart/
├── Chart.yaml          # Chart metadata (name, version, appVersion)
├── values.yaml         # Default values (overridden by -f or --set)
├── templates/
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── ingress.yaml
│   ├── _helpers.tpl    # Named templates (partials)
│   └── NOTES.txt       # Post-install instructions
├── charts/             # Subcharts (dependencies)
└── .helmignore

Key template functions:

yaml
# _helpers.tpl
{{- define "my-chart.fullname" -}}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}

# deployment.yaml
metadata:
  name: {{ include "my-chart.fullname" . }}
  labels:
    app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
    app.kubernetes.io/managed-by: {{ .Release.Service }}

What interviewers test: whether you can debug a helm template output versus what is actually deployed (helm get manifest ), and how to use helm lint.


Troubleshooting

24. A pod is stuck in Pending. How do you diagnose it?

bash
kubectl describe pod <pod-name> -n <namespace>

Look at the Events section at the bottom. Common causes and their event messages:

| Event message | Root cause |

|---|---|

| 0/3 nodes are available: 3 Insufficient cpu | No node has enough CPU to satisfy the pod's request |

| 0/3 nodes are available: 3 node(s) had untolerated taint | Pod has no toleration for node taints |

| 0/3 nodes are available: 3 didn't match Pod's node affinity | nodeAffinity/nodeSelector rules exclude all nodes |

| persistentvolumeclaim "..." not found | PVC doesn't exist or is in wrong namespace |

| no persistent volumes available for this claim | No PV matches the PVC's storage class/access mode/size |

bash
# Check node capacity
kubectl describe nodes | grep -A5 "Allocated resources"

# Check if PVC is bound
kubectl get pvc -n <namespace>

# Check available PVs
kubectl get pv

What interviewers test: systematic diagnosis from events, not guessing. The answer to "it's pending" is always kubectl describe.


25. A pod is in CrashLoopBackOff. What is your diagnostic process?

CrashLoopBackOff means the container started, crashed, Kubernetes restarted it, it crashed again — and now Kubernetes is applying exponential backoff before retrying.

bash
# Check current logs
kubectl logs <pod> -n <namespace>

# Check logs from the PREVIOUS (crashed) container instance — critical
kubectl logs <pod> -n <namespace> --previous

# Describe to see exit codes and restart count
kubectl describe pod <pod> -n <namespace>

Exit codes that tell a story:

  • Exit Code 1: application error (check logs)
  • Exit Code 137: OOM kill (SIGKILL) — check memory limits and usage
  • Exit Code 139: segfault (SIGSEGV)
  • Exit Code 143: graceful shutdown (SIGTERM) — might be a liveness probe killing it
bash
# If the container crashes immediately and you can't get logs:
# Override the entrypoint to keep it alive for inspection
kubectl debug -it <pod> --image=busybox --target=<container>

# Or patch the deployment to override command
kubectl set image deployment/my-app my-app=busybox
kubectl set env deployment/my-app -- sleep infinity

What interviewers test: using --previous for logs (most people miss this), and systematic triage by exit code.


26. How do you exec into a running container? How do you copy files to/from it?

bash
# Exec into a container
kubectl exec -it <pod> -n <namespace> -- /bin/bash

# If the pod has multiple containers, specify which one
kubectl exec -it <pod> -n <namespace> -c <container-name> -- /bin/sh

# Copy a file from a container to local machine
kubectl cp <namespace>/<pod>:/path/to/file ./local-file

# Copy from local to container
kubectl cp ./local-file <namespace>/<pod>:/path/to/file

# Run a one-off debugging pod with network tools
kubectl run debug-pod --rm -it \
  --image=nicolaka/netshoot \
  --restart=Never \
  -- /bin/bash

What interviewers test: knowing nicolaka/netshoot or similar Swiss Army knife images for network debugging (curl, dig, tcpdump, netstat, nmap all in one image).


27. How do you check why a node is NotReady?

bash
# List nodes and their status
kubectl get nodes

# Describe the not-ready node
kubectl describe node <node-name>

# Look for conditions
kubectl get node <node-name> -o jsonpath='{.status.conditions[*].message}'

# Check kubelet logs on the node (requires SSH or node-level access)
journalctl -u kubelet -n 100 --no-pager

# Common causes:
# - kubelet crashed or stopped
# - Node is under memory/disk pressure (check conditions: MemoryPressure, DiskPressure)
# - Network issue: node can't reach the API server
# - containerd/docker daemon crashed

# Check node conditions programmatically
kubectl get nodes -o json | jq '.items[].status.conditions[] | select(.status=="True")'

What interviewers test: whether you know the difference between a node being unreachable versus a node being evicted due to resource pressure, and the relevant node conditions to inspect.


28. How do you debug a Service that is not routing traffic to pods?

Methodical approach:

bash
# Step 1: verify the service exists and has the right selector
kubectl describe service <service-name> -n <namespace>
# Look for: Selector, Endpoints

# Step 2: check if endpoints are populated
kubectl get endpoints <service-name> -n <namespace>
# If "Endpoints: <none>" — the selector does not match any running pods

# Step 3: verify pod labels match the service selector
kubectl get pods -n <namespace> --show-labels
# Compare pod labels with service's selector

# Step 4: check if pods pass readiness probes
kubectl get pods -n <namespace>
# Pods must be Running AND Ready (1/1, not 0/1)

# Step 5: test connectivity from inside the cluster
kubectl run test-pod --rm -it --image=curlimages/curl --restart=Never \
  -- curl http://<service-name>.<namespace>.svc.cluster.local:<port>

# Step 6: check DNS resolution
kubectl run test-dns --rm -it --image=busybox --restart=Never \
  -- nslookup <service-name>.<namespace>.svc.cluster.local

Common root cause: pod labels have a typo, or the pods exist but are not Ready because readiness probes fail — which means they are excluded from Endpoints.


Multi-Container Patterns

29. Explain the sidecar, ambassador, and adapter patterns with concrete examples.

Sidecar augments the main container without changing it:

  • Envoy/Istio proxy intercepting all traffic for mTLS and observability
  • Fluent Bit collecting and forwarding container logs to a centralized system
  • A secret rotation sidecar writing new credentials to a shared volume

Ambassador proxies outbound connections from the main container:

  • A sidecar container that accepts localhost connections and proxies them to the correct environment-specific endpoint (dev, staging, production) — the main app always connects to localhost:5432
  • A connection pooling proxy (PgBouncer) running as a sidecar so the main app doesn't manage connection pools

Adapter transforms output from the main container into a standard format:

  • A sidecar that reads app-specific metrics in a custom format and exposes them as standard Prometheus metrics on :9090/metrics
  • A log transformer that converts structured JSON logs into the format expected by a legacy log aggregator
yaml
containers:
  - name: app
    image: legacy-app:1.0
    # writes logs in custom format to /var/log/app.log
  - name: log-adapter
    image: log-transformer:1.0
    # reads /var/log/app.log, writes to stdout in JSON
    volumeMounts:
      - name: logs
        mountPath: /var/log
volumes:
  - name: logs
    emptyDir: {}

30. How do init containers differ from regular containers? What are they used for?

Init containers run sequentially before any regular container starts. They must complete successfully (exit 0) before the next init container — or the main containers — start. If an init container fails, the pod is restarted according to restartPolicy.

They share volumes with main containers but have separate images and resource quotas.

Use cases:

  • Database migration: run alembic upgrade head or rails db:migrate before the app starts
  • Dependency waiting: until curl -sf http://redis:6379; do sleep 1; done
  • Secret seeding: pull secrets from Vault into a shared volume before the app reads them
  • Permission setup: chmod 700 /data before a process that needs specific permissions starts
yaml
initContainers:
  - name: run-migrations
    image: myapp:1.0
    command: ["python", "manage.py", "migrate", "--noinput"]
    env:
      - name: DATABASE_URL
        valueFrom:
          secretKeyRef:
            name: db-secret
            key: url
  - name: wait-for-cache
    image: redis:7-alpine
    command: ['sh', '-c', 'until redis-cli -h redis ping; do sleep 2; done']

What interviewers test: init containers are sequential and blocking — they enforce ordering without pod interdependency. Main containers start in parallel once all init containers complete.


Advanced Topics

31. What is a taint and toleration? How do they work together?

Taints are applied to nodes to repel pods that do not explicitly tolerate them. Tolerations are applied to pods to allow them to be scheduled on tainted nodes.

bash
# Taint a node (no GPU workloads unless tolerated)
kubectl taint nodes node1 hardware=gpu:NoSchedule

# Remove the taint
kubectl taint nodes node1 hardware=gpu:NoSchedule-
yaml
# Pod that tolerates the GPU taint
tolerations:
  - key: "hardware"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

Taint effects:

  • NoSchedule: don't schedule new pods here (existing pods unaffected)
  • PreferNoSchedule: prefer not to schedule here (soft)
  • NoExecute: evict existing pods that don't tolerate this taint, don't schedule new ones

What interviewers test: the asymmetry — taints are on nodes, tolerations are on pods; tolerations allow scheduling on tainted nodes but do not force it (you still need nodeAffinity to force assignment to specific nodes).


32. What is the difference between nodeSelector, nodeAffinity, and podAffinity?

  • nodeSelector: simplest form — requires exact label match on node. No OR conditions.
  • nodeAffinity: more expressive. Supports In, NotIn, Exists, DoesNotExist, Gt, Lt operators. Has requiredDuringSchedulingIgnoredDuringExecution (hard) and preferredDuringSchedulingIgnoredDuringExecution (soft).
  • podAffinity/podAntiAffinity: schedule pods relative to other pods. podAntiAffinity spreads pods across nodes/AZs.
yaml
affinity:
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: topology.kubernetes.io/zone
              operator: In
              values:
                - us-east-1a
                - us-east-1b
  podAntiAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchLabels:
            app: my-app
        topologyKey: kubernetes.io/hostname

The podAntiAffinity with topologyKey: kubernetes.io/hostname ensures no two pods of the same app land on the same node — critical for HA deployments.


33. What is a PodDisruptionBudget (PDB) and why is it important?

A PDB limits the number of pods that can be voluntarily disrupted simultaneously — during node drains, cluster upgrades, or pod evictions by the autoscaler.

yaml
apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: my-app-pdb
spec:
  minAvailable: 2   # OR use maxUnavailable: 1
  selector:
    matchLabels:
      app: my-app

If you have 3 replicas and minAvailable: 2, Kubernetes will not allow a kubectl drain or Cluster Autoscaler scale-down to remove more than 1 pod at a time. The drain will block until a pod is rescheduled elsewhere.

Common mistake: forgetting PDBs on stateless services. Without them, cluster upgrades drain all pods simultaneously, causing outages.


34. How does the Cluster Autoscaler work?

The Cluster Autoscaler (CA) watches for pods that cannot be scheduled due to resource constraints and requests new nodes from the cloud provider's autoscaling group. It also removes underutilized nodes (default: less than 50% utilized for 10+ minutes).

Scale-up: a pod is Pending → CA simulates whether any node group addition would allow scheduling → if yes, adds a node → cloud provider provisions it (1-3 min typically).

Scale-down: CA checks each node; if all its pods could be rescheduled elsewhere and it's been underutilized → CA drains and removes it (respects PDBs).

Important interactions:

  • CA and HPA work together: HPA adds pods → CA adds nodes
  • CA respects PDBs during scale-down
  • Annotation cluster-autoscaler.kubernetes.io/safe-to-evict: "false" prevents CA from evicting a pod to shrink a node

35. What is etcd and why does it matter for cluster operations?

etcd is a distributed consensus key-value store (Raft protocol) that is the single source of truth for all cluster state: every API object, every secret, every lease. The API server is essentially a caching/validation layer over etcd.

For operations:

bash
# Backup etcd (critical — do this before upgrades)
ETCDCTL_API=3 etcdctl snapshot save snapshot.db \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt \
  --key=/etc/kubernetes/pki/etcd/healthcheck-client.key

# Verify snapshot
etcdctl snapshot status snapshot.db

# Restore (after a catastrophic failure)
etcdctl snapshot restore snapshot.db \
  --data-dir=/var/lib/etcd-restored

Performance considerations: etcd is sensitive to disk I/O latency. IOPS spikes from colocated workloads corrupt leader election. Always run etcd on dedicated SSDs. For production clusters with 3+ control plane nodes, run a 3 or 5-node etcd cluster for HA.


36. How do you upgrade a Kubernetes cluster?

The safe upgrade path (control plane first, then nodes, one minor version at a time — no skipping):

bash
# On control plane node
apt-get update && apt-get install -y kubeadm=1.28.0-00

# Check upgrade plan
kubeadm upgrade plan

# Apply upgrade
kubeadm upgrade apply v1.28.0

# Upgrade kubelet and kubectl on control plane
apt-get install -y kubelet=1.28.0-00 kubectl=1.28.0-00
systemctl daemon-reload && systemctl restart kubelet

# For each worker node:
kubectl drain <node-name> --ignore-daemonsets --delete-emptydir-data
# (on the worker node)
apt-get install -y kubeadm=1.28.0-00
kubeadm upgrade node
apt-get install -y kubelet=1.28.0-00
systemctl daemon-reload && systemctl restart kubelet
# (back on control plane)
kubectl uncordon <node-name>

What interviewers test: the drain-upgrade-uncordon pattern per node, the need to upgrade kubeadm before kubelet, and the one-minor-version-at-a-time constraint.


37. What is a CRD and what is an Operator?

A Custom Resource Definition (CRD) extends the Kubernetes API with new resource types. Once created, you can kubectl get, kubectl apply, and interact with custom resources the same way you interact with built-in ones.

An Operator is a controller that watches custom resources and reconciles state. It encodes operational knowledge: how to deploy, scale, backup, and recover a specific application.

Examples: the Prometheus Operator (creates Prometheus, ServiceMonitor, PrometheusRule CRDs), the PostgreSQL Operator (Zalando's postgresql CRD that manages HA Postgres clusters), cert-manager (Certificate, Issuer CRDs for automatic TLS management).

bash
# See all CRDs in the cluster
kubectl get crds

# Interact with a custom resource (cert-manager example)
kubectl get certificate -A
kubectl describe certificaterequest my-cert -n production

What interviewers test: that you understand Operators as an extension of the controller pattern — they are just controllers that happen to manage custom resources instead of built-in ones.


38. How do you implement zero-downtime deployments for a database-backed app?

Checklist for truly zero-downtime:

  1. 1Backward-compatible migrations: never drop a column in the same deploy as removing its usage. Use a two-phase process: deploy new code that works with both old and new schema → run migration → deploy cleanup.
  1. 2Readiness probes: ensure the pod is not added to Service Endpoints until it is truly ready (DB connections established, migrations checked, health endpoint returns 200).
  1. 3maxUnavailable: 0 in rolling update strategy.
  1. 4PodDisruptionBudget: minAvailable equal to the minimum capacity needed to handle traffic.
  1. 5Graceful shutdown: handle SIGTERM — stop accepting new requests, drain in-flight requests, close DB connections. Set terminationGracePeriodSeconds accordingly.
  1. 6preStop lifecycle hook (for apps that don't handle SIGTERM):
yaml
lifecycle:
  preStop:
    exec:
      command: ["/bin/sh", "-c", "sleep 5"]

This 5-second sleep gives kube-proxy/Ingress time to remove the pod from the load balancer before the container receives SIGTERM.


39. What is a ServiceAccount token and how does pod-to-API server communication work?

By default, every pod gets a ServiceAccount token mounted at /var/run/secrets/kubernetes.io/serviceaccount/token. This token is a JWT that the pod uses to authenticate to the Kubernetes API server.

In Kubernetes 1.21+, these are bound service account tokens — short-lived (1 hour by default), audience-bound, and automatically rotated by the kubelet.

If your application uses the Kubernetes API (monitoring agents, operators, CI runners), it should use a ServiceAccount with minimal RBAC permissions:

yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-operator
  namespace: operator-system
---
# Then bind it to the pod:
spec:
  serviceAccountName: my-operator
  automountServiceAccountToken: true  # default; set false if unused

For pods that don't need API access, set automountServiceAccountToken: false to avoid unnecessarily exposing credentials.


40. What are the key kubectl commands every engineer should know?

bash
# Context management
kubectl config get-contexts
kubectl config use-context <context-name>
kubectl config set-context --current --namespace=<namespace>

# Rapid inspection
kubectl get all -n <namespace>
kubectl get events -n <namespace> --sort-by=.lastTimestamp
kubectl top pods -n <namespace>
kubectl top nodes

# Editing live resources
kubectl edit deployment/<name>
kubectl patch deployment my-app -p '{"spec":{"replicas":5}}'

# Port-forwarding (without exposing via Service)
kubectl port-forward pod/<pod-name> 8080:8080
kubectl port-forward service/<service-name> 8080:80

# Debugging
kubectl debug node/<node-name> -it --image=ubuntu  # privileged node access
kubectl get pod <pod> -o yaml  # full spec including defaulted fields
kubectl explain deployment.spec.strategy  # inline API docs

# Force delete a stuck terminating pod (last resort — can cause data issues)
kubectl delete pod <pod> --grace-period=0 --force

# Apply with dry-run to preview changes
kubectl apply -f manifest.yaml --dry-run=server

# Diff against live cluster
kubectl diff -f manifest.yaml

Quick Reference: What Each Question Section Tests

| Topic | What interviewers really want to know |

|---|---|

| Architecture | Do you understand declarative reconciliation vs imperative commands? |

| Pods/Probes | Have you debugged crashed pods in production? |

| Deployments | Do you understand rollout mechanics, not just kubectl apply? |

| StatefulSets | Can you reason about pod identity and ordered operations? |

| Services/Ingress | Do you understand L4 vs L7, and the cost implications of LoadBalancer? |

| RBAC | Have you operated a multi-tenant cluster with real security requirements? |

| Secrets | Do you know the difference between encoding and encryption? |

| HPA/VPA | Can you design an autoscaling strategy for a real production workload? |

| PVs | Do you know access modes and what happens on node failure? |

| Helm | Have you managed releases across multiple environments? |

| Troubleshooting | Is your diagnostic process systematic or guess-based? |

| Advanced (taints, PDBs, etcd) | Are you ready for on-call on a production cluster? |


Final Preparation Advice

Set up a local cluster. Use kind (Kubernetes in Docker) or k3d for a full multi-node cluster on your laptop. Practice every command in this guide until it is muscle memory.

bash
# Create a 3-node kind cluster
kind create cluster --config - <<EOF
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
  - role: control-plane
  - role: worker
  - role: worker
EOF

Know your defaults. Interviewers ask about default values because defaults cause production incidents: default terminationGracePeriodSeconds (30s), default HPA cooldown (5 min scale-down), default ServiceAccount token automounting, default NetworkPolicy behavior (allow all).

Prepare a real incident story. Every interviewer will ask "tell me about a Kubernetes problem you debugged in production." Have a story ready with: symptoms, investigation steps (exactly which commands), root cause, and what you changed to prevent recurrence.

Practice kubectl without autocomplete. Interviewers watch whether you reach for docs or type confidently. Know the resource short names: po (pods), deploy (deployments), svc (services), cm (configmaps), pvc (persistentvolumeclaims), hpa (horizontalpodautoscalers), ns (namespaces).

FAQ

What Kubernetes topics come up most in DevOps interviews?+

The most common topics are: pod lifecycle (probes, resource limits, CrashLoopBackOff debugging), Deployment rollout strategies (RollingUpdate with maxSurge/maxUnavailable), Service types and Ingress, RBAC (Role vs ClusterRole, kubectl auth can-i), HPA with metrics-server, and PersistentVolumes with StorageClasses. Expect at least one live troubleshooting question where you walk through diagnosing a Pending or CrashLoopBackOff pod.

How do I answer Kubernetes questions if I only have theoretical knowledge?+

Set up a local cluster with kind or k3d — it runs Kubernetes entirely inside Docker and takes under 5 minutes to start. Practice every kubectl command until it is muscle memory. Interviewers can immediately tell if you have operated a real cluster versus read documentation. Focus on troubleshooting scenarios: break things deliberately (set wrong resource limits, create Services with mismatched selectors, crash pods with bad liveness probes) and practice diagnosing them.

What is the difference between a Deployment and a StatefulSet in Kubernetes?+

A Deployment is for stateless workloads: pods are interchangeable, get random names, share a single PVC (if any), and can be replaced or rescheduled without coordination. A StatefulSet is for stateful workloads: each pod gets a stable ordinal identity (app-0, app-1), a dedicated PVC that follows the pod across rescheduling, a stable DNS entry via a headless service, and ordered startup and shutdown. Use StatefulSets for databases, message brokers, and any workload where pods must know and contact each other by stable hostname.

Are Kubernetes Secrets actually encrypted?+

No — not by default. Secrets are stored in etcd as base64-encoded values, which is encoding, not encryption. Anyone with kubectl get secret access can decode them trivially. To actually encrypt secrets at rest, you must configure EncryptionConfiguration on the API server with an AES-GCM or KMS provider. For production, the recommended approach is to use an external secret manager (AWS Secrets Manager, HashiCorp Vault, GCP Secret Manager) combined with an operator like External Secrets Operator or Vault Agent Injector, so plaintext credentials never touch etcd.

What is the difference between kubectl apply and kubectl create?+

kubectl create is imperative — it creates a resource and fails if it already exists. kubectl apply is declarative — it creates the resource if it does not exist, patches it if it does, and stores the applied configuration as an annotation for future three-way merges. In production, always use kubectl apply (or a GitOps tool like Argo CD or Flux). Use kubectl create only for one-off imperative operations like creating secrets from literals, or with --dry-run=client -o yaml to generate YAML scaffolding quickly.

How do I prepare for a Kubernetes live coding or whiteboard interview?+

Practice writing YAML from memory for the six most common resource types: Pod, Deployment, Service, Ingress, ConfigMap/Secret injection, and HPA. Know the required fields for each without looking them up. For troubleshooting questions, develop a consistent three-step process: kubectl describe (read the Events section), kubectl logs --previous (for crashed containers), kubectl get endpoints (for Service routing issues). Interviewers are not testing whether you memorize every field — they are testing whether your diagnostic process is systematic and whether you understand why each field exists.

Artículos relacionados

DevOps Engineer Interview Questions and How to Answer Them (45+ Questions)

Complete technical guide covering 50 DevOps interview questions with detailed answers, real code snippets across CI/CD, Kubernetes, Terraform, monitoring, Linux, AWS, and incident management.

Docker and Kubernetes Interview Questions (40+ Questions)

Complete Docker and Kubernetes interview guide with 45 questions, detailed answers, and real code examples

AWS Interview Questions and How to Answer Them (45+ Questions)

A comprehensive, expert-level guide covering 48 AWS interview questions with detailed answers and real code examples. Covers IAM and security, EC2/Lambda/ECS compute, S3/EBS/EFS storage, VPC/Route 53/CloudFront networking, RDS/DynamoDB/ElastiCache databases, and architecture best practices. Targeted at software and DevOps engineers preparing for AWS interviews at tech companies.

Preparate para tu entrevista real

Pegá el link de tu vacante: investigamos quién te entrevista y te ensayamos en vivo.

Empezar gratis →

¿Tenés entrevista próxima? Instalá el copiloto en vivo →

InterviewHack.ai

Preparate para la entrevista exacta: quién te entrevista, tu CV a medida y coach real.

Producto

VacantesRevisar CV (ATS) gratis¿Cómo suena tu inglés?¿Te pagan bien?Reporte de sueldos LATAMCursos gratisBlogCV a medidaPráctica habladaEs gratis

Empleos remotos

ReactPythonFull-StackLATAMArgentinaMéxicoVer todas →

Preparate

Práctica habladaFrontendBackendAI EngineerPor empresaVendete con tu CV

Empresa

Buscás talentoAcerca deContactoPrivacidadTérminos

© 2026 InterviewHack.ai · Tu CV es tuyo. Nunca se usa para entrenar nada. · Un producto de IA-PTY