Skip to main content

Prácticas recomendadas para las políticas de red de Kubernetes

Escrito por

Peter De Tender

Kubernetes Blog

21 de diciembre de 2022

0 minutos de lectura

Controlar y filtrar el tráfico al contenerizar una carga de trabajo en Pods de Kubernetes es tan crucial como usar un firewall en una configuración de red más tradicional. La diferencia es que, en este escenario, estas capacidades las proporciona la API Kubernetes NetworkPolicy.

En este artículo exploraremos Kubernetes NetworkPolicy creando una política de red de ejemplo y examinando sus parámetros principales. Luego, veremos algunos casos de uso comunes de NetworkPolicy y aprenderemos a monitorearlos con kubectl. Por último, descubriremos cómo implementar la Container Network Interface (CNI) mediante extensiones de Kubernetes de terceros.

Por qué no deberías evitar las políticas de red de Kubernetes

Implementar políticas de red es fundamental para operar un entorno de Kubernetes. Sin una política de red configurada, todos los Pods de un clúster pueden comunicarse entre sí de forma predeterminada. Por eso, si nuestro Pod contiene datos confidenciales, como una base de datos de backend con información privada, debemos asegurarnos de que solo ciertos Pods de frontend puedan conectarse a él.

También podemos aislar el tráfico de red entre los Pods de un entorno de desarrollo y los que se ejecutan en un entorno de producción. Sin políticas de red, todo el tráfico circula libremente hacia y desde todos los puntos de la red.

Por suerte, configurar Kubernetes NetworkPolicy es una forma sencilla, eficaz e integral de garantizar que el tráfico de red fluya solo según lo previsto.

Definición de políticas de red de Kubernetes

Veamos un ejemplo de NetworkPolicy. Considera una carga de trabajo de ejemplo con un frontend de WordPress y un backend de base de datos MySQL, que ejecuta una colección de Pods con servicios web y de base de datos, todos implementados en el espacio de nombres default de Kubernetes. Los protocolos de seguridad de la empresa exigen que aislemos el tráfico de red de cargas de trabajo específicas y permitamos solo el tráfico entrante y saliente mínimo necesario para usarlas.

Esta estrategia contempla las siguientes condiciones:

  • Bloquear el comportamiento predeterminado de Kubernetes que permite todo el tráfico.

  • Asegurarse de que solo los Pods con la etiqueta wordpress en el espacio de nombres default puedan comunicarse entre sí.

  • Permitir la conectividad entrante (ingress) desde la Internet pública en los puertos 80/443 y desde el rango de IP 172.16.0.0.

  • Permitir únicamente que los Pods con la etiqueta wordpress se conecten a los Pods de la base de datos MySQL por el puerto 3306.

  • Permitir siempre la conectividad con el servicio DNS de Kubernetes (puerto 53).

  • Bloquear toda conectividad saliente fuera del clúster.

El diagrama de red de abajo ilustra cómo podrían verse estas reglas.

Diagrama que muestra las políticas predeterminadas de denegación de entrada y salida en un espacio de nombres de Kubernetes, con tráfico seleccionado en los puertos 80 y 443 y tráfico DNS permitido.

Para este ejemplo, podemos distribuir las políticas de red entre los archivos de definición de políticas o combinarlas en un solo archivo de manifiesto YAML. Como nuestro ejemplo utiliza una carga de trabajo (webapp), tiene sentido usar un solo archivo de definición del conjunto de reglas. Sin embargo, como este ejemplo incluye varias conexiones de entrada y salida, también podríamos crear archivos de configuración individuales para cada conexión dentro del clúster.

Revisemos varios de los parámetros anteriores para entender cómo se relacionan con la configuración y cómo afectan el comportamiento del tráfico de red.

API y metadatos

En la primera línea del archivo YAML de abajo, especificamos la API de redes (networking.k8s.io) y su versión (v1). También definimos el tipo de archivo YAML como NetworkPolicy para indicar al controlador de la API de Kubernetes que estamos configurando políticas de red. Los elementos name y namespace de la sección metadata contienen el nombre que asignamos a este conjunto de reglas y el espacio de nombres al que está vinculado.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-network-policy
  namespace: default

