LIVE: New phishing campaigns targeting mobile users —View latest threats →

Back to Tutorials
Avanzado 17 min de lectura

Seguridad en Docker y Kubernetes: cómo reforzar tus contenedores

Los contenedores cambiaron la forma en que desplegamos software, pero muchos equipos los publican con acceso root, imágenes obsoletas y secretos expuestos. Aquí tienes la guía completa de refuerzo.

25 de febrero de 2026

El error conceptual sobre la seguridad de los contenedores

Un error conceptual común es creer que los contenedores proporcionan un aislamiento fuerte, análogo al de las máquinas virtuales. No es así. Los contenedores comparten el kernel del host: una vulnerabilidad de escape de contenedor que logre ejecutar código en el kernel del host concede acceso a todos los contenedores de ese host, además del propio host. La seguridad de los contenedores consiste en reducir el radio de impacto de un contenedor comprometido, no en asumir que la frontera es impenetrable.

La superficie de ataque abarca la imagen del contenedor, la configuración del entorno de ejecución, la plataforma de orquestación, la red y la capa de gestión de secretos. El refuerzo debe abordarlas todas.

Refuerzo de las imágenes de Docker

Usa imágenes base mínimas

Cada paquete de una imagen base es una vulnerabilidad potencial. Prefiere las imágenes distroless (imágenes de Google sin shell, gestor de paquetes ni herramientas del sistema operativo) o Alpine Linux (musl libc, apk, ~5 MB):

# Instead of ubuntu:22.04
FROM gcr.io/distroless/java21-debian12

A las imágenes distroless no se puede acceder de forma interactiva mediante un shell, lo que limita significativamente las opciones del atacante si el contenedor se ve comprometido.

Compilaciones multietapa

Las dependencias de compilación (compiladores, herramientas de compilación, frameworks de pruebas) nunca deberían estar en la imagen de producción:

FROM golang:1.22 AS builder
WORKDIR /app
COPY . .
RUN go build -o server .

FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
ENTRYPOINT ["/server"]

La imagen final contiene únicamente el binario compilado y sus dependencias de ejecución.

Nunca ejecutes como root

De forma predeterminada, los procesos de los contenedores se ejecutan como root (UID 0). Si se produce un escape de contenedor, el atacante tiene root en el host. Crea siempre un usuario sin privilegios de root:

RUN useradd -u 1001 -r appuser
USER appuser

Combínalo con un sistema de archivos --read-only y --tmpfs /tmp para las ubicaciones que necesiten escritura.

Analiza las imágenes en busca de vulnerabilidades

Integra el análisis de imágenes en tu pipeline de CI/CD:

# Trivy — fast, comprehensive vulnerability scanner
trivy image myapp:latest

# Grype — alternative with SBOM support
grype myapp:latest

Haz que la compilación falle si se encuentran CVE altos o críticos. Recompila y actualiza las imágenes base de forma periódica, no solo cuando cambies el código de la aplicación.

Seguridad del entorno de ejecución de Docker

Descarta capacidades

Las capacidades de Linux dividen el modelo de privilegios de todo o nada de root en unidades discretas. Descarta todas las capacidades y vuelve a añadir solo las que la aplicación necesite:

docker run --cap-drop ALL --cap-add NET_BIND_SERVICE myapp

Seccomp y AppArmor

El perfil de seccomp predeterminado de Docker bloquea unas 44 llamadas al sistema peligrosas. Úsalo de forma explícita y considera un perfil personalizado para cargas de trabajo sensibles. Los perfiles de AppArmor o SELinux añaden control de acceso obligatorio sobre el kernel:

docker run --security-opt seccomp=profile.json myapp
docker run --security-opt apparmor=docker-default myapp

Nunca uses --privileged

El indicador --privileged otorga al contenedor un acceso casi completo al host, desactivando todo el aislamiento de seguridad. En ocasiones es necesario para casos de uso concretos (como ejecutar Docker dentro de Docker), pero debe evitarse por completo en producción y tratarse como una señal de alarma inmediata durante las revisiones de seguridad.

Refuerzo de la seguridad de Kubernetes

Estándares de seguridad de pods

Kubernetes aplica políticas de seguridad mediante los Pod Security Standards (que sustituyen a la obsoleta PodSecurityPolicy):

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest

El perfil restricted impone: sin contenedores privilegiados, sin usuario root, sin escalada de privilegios, perfil de seccomp obligatorio y todas las capacidades descartadas.

RBAC: mínimo privilegio para las cuentas de servicio

Cada pod se ejecuta con una cuenta de servicio. De forma predeterminada, esa cuenta de servicio puede acceder a la API de Kubernetes. Aplica el mínimo privilegio:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-role
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get"]

Audita con kubectl auth can-i --list --as=system:serviceaccount:default:myapp. Desactiva el montaje automático de los tokens de cuenta de servicio cuando no sea necesario: automountServiceAccountToken: false.

Gestión de secretos

Los Secrets de Kubernetes están codificados en Base64, no cifrados, de forma predeterminada. Usa:

  • Cifrado en reposo: activa EncryptionConfiguration en el servidor de la API para cifrar los secretos en etcd
  • Gestores de secretos externos: AWS Secrets Manager, HashiCorp Vault o GCP Secret Manager a través del External Secrets Operator
  • Nunca pongas secretos en ConfigMaps, en variables de entorno de las especificaciones de Deployment (visibles con kubectl describe) ni en las imágenes de los contenedores

Políticas de red

De forma predeterminada, todos los pods de un clúster de Kubernetes pueden comunicarse entre sí. Implementa NetworkPolicy para aplicar microsegmentación:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
spec:
  podSelector: {}
  policyTypes: [Ingress]

Después, añade reglas de permiso explícitas solo para las rutas de comunicación necesarias. Usa un plugin de CNI que aplique NetworkPolicy (Calico, Cilium, Weave).

Postura de seguridad continua

  • Usa Falco (herramienta de seguridad en tiempo de ejecución de la CNCF) para detectar comportamientos sospechosos durante la ejecución: aperturas inesperadas de shells, conexiones salientes a nuevas IP, intentos de escalada de privilegios
  • Analiza las configuraciones del clúster con kube-bench (CIS Kubernetes Benchmark) y el operador de Trivy
  • Activa el registro de auditoría en el servidor de la API de Kubernetes y envía los logs a un SIEM
  • Rota con regularidad los digests de las imágenes y automatiza las actualizaciones de dependencias con Renovate o Dependabot
#Docker#Kubernetes#container security#DevSecOps#cloud