Skip to content

Network Policies

Desarrollo del tema

¿Qué es una NetworkPolicy en Kubernetes?

K8S-NetworkPolicy-Example

Las Network Policies en Kubernetes son una estructura que permite especificar cómo un Pod puede comunicarse con otras "entidades" a través de la red (se usa el termino "entidad" para evitar sobrecargar los términos más comunes como "endpoints" y "servicios" en Kubernetes) a través de la red.

Las Network Policies son centradas en aplicaciones y permiten controlar el tráfico de red a nivel de dirección IP o puertos para los protocolos TCP, UDP y SCTP (capa OSI 3 o 4). En si, se pueden establecer reglas para permitir o bloquear conexiones entre Pods en un clúster de Kubernetes.

Las entidades con las que un Pod puede comunicarse se identifican mediante una combinación de los siguientes tres identificadores:

  • Otros pods que están permitidos (excepción: un pod no puede bloquear el acceso a sí mismo).

  • Namespaces permitidos.

  • Bloques de IP (excepción: el tráfico hacia y desde el nodo donde se ejecuta un Pod siempre está permitido, independientemente de la dirección IP del Pod o del nodo).

A parte de los identificadores, es importante tener en cuenta los dos tipos de aislamiento para un pod:

  • Ingress: Controla el tráfico entrante hacia los Pods. Puedes especificar reglas para permitir o bloquear conexiones desde fuentes específicas.

  • Egress: Controla el tráfico saliente desde los Pods. Puedes definir políticas para permitir o restringir conexiones hacia destinos específicos.

¿Cuándo usar Network Policies?

Utiliza Network Policies cuando se necesite restringir el acceso entre Pods en función de reglas específicas. Por ejemplo, se puede permitir que solo ciertos Pods se comuniquen con un servicio de base de datos o bloquear el tráfico hacia Pods sensibles.

Aquí un ejemplo de una Network Policy que ilustra esto:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-db-access
spec:
  podSelector:
    matchLabels:
      app: my-app
  ingress:
    - from:
        - podSelector:
            matchLabels:
              role: database
      ports:
        - protocol: TCP
          port: 3306

En este ejemplo:

  • Los Pods con la etiqueta app: my-app pueden recibir tráfico desde Pods con la etiqueta role: database en el puerto 3306.

  • El tráfico saliente no está restringido en esta política.

Las Network Policies en Kubernetes también permiten aplicar condiciones AND y OR para controlar según la necesidad varias reglas.

  • AND: Cuando se aplica una condición AND, se está especificando que ambas condiciones deben cumplirse para permitir el tráfico. Por ejemplo, puedes crear una Network Policy que permita el tráfico solo si el Pod coincide con ambos selectores (por etiquetas o namespaces).

  • OR: Cuando se aplica una condición OR, se está permitiendo el tráfico si al menos una de las condiciones se cumple. Por ejemplo, puedes crear una Network Policy que permita el tráfico si el Pod coincide con cualquiera de los selectores especificados.

Ejemplo de Network Policy con varias condiciones:

Declaración de NetworkPolicy

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-db-access
spec:
podSelector:
    matchLabels:
    app: my-app
ingress:
    - from:
        - podSelector:
            matchLabels:
            role: database
        - namespaceSelector:
            matchLabels:
            environment: production
    ports:
    - protocol: TCP
        port: 3306

En este ejemplo:

  • El tráfico está permitido si el Pod tiene la etiqueta app: my-app.

  • Además, el tráfico puede venir de Pods con la etiqueta role: database o de cualquier namespace con la etiqueta environment: production.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-db-access
spec:
podSelector:
    matchLabels:
    app: my-app
ingress:
    - from:
        - podSelector:
            matchLabels:
            role: database
          namespaceSelector:
            matchLabels:
            environment: production
    ports:
    - protocol: TCP
        port: 3306