La siguiente parte del archivo YAML contiene la sección de especificaciones (specs), donde podemos establecer los filtros que aplicará la política de red.

El siguiente fragmento incluye varios parámetros importantes:

  • podSelector — Especifica qué Pods están sujetos a las políticas de tráfico establecidas. Nuestro ejemplo usa el parámetro matchLabels para garantizar que la política de red se aplique a todos los Pods con la etiqueta app: wordpress. Además, el parámetro excluye de esta política de red a todos los demás Pods.

  • policyTypes — Contiene dos categorías: Ingress y Egress

  • Ingress — Define todo el tráfico entrante de Pods, espacios de nombres o colecciones de Pods

  • Egress — Define todo el tráfico saliente de Pods, espacios de nombres o colecciones de Pods

spec:
  podSelector:
    matchLabels:
      app: wordpress
  policyTypes:
    - Egress
    - Ingress

A continuación, la sección ingress de la política de red define los tipos de tráfico entrante permitidos. La siguiente sección permite el tráfico entrante en los puertos 443 y 80 desde:

  • Todos los Pods con la etiqueta wordpress

  • Todo el tráfico de la Internet pública (cidr: 0.0.0.0/0)

  • Todas las direcciones IP del rango 172.16.0.0/16, que podría representar un rango de IP corporativo (una VPN, VLAN o subred).

El fragmento YAML que permite el tráfico anterior se vería así:

  ingress:
    - from:
      - podSelector:
          matchLabels:
            app: wordpress
      ports:
        - port: 443
        - port: 80  
    - from:
      - ipBlock:
          cidr: 172.16.0.0/16
      ports:
        - port: 443
        - port: 80
    - from:
      - ipBlock:
          cidr: 0.0.0.0/0
      ports:
        - port: 443
        - port: 80

Por último, detallamos la sección egress con las reglas de tráfico saliente. Permitimos que el tráfico saliente de los Pods con la etiqueta webapp se comunique por los puertos 1433 (SQL) y 53 (DNS).

Especificar la etiqueta webapp garantiza que ningún otro Pod pueda comunicarse con las instancias de SQL Server, lo que elimina todos los riesgos de seguridad relacionados. De manera similar, la configuración permite que el puerto 53 se conecte a todos los Pods del clúster.

Hay otra conclusión importante de esta definición de política. Una vez que integramos la política de red para controlar la conectividad de los Pods, debemos configurar los ajustes de permiso y denegación en ambas direcciones. Permitir el tráfico saliente del frontend sin permitir el tráfico entrante al backend impedirá la comunicación.

El fragmento YAML para esta parte del tráfico se ve así:

  egress: 
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP

    - to:
        - podSelector:
            matchLabels:
              app: wordpress
      ports:
        - port: 3306

Aplicación de políticas de red de Kubernetes

Ya terminamos el manifiesto YAML de ejemplo de NetworkPolicy, que se ve así:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: sample-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: webapp
  policyTypes:
    - Egress
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app: webapp
      ports:
        - port: 443
        - port: 80
    - from:
        - podSelector: {}
    - from:
        - ipBlock:
            cidr: 172.16.0.0/16
      ports:
        - port: 443
        - port: 80
    - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      ports:
        - port: 443
        - port: 80
  egress:
    - to:
        - namespaceSelector: {}
          podSelector:
            matchLabels:
              k8s-app: kube-dns
      ports:
        - port: 53
          protocol: UDP
    - to:
        - podSelector: {}
    - to:
        - podSelector:
            matchLabels:
              app: webapp
      ports:
        - port: 443
        - port: 80

Ahora debemos incorporar el archivo al clúster de Kubernetes. Para hacerlo, primero guarda el archivo como sample-network-policy.yaml.

Ahora aplicamos el archivo de definición como la mayoría de las demás configuraciones de Kubernetes: mediante la interfaz de línea de comandos (CLI) kubectl.

