NetworkPolicy en Kubernetes es una de esas funciones que parecen sencillas hasta que intentas aplicarlas en un clúster con mucho tráfico. En 2026 sigue siendo una pieza clave para el enfoque de mínimo privilegio, pero es fácil equivocarse porque la aplicación real depende del CNI, todo se basa en etiquetas, y “lo que querías” no siempre coincide con “lo que hace el API”. Esta guía se centra en los fallos que de verdad provocan incidentes y en patrones que los equipos repiten una y otra vez para segmentar tráfico sin romper producción.
El caso más habitual de “no funciona” no es un problema del YAML: NetworkPolicy es un API, no un cortafuegos por sí mismo. El clúster necesita una solución de red que implemente la aplicación de NetworkPolicy; si no, puedes tener políticas creadas y aun así no cambiar nada. Incluso con aplicación activada, el comportamiento puede variar según el CNI en detalles, registros y visibilidad, así que conviene verificarlo en lugar de darlo por hecho.
También hay que ser preciso con el concepto de aislamiento. Por defecto, los pods no están aislados y aceptan tráfico desde cualquier origen. Un pod pasa a estar aislado para ingress y/o egress solo cuando una política lo selecciona y cubre esa dirección (mediante policyTypes o el comportamiento implícito). A partir de ese momento, las reglas son listas de अनुमति: el tráfico solo se permite si al menos una política aplicable lo autoriza; lo demás se deniega para la dirección aislada.
Por último, recuerda la capa en la que trabaja NetworkPolicy. La política clásica es principalmente L3/L4: IPs, namespaces, pods y puertos. Si tu objetivo es “permitir solo esta ruta HTTP” o “solo este nombre DNS”, normalmente necesitas extensiones del CNI o APIs de políticas más recientes, no forzar esos requisitos dentro de NetworkPolicy básica.
Confiar en una política en un clúster donde la aplicación no está habilitada (o no lo está en todos los node pools) sigue siendo un error frecuente. El YAML parece correcto, CI pasa, pero nada cambia, y el equipo lo descubre en una auditoría o tras un incidente. Conviene tener una comprobación explícita en runbooks: qué CNI aplica políticas y cómo validarlo en un namespace de pruebas.
Dejar policyTypes implícito y asumir que cubre ambas direcciones crea brechas sutiles. Muchos equipos escriben una política de ingress y dan por hecho que también limita el tráfico saliente, y luego descubren que el egress quedó abierto. Para cargas donde el acceso saliente importa (casi todas), es mejor ser explícito.
Otro malentendido habitual es creer que los Services son “objetivos” de la política. NetworkPolicy selecciona pods, no Services. Puedes diseñar reglas que coincidan con los pods detrás de un Service, pero el nombre del Service no es un selector. Cuando alguien “permite el Service”, a menudo olvida cómo están etiquetados los pods y la regla acaba sin coincidir con nada.
Un esquema de segmentación que aguanta cambios reales en la organización parte de límites que significan algo: namespaces para tenancy y ciclo de vida, etiquetas para identidad y rol de la app, y una lista pequeña de servicios compartidos (DNS, logging, métricas, ingress, gateways de malla) a los que muchas cargas deben llegar. Si estos básicos son inconsistentes, las políticas se vuelven frágiles y el resultado suele ser desactivarlas o añadir excepciones demasiado amplias.
Un patrón práctico es estandarizar un contrato mínimo de etiquetas: app.kubernetes.io/name, app.kubernetes.io/part-of, app.kubernetes.io/component y una etiqueta de entorno o tenant a nivel de namespace. Así, los selectores se vuelven legibles, previsibles y reduces el “¿por qué no coincide?” provocado por etiquetas improvisadas.
Los servicios compartidos merecen un tratamiento especial. DNS es la causa más común de caídas durante el despliegue: el equipo activa egress con denegación por defecto y se olvida de permitir salida hacia los pods de DNS (y a veces hacia la IP de node-local DNS si se usa). Trata DNS y cualquier proxy de salida obligatorio como dependencias de primer nivel y refléjalas explícitamente en tu patrón base.
Patrón 1: “Base por namespace + refinamiento por aplicación”. Empieza con default-deny para ingress (y egress cuando aplique) a nivel de namespace, y luego añade reglas pequeñas por servicio. La idea no es tener una matriz perfecta el primer día, sino crear un perímetro controlado e iterar con seguridad a medida que aparecen flujos legítimos.
Patrón 2: “Lista permitida para servicios compartidos”. Mantén un conjunto reducido de políticas (a menudo propiedad de SRE) que permita a los namespaces de aplicaciones llegar a servicios esenciales: DNS, agentes de observabilidad, endpoints de admisión/webhooks operativos y, cuando sea necesario, componentes del ingress. Debe ser corto y revisado, porque cada excepción “compartida” puede facilitar movimiento lateral si crece sin control.
Patrón 3: “Capas por rol dentro de un namespace”. Si prefieres menos namespaces, usa roles como role=frontend, role=backend, role=db y define flujos permitidos: frontend → backend, backend → db, y deniega lo demás. Esto encaja con la arquitectura habitual y reduce la proliferación de selectores únicos.

La estrategia más segura en 2026 sigue siendo la aplicación progresiva. Primero documentas flujos previstos (una tabla simple suele bastar), después introduces default-deny en un alcance controlado y añades reglas de permiso de forma iterativa mientras monitorizas. El enfoque “todo de golpe” (activar denegación por defecto en todas partes y arreglar roturas en vivo) casi siempre acaba en un incidente ruidoso y un rollback.
Las pruebas deben incluir casos positivos y negativos. No basta con confirmar “el servicio A puede llamar al servicio B”; también necesitas una prueba de regresión que verifique “el servicio C no puede llamar al servicio B”. Sin pruebas negativas, con el tiempo las políticas tienden a volverse más permisivas sin que nadie lo note.
Para diagnosticar, ayuda un método consistente. Empieza confirmando si el pod está seleccionado por alguna política (y para qué dirección), luego lista las políticas del namespace que podrían aplicar y solo entonces revisa reglas. Si tu CNI ofrece visibilidad de flujos o logs de veredicto de política, úsalo pronto: reduce la depuración de horas a minutos al mostrar qué regla permitió o bloqueó una conexión.
El egress es donde suele aparecer el dolor real: APIs externas, repositorios de paquetes, proveedores de identidad y webhooks convierten el “denegar por defecto” en una lista larga de permisos. Dos mitigaciones útiles: enrutar la salida por un camino controlado (proxy o gateway) y permitir egress principalmente hacia ese punto, en lugar de abrir decenas de destinos externos.
Los namespaceSelector fallan en la práctica cuando los namespaces no están etiquetados de forma consistente. Se escriben reglas que dependen de esa selección y luego se descubre que namespaces del sistema o heredados no tienen etiquetas, así que la regla no puede coincidir. La corrección es tanto organizativa como técnica: definir un estándar mínimo de etiquetado de namespaces y hacerlo cumplir.
Por último, vigila la evolución del ecosistema de políticas. En upstream existe trabajo continuo alrededor de APIs de políticas con alcance administrativo (a menudo como CRDs) para establecer guardarraíles globales. Si necesitas reglas base transversales a múltiples namespaces, evalúa esas opciones en tu entorno en lugar de intentar simular “política del clúster” únicamente con objetos NetworkPolicy por namespace.