Kubernetes - runtime seguro
El clúster Kubernetes es un sistema operativo distribuido: RBAC, admission controllers y policies rigen lo que cada pod puede hacer, montar y exponer.
Qué es
Kubernetes no es solo un orquestador de contenedores, es un sistema operativo distribuido con propia: API, etcd, red de pods, secrets y volúmenes. Cada capa trae controles: RBAC dice quién puede pedir qué a la API, los admission controllers dicen qué puede entrar al clúster, las NetworkPolicies dicen con qué otros pods puede hablar cada pod, y el kubelet dice qué puede hacer cada contenedor en el nodo.
Tratar a Kubernetes como 'solo un deploy runner' es el error que filtra tokens en logs, abre puertos a internet y corre contenedores como root con sistemas de archivos escribibles. Defender el clúster exige los cuatro controles combinados, no solo uno.
RBAC: la primera cerca
RBAC (Role-Based Access Control) vincula un sujeto (ServiceAccount, User, Group) a un rol, y el rol a un conjunto de verbos sobre recursos. Funciona en dos niveles: Role + RoleBinding (alcance de namespace) y ClusterRole + ClusterRoleBinding (alcance de todo el clúster).
El error clásico es dar cluster-admin al pipeline de CI o a un service account de aplicación. Funciona, el deploy pasa, y cualquier RCE en un pod se vuelve control total del clúster, incluyendo la lectura de todos los secrets en todos los namespaces.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ci-deployer-all
subjects:
- kind: ServiceAccount
name: ci-runner
namespace: ci
roleRef:
kind: ClusterRole
name: cluster-admin # poder total, en todo el clúster
apiGroup: rbac.authorization.k8s.ioapiVersion: v1
kind: Namespace
metadata:
name: payments
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: deployer
namespace: payments
rules:
- apiGroups: ["apps"]
resources: ["deployments", "replicasets"]
verbs: ["get", "list", "watch", "update", "patch"]
- apiGroups: [""]
resources: ["pods", "pods/log"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: ci-deployer
namespace: payments
subjects:
- kind: ServiceAccount
name: ci-runner
namespace: ci
roleRef:
kind: Role
name: deployer
apiGroup: rbac.authorization.k8s.ioNetworkPolicies: el firewall de los pods
Por defecto, todo pod habla con todo pod en todo namespace. Las NetworkPolicies corrigen esto: son selectores de pod que dicen quién puede entrar y salir, con semántica de allowlist (lo que no está permitido está bloqueado).
La primera política siempre es la de deny-by-default en el namespace. Sin ella, abrir un puerto nuevo en un pod es abrir un puerto nuevo en todo el clúster. La segunda viene con allow explícito para el tráfico legítimo (ingress desde el ingress controller, salida hacia APIs externas, pod-to-pod dentro de la misma app).
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: payments
spec:
podSelector: {} # vale para todos los pods del namespace
policyTypes:
- Ingress
- Egress
ingress: [] # nada entra
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
ports:
- protocol: UDP
port: 53 # DNS para resolver servicios externosAdmission control: política antes de que el pod suba
Los admission controllers están entre la aceptación del request y la persistencia en etcd. Pueden validar (rechazar) o mutar (reescribir) el manifiesto. Kubernetes trae Pod Security Admission (PSA) integrado desde la 1.23, con profiles privileged, baseline y restricted. Para lógica más fina entran los policy engines:
- Gatekeeper: usa Rego, sintaxis de , ideal para equipos con cultura de ingeniería de políticas
- Kyverno: YAML puro, se lee como un manifiesto normal de Kubernetes, ideal para equipos que quieren escribir policies sin aprender otro lenguaje
- Pod Security Admission: nativo, sin dependencias extra, los profiles baseline y restricted cubren el 80% de los casos
- ValidatingAdmissionPolicy (KEP-3485): admission declarativo en CEL, estabilizándose en versiones recientes
Secretos en etcd: cifrado en reposo
Por defecto, los secrets en etcd se guardan en texto plano (solo base64 en el YAML). Quien tenga acceso de lectura a etcd, o a un backup de este, lee todos los tokens, contraseñas y claves. El encryption at rest resuelve esto: cada clave de etcd se cifra con una clave envuelta por un .
El precio es gestionar una clave (rotación, revocación), y lo que se gana es : incluso un dump de etcd se vuelve dato inerte sin el KMS.
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
- secrets
providers:
- kms:
name: aws-kms
endpoint: unix:///var/run/kms-provider/socket
cachesize: 100
keyid: arn:aws:kms:us-east-1:111122223333:key/abcd-...
- identity: {} # fallback para leer datos antiguosDónde aparece
Kubernetes es la frontera entre lo que produjo el pipeline y lo que va a correr en producción. Toda defensa que falló antes (imagen sin escanear, manifiesto sin policy) cae aquí: el admission control rechaza, la NetworkPolicy aísla, el RBAC limita el daño. Por otro lado, es la última oportunidad de corregir lo que pasó: PSP/PSA atrapa un manifiesto laxo, OPA atrapa labels incorrectos, los secrets en KMS neutralizan un dump de etcd.
Puntos fuertes
- los controles nativos de Kubernetes ya cubren RBAC, NetworkPolicy, PSA, encryption at rest: no hay que comprar nada
- policy as code (Kyverno, Gatekeeper) pasa a ser cosa de PR, con review y pruebas, no de ticket urgente
- los namespaces se vuelven unidades de aislamiento baratas, dando un límite de sin necesitar clústeres separados
Limitaciones
- RBAC, NetworkPolicy y admission son controles default-deny: deben configurarse antes de que corra cualquier cosa, y el camino de migración para un clúster existente es manual
- todo el clúster es tan seguro como el nodo: un kubelet expuesto o un contenedor con privilegios rompe las garantías de las capas de arriba
- operar policies a escala (X clústeres, Y namespaces) se vuelve trabajo de plataforma, no de app, y sin un responsable se vuelve un desorden
conexiones en el mapa
- CSPM - postura cloudaudita la posturaKubernetes - runtime seguro
- CWPP - protección de workloadsdetecta comportamientoKubernetes - runtime seguro
actualizado el 14/10/2026 · fuentes para profundizar · reportar un error
Estudia antes
pon a prueba lo que entendiste
Cargando preguntas…