Ejecuta el siguiente comando:

kubectl apply -f sample-network-policy.yaml
Terminal que muestra la creación de la política de red de Kubernetes de ejemplo con kubectl apply

Validación y monitoreo de las políticas de red de Kubernetes

Al igual que con la administración tradicional de firewalls, la validación y el monitoreo de las políticas de red de Kubernetes requieren supervisión operativa. De vez en cuando, debemos volver a evaluar las reglas de red existentes para decidir si siguen siendo aplicables a la carga de trabajo asociada.

También es posible que debamos validar el conjunto de reglas para solucionar problemas de tráfico o investigar conflictos entre distintas políticas de red. Por suerte, podemos validar las políticas de red mediante la CLI kubectl. Ejecutar el siguiente comando analiza y monitorea tus políticas de red actuales:

kubectl describe networkpolicy <networkpolicy name as listed in the YAML manifest>

A continuación, se muestra un ejemplo del resultado para el tipo de política ingress.

Salida de terminal que muestra una Kubernetes NetworkPolicy con «Permitir tráfico de entrada» resaltado y reglas para los puertos 443 y 80.

Además, esta imagen muestra un ejemplo del resultado para el tipo de política egress:

Salida de la terminal que muestra el tráfico de salida permitido hacia kube-dns y los pods de la aplicación web, con tipos de política de salida y entrada

Prácticas recomendadas para aplicar políticas de red de Kubernetes

Como en cualquier configuración de seguridad de red, conviene seguir varias prácticas recomendadas para las políticas de red de Kubernetes:

  • Usa la política de red predeterminada deny-all para garantizar que solo se permita la comunicación autorizada explícitamente.

  • Agrupa los Pods que deben comunicarse entre sí mediante el parámetro PodSelector.

  • Permite la comunicación entre espacios de nombres solo cuando sea necesario.

  • No permitas comunicaciones de red innecesarias, ni siquiera dentro del clúster de Kubernetes.

  • Ten cuidado al permitir que los Pods del clúster reciban tráfico de red que provenga de fuera del clúster.

  • Denegar el tráfico saliente hacia la Internet pública podría interferir con ciertas actualizaciones de aplicaciones o procesos de validación.

Los complementos CNI de Kubernetes optimizan la administración de políticas de red

Una de las ventajas de los complementos CNI es que abstraen los detalles de implementación de NetworkPolicy, lo que permite que quienes administran el clúster elijan la mejor solución para sus necesidades sin tener que lidiar con la complejidad de las tecnologías subyacentes.

Sin embargo, las instalaciones predeterminadas de Kubernetes no incluyen un complemento CNI preinstalado, a menos que la distribución o el proveedor haya agregado uno. Esto significa que tendrás que elegir e instalar el complemento que mejor se adapte a tus necesidades. Además, aunque tu distribución incluya uno predeterminado, es posible que otro se ajuste mejor a tus requisitos.

Hay muchos proveedores de CNI, y algunos de los más populares son:

Cada complemento tiene capacidades únicas, así que quizá debas probar varios para decidir cuál se adapta mejor a tus requisitos de red y seguridad de red.

Conclusión

Configurar una topología de red empresarial con enrutamiento complejo, reglas de tráfico e integraciones de seguridad puede ser tedioso. Por suerte, en un entorno de Kubernetes, las políticas de red pueden cumplir la misma función que los firewalls en una infraestructura tradicional.

Por supuesto, configurar políticas de red es solo el primer paso de un proceso que requiere reevaluaciones y mantenimiento periódicos. Aunque el complemento kubenet integrado ofrece ciertas capacidades de red para administrar tus políticas, otros complementos CNI ofrecen funcionalidades más avanzadas. Por suerte, la combinación adecuada de políticas y administración garantiza que el tráfico de red se mantenga seguro y eficiente.

Recursos adicionales sobre seguridad de Kubernetes

Protege la infraestructura desde el origen

Snyk automatiza la seguridad y el cumplimiento de IaC en los flujos de trabajo, y detecta recursos con desviaciones de configuración y recursos faltantes.