Saltar a contenido

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 etiqueta app: frontend dentro 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: frontend Y ADEMÁS ese pod se encuentre dentro de un namespace etiquetado con env: 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.yaml que 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:

    kubectl get ns --show-labels
    

    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:

    kubectl get netpol -n <namespace>