En este ejemplo:

  • El tráfico está permitido si el Pod tiene la etiqueta app: my-app.

  • Además, el tráfico puede venir de Pods con la etiqueta role: database y de cualquier namespace con la etiqueta environment: production. Esto es porque, namespaceSelector forma parte del listado podSelector y no de from.

Importante tener en cuenta que las políticas de red son implementadas por el plugin de red que se esté utilizando, por lo tanto hay que asegurarse de que la solución de red soporte NetworkPolicy para que las políticas tengan efecto. A continuación, las soluciones de red de Kubernetes que soportan NetworkPolicy.

  • Kube-router

  • Calico

  • Romana

  • Weave-net

Laboratorio: Creación de NetworkPolicy

Descripción

En la presente guía se creara una NetworkPolicy para un Deployment en el cluster de kubernetes que se ha usado para los laboratorios.

Objetivos

  • Restringir el tráfico de red entre Pods según reglas específicas, para mejorar la seguridad, aislar aplicaciones y definir políticas de acceso.

Antes de comenzar

  • Contar con el acceso al ambiente del laboratorio.

Conexión hacia cluster

  1. Ingrese al cluster asignado con las credenciales proporcionadas.

  2. Configure la variable KUBECONFIG.

    export KUBECONFIG=~/devcluster/kube_config_cluster.yml
    
  3. Verifique el acceso mediante comandos.

    kubectl get namespaces
    

Inicio de laboratorio

  1. Crear un nuevo namespace llamado example-networkpolicy

    kubectl create ns example-networkpolicy
    

    Establecer el nuevo namespace por defecto en el contexto actual:

    kubectl config set-context --current --namespace=example-networkpolicy
    
  2. Crear un Deployment y exponerlo mediante un Service:

    • Crear un Deployment con Nginx:
    kubectl create deployment nginx-deployment --image=nginx
    
    • Crear una exposición del Deployment mediante un Service:
    kubectl expose deployment nginx-deployment --port=80 --target-port=80 --type=ClusterIP
    
  3. Prueba el Service desde un segundo Pod:

    • Crea un segundo Pod para probar la conexión:
    kubectl run busybox-pod --image=busybox --command -- sleep infinity
    kubectl exec busybox-pod -it -- /bin/sh
    
    • Desde el Pod de BusyBox, verifica que puedas acceder al Service:
    wget -O- http://nginx-deployment
    
  4. Limita el acceso al Service:

    • Define una Network Policy (por ejemplo, en un archivo nginx-network-policy.yaml):
    mkdir example-networkpolicy; vim example-networkpolicy/nginx-network-policy.yaml
    
    • Se agrega el siguiente contenido:
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      name: allow-nginx-access
    spec:
      podSelector:
        matchLabels:
          app: nginx-deployment
      ingress:
      - from:
        - podSelector:
            matchLabels:
              role: database
        ports:
        - protocol: TCP
          port: 80
      policyTypes:
      - Ingress
    
    • Aplica la Network Policy:
    kubectl apply -f example-networkpolicy/nginx-network-policy.yaml
    
  5. Prueba el Service desde el segundo Pod:

    • Ingresa nuevamente al segundo Pod:
    kubectl exec busybox-pod -it -- /bin/sh
    
    • Desde el segundo Pod de BusyBox, nos daremos cuenta que no hay respuesta:
    wget -O- http://nginx-deployment
    
  6. Prueba el Service desde un tercer Pod:

    • Crea un tercer Pod con los Labels especificados en la NetworkPolicy:
    kubectl run busybox-pod-labels --image=busybox --labels role=database --command -- sleep infinity
    kubectl exec busybox-pod-labels -it -- /bin/sh
    
    • Desde el Pod, verifica que ahora si hay respuesta:
    wget -O- http://nginx-deployment
    
  7. Limpiamos el ambiente:

    kubectl delete pod busybox-pod-labels --force --grace-period=0
    kubectl delete pod busybox-pod --force --grace-period=0
    kubectl delete ns example-networkpolicy
    kubectl config set-context --current --namespace=default