Network Policies (NetPol)
La Regla de Oro Por Defecto (Default Behavior)
Por defecto en Kubernetes, la red es completamente abierta.
-
Comportamiento "Non-Isolate": Todos los Pods pueden hablar con todos los Pods a lo largo de cualquier namespace del clúster sin ninguna restricción.
-
El Cambio de Estado: En el momento exacto en que seleccionas un Pod en una NetworkPolicy, ese Pod se vuelve aislado (Isolated). A partir de ahí, rechazará todo el tráfico excepto el que permitas explícitamente (Lista Blanca).
Requisito Obligatorio: El CNI Plugin
Una NetworkPolicy es solo un recurso declarativo (un YAML). Kubernetes por sí mismo no sabe cómo bloquear puertos.
- Requiere un plugin de red (CNI) que soporte e implemente las NetworkPolicies (ej. Calico, Cilium, Weave, Kube-router).
[!CAUTION] Si usas Flannel, las NetworkPolicies se crearán sin errores en el API Server, pero no bloquearán absolutamente nada.
Anatomía de una NetworkPolicy (Desglose del YAML)
Para no equivocarte nunca en los exámenes, grábate esta estructura mental basada en 4 pilares básicos:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-db
namespace: backend # 1. ¿DÓNDE vive la regla? (Scope)
spec:
podSelector:
matchLabels:
app: api-server # 2. ¿A QUÉ PODS del namespace aplica el aislamiento?
policyTypes:
- Ingress # 3. ¿Qué tipo de tráfico vamos a controlar?
- Egress
ingress: # 4. LAS REGLAS: ¿Qué permitimos entrar?
- from: # Si queremos que los Pods sean accedidos desde cualquier origen, podemos omitir la sección "from" y colocar directamente "ports"
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
Explicación de los selectores (from / to):
Hay tres tipos de selectores que se pueden usar en los bloques from (Ingress) o to (Egress):
- podSelector: Elige pods dentro del mismo namespace de la política.
- namespaceSelector: Elige todos los pods de un namespace que tenga esa etiqueta.
- ipBlock: Rangos de IPs CIDR (comúnmente usado para tráfico externo al clúster).
La Trampa más Común del Examen: AND vs OR
Un solo espacio o un guion (-) cambia por completo el significado de tu política de seguridad. Presta extrema atención a esto:
Caso A: Comportamiento "OR" (Separados por guion)
ingress:
- from:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: staging
- podSelector:
matchLabels:
app: frontend
- Significado: Permite el tráfico si viene de CUALQUIER pod en el namespace
stagingÓ si viene de un pod con etiquetaapp: frontenddentro del mismo namespace de la política.
Caso B: Comportamiento "AND" (Sin guion en el segundo selector)
ingress:
- from:
- namespaceSelector:
matchLabels:
env: staging
podSelector:
matchLabels:
app: frontend
- Significado: Permite el tráfico ÚNICAMENTE si viene de un pod que tenga la etiqueta
app: frontendY ADEMÁS ese pod se encuentre dentro de un namespace etiquetado conenv: staging.
Patrones de Diseño Útiles (Políticas por Defecto)
Denegar TODO el tráfico entrante (Default Deny All Ingress)
Es la mejor práctica de seguridad (utilizada exhaustivamente en el CKS). Aísla todos los pods del namespace actual.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: producción
spec:
podSelector: {} # {} significa "Todos los pods del namespace"
policyTypes:
- Ingress
# Al dejar el bloque ingress vacío, no se permite nada.
Permitir consultas DNS (Requerido para Egress)
Si bloqueas el tráfico saliente (Egress) de un Pod, este ya no podrá resolver nombres de dominio (servicios) porque no puede hablar con CoreDNS. Siempre debes permitir explícitamente el puerto 53 (UDP/TCP) hacia el namespace del sistema:
egress:
- to:
- namespaceSelector:
matchLabels:
kubernetes.io/metadata.name: kube-system
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- protocol: UDP
port: 53
- protocol: TCP
port: 53
Tips de Velocidad y Troubleshooting
-
No crees los YAML desde cero: En el examen, la documentación oficial tiene ejemplos listos de NetworkPolicies. Copia el bloque completo usando el truco del
cat <<EOF > policy.yamlque vimos anteriormente y edita solo los selectores. -
Comprobar etiquetas del Namespace: Si tu regla filtra por namespaces, asegúrate de que el namespace destino realmente tenga la etiqueta. Puedes listarlos y verificar con:
Si no la tiene, agrégala:
kubectl label ns <nombre-ns> env=staging. -
El comando de auditoría rápida: Para ver qué políticas están aplicando en un namespace: