Docker & Kubernetes Preguntas de entrevista
Las entrevistas de Docker y Kubernetes evalúan tu capacidad para contenerizar aplicaciones y orquestarlas a escala. Estas preguntas se hacen comúnmente para roles de DevOps, SRE e ingeniería de plataforma. Cubren tanto conceptos fundamentales como imágenes y contenedores, como habilidades prácticas como escribir manifiestos YAML y depurar clústeres. Espera una mezcla de explicaciones conceptuales, tareas prácticas y escenarios de resolución de problemas.
Lo que cubren las entrevistas de Docker & Kubernetes
Conceptos Básicos de Contenedores
Las preguntas cubren la arquitectura de Docker, imágenes, contenedores, volúmenes y redes. Pueden pedirte que escribas Dockerfiles y comprendas las compilaciones multi-etapa.
Arquitectura de Kubernetes
Enfoque en componentes del plano de control, nodos, pods, deployments, services e ingress. Espera preguntas sobre el scheduler, kubelet y API server.
Redes y Almacenamiento
Los temas incluyen redes de Pod, tipos de service, políticas de red, volúmenes persistentes y clases de almacenamiento. Debes entender cómo se comunican los contenedores dentro y a través de clústeres.
CI/CD y Monitoreo
Preguntas sobre la integración de Docker y Kubernetes con pipelines de CI/CD, uso de Helm, monitoreo con Prometheus y registro con Fluentd o herramientas similares.
Ejemplos de preguntas de entrevista sobre Docker & Kubernetes
- ¿Cuál es la diferencia entre una imagen Docker y un contenedor?Lo que cubre una buena respuesta
- Imagen: plantilla inmutable y estática con sistema de archivos, metadatos y configuración.
- Contenedor: instancia ejecutable de una imagen con su propio espacio de procesos y red.
- Imagen guardada en registro (Docker Hub); contenedor se ejecuta en host.
- Múltiples contenedores pueden basarse en misma imagen; cada uno aislado.
Ver respuesta de ejemplo
Una imagen Docker es un artefacto inmutable, de solo lectura, que contiene el sistema de archivos, binarios, bibliotecas y configuraciones necesarias para una aplicación. Un contenedor es una instancia ejecutable de esa imagen: se crea al ejecutar 'docker run', añadiendo una capa de escritura temporal y asignando recursos como CPU, memoria y red. La imagen puede existir en un registro sin estar activa; el contenedor es el proceso en marcha. Diferencias clave: imagen es estática (no cambia), contenedor es dinámico (se modifica con datos). Puedes tener decenas de contenedores de la misma imagen, cada uno aislado. La imagen se descarga una vez; los contenedores se crean y destruyen. La confusión común es tratar al contenedor como si fuera la imagen; la imagen es el plano, el contenedor es la casa construida.
- ¿Cómo depurarías un Pod que está atascado en CrashLoopBackOff?Lo que cubre una buena respuesta
- Revisar logs del pod con 'kubectl logs <pod>' y '--previous' si reinició.
- Describir el pod con 'kubectl describe pod <pod>' para ver eventos y razones de fallo.
- Comprobar la imagen, comandos y argumentos en la especificación del pod.
- Verificar que todos los configmaps, secrets y volúmenes necesarios existan y sean accesibles.
- Si es por recurso, aumentar límites de CPU/memoria en el pod.
Ver respuesta de ejemplo
El estado CrashLoopBackOff indica que el contenedor se inicia, falla y Kubernetes reinicia continuamente. Primero, ejecuto 'kubectl logs <pod> --previous' para ver logs del último intento fallido. Luego, 'kubectl describe pod' muestra eventos como ImagePullBackOff, CrashLoopBackOff o errores de montaje. Analizo el código de salida (exit code) y busco en los logs errores de aplicación, como excepciones no capturadas o fallos de conexión a base de datos. Verifico que los recursos (ConfigMaps, Secrets) estén creados y referenciados correctamente. Si el contenedor muere por falta de recursos, ajusto resource requests/limits. Otra posibilidad: el comando de inicio o el health check (livenessProbe) está mal configurado. Si todo falla, ejecuto un contenedor interactivo con la misma imagen para depurar en vivo. La clave es iterar: logs, describir, revisar especificación y probar localmente.
- Escribe un Dockerfile para una aplicación Node.js que se ejecute en el puerto 3000.Lo que cubre una buena respuesta
- Usar imagen base oficial de Node.js (node:18-alpine para tamaño pequeño).
- Establecer el directorio de trabajo dentro del contenedor.
- Copiar package.json y ejecutar npm install antes de copiar el resto del código para caché.
- Exponer el puerto 3000 con la instrucción EXPOSE (documentativo).
- Definir el comando de inicio CMD ["node", "app.js"] (o similar).
Ver respuesta de ejemplo
El Dockerfile debe ser eficiente: se usa una imagen base pequeña y moderna, se aprovecha la caché de capas copiando primero los archivos de dependencias. Se recomienda usar la variante 'slim' o 'alpine'. A continuación se muestra un ejemplo completo y comentado.
Solución de referenciadockerfile # Usar imagen oficial de Node.js versión 18 con Alpine (ligera) FROM node:18-alpine # Establecer directorio de trabajo dentro del contenedor WORKDIR /usr/src/app # Copiar package.json y package-lock.json (si existe) primero para aprovechar caché COPY package*.json ./ # Instalar dependencias de producción (sin dev para imagen más pequeña) RUN npm ci --only=production # Copiar el resto del código de la aplicación COPY . . # Exponer el puerto en el que la app escucha (documentación, no publica por sí solo) EXPOSE 3000 # Comando para iniciar la aplicación CMD [ "node", "app.js" ] - Explica cómo funcionan los Services de Kubernetes y cómo habilitan el balanceo de carga.Lo que cubre una buena respuesta
- Service expone un conjunto de Pods mediante un selector de etiquetas.
- Asigna una IP virtual (ClusterIP) y un nombre DNS estable dentro del clúster.
- El balanceo de carga se realiza por defecto con round-robin a través de los endpoints.
- Tipos: ClusterIP (solo interno), NodePort (puerto en cada nodo), LoadBalancer (balanceador externo).
- El Service monitorea los Pods vía el controlador de Endpoints, actualizando dinámicamente.
Ver respuesta de ejemplo
Un Service en Kubernetes abstrae un conjunto lógico de Pods que realizan la misma función. Se define con un selector de etiquetas que coincide con las etiquetas de los Pods. Cuando se crea, el plano de control asigna una IP virtual (ClusterIP) y un nombre DNS (por ejemplo, 'mi-servicio.default.svc.cluster.local'). Cualquier tráfico enviado a esa IP o nombre se redirige automáticamente a uno de los Pods seleccionados usando un algoritmo de balanceo de carga round-robin. El Service monitorea constantemente el estado de los Pods: si un Pod falla o se escala, el controlador de Endpoints actualiza la lista de direcciones IP de destino. Los tipos de Service determinan la exposición: ClusterIP solo dentro del clúster, NodePort abre un puerto en cada nodo (para acceso externo directo), LoadBalancer integra con un balanceador de carga cloud, y ExternalName mapea a un nombre DNS externo. El balanceo es transparente para el cliente, que solo ve la IP del Service. Es importante entender que el Service no es un proxy inverso tradicional; es una regla iptables/ipvs que distribuye paquetes a nivel de transporte (L4). Para balanceo a nivel de aplicación (L7) se recomienda un Ingress.
- Crea un Deployment que implemente una actualización con cero tiempo de inactividad.Lo que cubre una buena respuesta
- Estrategia RollingUpdate: actualiza Pods gradualmente reemplazando viejos por nuevos.
- Configurar 'maxSurge' y 'maxUnavailable' para controlar la velocidad de actualización.
- Uso de liveness/readiness probes para asegurar que el nuevo Pod sirva tráfico antes de eliminar el viejo.
- Estrategia Recreate causa tiempo de inactividad; RollingUpdate es la predeterminada para Deployment.
- Verificar con 'kubectl rollout status' y 'kubectl rollout undo' si hay fallos.
Ver respuesta de ejemplo
Para conseguir cero tiempo de inactividad, se usa un Deployment con la estrategia RollingUpdate. Esta estrategia reemplaza Pods antiguos por nuevos de forma gradual, manteniendo siempre un número mínimo de Pods disponibles. Los campos clave son 'maxSurge' (número de Pods extra que se pueden crear durante la actualización, p. ej. 25%) y 'maxUnavailable' (número de Pods que pueden estar no disponibles, p. ej. 25%). Es fundamental definir readiness probes para que el nuevo Pod solo reciba tráfico cuando esté listo. El siguiente manifiesto es un ejemplo que configura una actualización con cero inactividad.
Solución de referenciayaml apiVersion: apps/v1 kind: Deployment metadata: name: mi-app spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 # máximo de Pods extra (1 sobre el deseado) maxUnavailable: 0 # cero Pods no disponibles durante la actualización selector: matchLabels: app: mi-app template: metadata: labels: app: mi-app spec: containers: - name: app image: mi-app:v2 ports: - containerPort: 80 readinessProbe: httpGet: path: /health port: 80 livenessProbe: httpGet: path: /health port: 80 # Nota: con maxUnavailable=0, se asegura que siempre haya 3 Pods sirviendo (los viejos hasta que los nuevos estén listos) - ¿Cómo gestionas los secretos en Kubernetes?Lo que cubre una buena respuesta
- Usar recursos nativos de Kubernetes: Secret y ConfigMap (para datos no sensibles).
- Los Secret se codifican en base64 pero no cifran por defecto; habilitar encriptación en etcd.
- Inyectar secretos como variables de entorno o montarlos como volúmenes (archivos).
- Herramientas externas: Sealed Secrets, Vault (HashiCorp), External Secrets Operator.
- Principio de mínimo privilegio: RBAC para controlar acceso a secretos.
Ver respuesta de ejemplo
Kubernetes ofrece el recurso Secret para almacenar datos sensibles (contraseñas, tokens, claves). Los valores se almacenan en base64 (no es cifrado real), por lo que es obligatorio habilitar el cifrado en reposo de etcd (encryption at rest) y usar RBAC estricto. Para inyectar secretos en un Pod, se definen como variables de entorno: envFrom[].secretRef o env[].valueFrom.secretKeyRef; o se montan como volúmenes: volumes[].secret y volumeMounts. El montaje como archivo es más seguro porque no queda en el historial de procesos. Para entornos más seguros, se usan soluciones externas como Sealed Secrets (cifra el secreto en Git), HashiCorp Vault (con sidecar que inyecta dinámicamente) o External Secrets Operator que sincroniza secretos de AWS Secrets Manager, GCP Secret Manager, etc. La gestión incluye limitar el acceso con ServiceAccounts y Roles específicos. Una mala práctica común es hardcodear secretos en imágenes o configmaps; siempre usar el recurso Secret y rotarlos periódicamente.
- Describe el ciclo de vida de un Pod desde la creación hasta la eliminación.Lo que cubre una buena respuesta
- Fase Pending: el Pod se acepta pero aún no se asigna a un nodo (puede esperar recursos).
- Fase Running: al menos un contenedor está en ejecución (y todos están en Running o terminaron).
- Fase Succeeded: todos los contenedores terminaron con código 0 (tarea completada).
- Fase Failed: al menos un contenedor terminó con código distinto de 0. Unknown: estado no reportado.
- Eventos: creación por API server, scheduling en nodo, descarga de imágenes, inicio de contenedores, probes.
Ver respuesta de ejemplo
El ciclo de vida de un Pod comienza cuando se envía el objeto Pod al API server (por kubectl, YAML, etc.). El sistema valida la especificación y lo persiste en etcd. Luego el scheduler lo asigna a un nodo (fase Pending). Si hay recursos disponibles, el kubelet en el nodo comienza a crear los contenedores: descarga imágenes, crea volúmenes, y ejecuta init containers si existen. Una vez que todos los contenedores inician correctamente (y pasan readiness probes), el Pod pasa a Running. Durante la ejecución, Kubernetes monitorea la salud con liveness y readiness probes. Si falla un contenedor, el restartPolicy determina si se reinicia (Always/OnFailure). El Pod puede ser terminado por eliminación manual (grace period), por fallo crítico (fase Failed) o por completar su tarea exitosamente (fase Succeeded). Al eliminarse, se ejecuta preStop hook, se envía SIGTERM, y finalmente se limpian los recursos. Todo esto se refleja en los eventos (kubectl describe pod) y en el campo 'status.phase'. Es clave entender que un Pod no se repara por sí mismo (solo el contenedor se reinicia); para alta disponibilidad se usan ReplicaSets/Deployments.
- ¿Cómo escalarías un deployment basado en el uso de CPU usando HorizontalPodAutoscaler?Lo que cubre una buena respuesta
- HPA escala automáticamente el número de réplicas basado en métricas de CPU (u otras).
- Define un objetivo de utilización de CPU (targetAverageUtilization) y un mínimo/máximo de réplicas.
- El controlador HPA calcula la métrica promedio de todos los Pods y ajusta el deployment.
- Requiere que el clúster tenga Metrics Server instalado (para recopilar métricas).
- Se puede combinar con métricas personalizadas y multi-métrica.
Ver respuesta de ejemplo
El HorizontalPodAutoscaler (HPA) permite escalar un Deployment, ReplicaSet o StatefulSet en función de métricas como CPU, memoria o métricas personalizadas. Para escalar por CPU, se instala primero Metrics Server en el clúster (recopila métricas de uso de CPU/memoria de nodos y pods). Luego, se crea un objeto HPA que especifica: scaleTargetRef (el deployment a escalar), minReplicas, maxReplicas, y métricas. Por ejemplo, targetAverageUtilization de CPU al 50%: si el uso promedio supera el 50%, el controlador HPA calcula el número de réplicas deseado con la fórmula: desiredReplicas = ceil(currentReplicas * (currentMetricValue / desiredMetricValue)). Escala hacia arriba rápidamente, pero hacia abajo con un período de enfriamiento (cooldown) para evitar thrashing. Es importante definir resource requests en los contenedores para que el HPA pueda calcular la utilización. Un manifiesto de ejemplo se muestra a continuación.
Solución de referenciayaml apiVersion: autoscaling/v2 kind: HorizontalPodAutoscaler metadata: name: mi-app-hpa spec: scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: mi-app minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu target: type: Utilization averageUtilization: 50 behavior: scaleDown: stabilizationWindowSeconds: 300 # evitar cambios bruscos al bajar
Cómo prepararse
- Practica escribir Dockerfiles y manifiestos YAML de Kubernetes a mano sin depender de herramientas.
- Configura un clúster local usando Minikube o kind para experimentar con deployments y services reales.
- Comprende a fondo la línea de comandos de kubectl, incluyendo comandos de resolución de problemas como kubectl describe, kubectl logs y kubectl exec.
- Aprende los conceptos fundamentales de redes de contenedores y cómo Kubernetes implementa redes con plugins CNI.
- Estudia escenarios comunes de entrevistas como actualizaciones continuas, despliegues canary y límites de recursos de pods.
Preguntas frecuentes
¿Necesito conocer tanto Docker como Kubernetes para las entrevistas?
Sí, la mayoría de las entrevistas cubren ambos. Docker es a menudo un requisito previo, y las preguntas de Kubernetes asumen familiaridad con los conceptos básicos de contenedores.
¿Cuál es la mejor manera de prepararse para preguntas prácticas?
Configura un clúster local (Minikube/kind) y practica desplegando aplicaciones, escribiendo YAML desde cero y depurando problemas.
¿Qué tan importantes son las habilidades para escribir manifiestos YAML?
Muy importantes. Muchas entrevistas incluyen escribir o depurar archivos YAML para deployments, services y configmaps.
¿Debería enfocarme más en Docker o Kubernetes?
Kubernetes suele tener más peso, pero los fundamentos de Docker (imágenes, Dockerfile, compose) también se evalúan.
¿Hay alguna herramienta específica que deba conocer?
Conoce kubectl, Helm y la depuración básica con docker logs y exec. La familiaridad con Prometheus y Grafana es un plus.
Practica preguntas sobre Docker & Kubernetes con retroalimentación instantánea de IA
Sube tu currículum, obtén una entrevista simulada personalizada y ve exactamente qué mejorar — gratis para empezar.