Descripción general de la red

En esta página se proporciona una descripción general de los aspectos principales de las herramientas de redes de Google Kubernetes Engine. Esta información le resulta útil a quienes recién están comenzando con Kubernetes, así como a operadores de clústeres o desarrolladores de aplicaciones experimentados que necesitan más conocimientos sobre las herramientas de redes de Kubernetes para diseñar mejor las aplicaciones o configurar las cargas de trabajo de Kubernetes.

Kubernetes te permite definir de manera expresa cómo se implementan tus aplicaciones, cómo las aplicaciones se comunican entre sí y con el plano de control de Kubernetes, y cómo los clientes pueden llegar a tus aplicaciones. En esta página también se proporciona información sobre cómo GKE configura los servicios de Google Cloud Platform, si es necesario para las herramientas de redes.

Cuando usas Kubernetes para organizar tus aplicaciones, es importante cambiar tu forma de pensar acerca del diseño de red de tus aplicaciones y sus hosts. Con Kubernetes, piensas en cómo se comunican los pods, los servicios y los clientes externos, en lugar de pensar en cómo se conectan tus hosts o VM.

Kubernetes, junto con GCP, configura dinámicamente las reglas de filtrado de IP, las tablas de enrutamiento y las reglas de firewall en cada nodo, según el modelo expreso de tus implementaciones de Kubernetes y tu configuración de clúster en GCP. No realices cambios manuales en los nodos, ya que GKE anula esos cambios y tu clúster podría no funcionar correctamente. La única razón de acceder directamente a un nodo es para depurar problemas con tu configuración.

Requisitos previos

En esta página se utiliza terminología relacionada con las capas de Transporte, Internet y Aplicación de la suite de protocolo de Internet, incluidos HTTP y DNS, pero no es necesario ser experto en estos temas.

Además, es posible que este contenido te resulte más fácil de entender si tienes un conocimiento básico de los conceptos y utilidades de administración de red de Linux, como el enrutamiento y las reglas de iptables.

El modelo de herramientas de redes de Kubernetes se basa en gran medida en las direcciones IP. Los servicios, pods, contenedores y nodos se comunican mediante direcciones IP y puertos. Kubernetes proporciona tipos diferentes de balanceo de cargas para dirigir el tráfico a los pods correctos. Todos estos mecanismos se describen en detalle más adelante en esta sección. Ten en cuenta los siguientes términos mientras avanzas en la lectura:

  • ClusterIP: la dirección IP asignada a un servicio. También se la llama “IP de clúster” en otros documentos. Esta dirección es estable durante el ciclo de vida del servicio, como se explica en la sección Servicios más adelante.
  • IP de pod: la dirección IP asignada a un pod determinado. Es efímera, como se explica en la sección Pods más adelante.
  • IP de nodo: la dirección IP asignada a un nodo determinado.

Herramientas de redes dentro del clúster

En esta sección se analizan las herramientas de redes dentro de un clúster de Kubernetes, en relación con la asignación de IP, los pods y los servicios.

Asignación de IP

Kubernetes utiliza varios rangos de IP para asignar direcciones IP a nodos, pods y servicios.

  • Cada nodo tiene una dirección IP asignada desde la red de la nube privada virtual (VPC) del clúster. Esta IP de nodo proporciona conectividad desde componentes de control, como kube-proxy y kubelet, al servidor de API de Kubernetes.
  • Cada pod tiene una dirección IP asignada desde un rango de 256 direcciones IP, un bloque CIDR /24. Tienes la opción de especificar este rango cuando creas el clúster.
  • Cada servicio tiene una dirección IP, llamada ClusterIP, asignada desde la red de VPC del clúster. Tienes la opción de personalizar la red de VPC cuando creas el clúster.

Para obtener más información, visita Cómo crear clústeres de VPC nativa con IP de alias.

Pods

En Kubernetes, un pod es la unidad implementable más básica dentro de un clúster Kubernetes. Un pod ejecuta uno o más contenedores. Cero o más pods se ejecutan en un nodo. Cada nodo en el clúster es parte de un grupo de nodos. En GKE, estos nodos son máquinas virtuales que se ejecutan cada una como una instancia en Compute Engine.

Los pods también pueden adjuntarse a volúmenes de almacenamiento externo y otros recursos personalizados. En este diagrama se muestra un solo nodo que ejecuta dos pods, cada uno adjunto a dos volúmenes.

Diagrama que muestra un solo nodo que ejecuta dos pods, como se describe en el párrafo anterior

Cuando Kubernetes programa un pod con el fin de que se ejecute en un nodo, crea un espacio de nombres de red para el pod en el kernel de Linux del nodo. Este espacio de nombres de red conecta la interfaz de red física del nodo, como eth0, con el pod mediante una interfaz de red virtual, a fin de que los paquetes puedan fluir hacia y desde el pod. La interfaz de red virtual asociada en el espacio de nombres de la red raíz del nodo se conecta a un puente de Linux que permite la comunicación entre los pods en el mismo nodo. Un pod también puede enviar paquetes fuera del nodo con la misma interfaz virtual.

Kubernetes asigna una dirección IP (la IP del pod) a la interfaz de red virtual en el espacio de nombres de la red del pod desde un rango de direcciones reservadas para pods en el nodo. Este rango de direcciones es un subconjunto del rango de direcciones IP asignado al clúster para pods, que puedes configurar cuando creas un clúster.

Un contenedor que se ejecuta en un pod utiliza el espacio de nombres de red del pod. Desde el punto de vista del contenedor, el pod parece ser una máquina física con una interfaz de red. Todos los contenedores en el pod ven esta misma interfaz de red. El localhost de cada contenedor está conectado, a través del pod, a la interfaz de red física del nodo, como eth0.

De manera predeterminada, cada pod tiene acceso ilimitado a todos los otros pods que se ejecutan en todos los nodos del clúster, pero puedes limitar el acceso entre los pods. Kubernetes elimina y recrea pods regularmente. Esto sucede cuando se actualiza un grupo de nodos, cuando se cambia la configuración expresa del pod o la imagen de un contenedor, o cuando un nodo deja de estar disponible. Por lo tanto, la dirección IP de un pod es un detalle de implementación en el que no debes confiar. Kubernetes proporciona direcciones IP estables con servicios.

Servicios

En Kubernetes, puedes asignar pares clave-valor arbitrarios, denominados etiquetas, a cualquier recurso de Kubernetes. Kubernetes usa etiquetas para agrupar varios pods relacionados en una unidad lógica denominada un "servicio". Un servicio tiene una dirección IP y puertos estables, y proporciona un balanceo de cargas entre el conjunto de pods cuyas etiquetas coinciden con todas las etiquetas que defines en el selector de etiquetas cuando creas el servicio.

En el siguiente diagrama, se muestran dos servicios independientes, cada uno de los cuales se compone de varios pods. Cada uno de los pods en el diagrama tiene la etiqueta app=demo, pero el resto de las etiquetas difieren. El servicio “frontend” hace coincidir todos los pods con app=demo y component=frontend, mientras que el servicio “usuarios” hace coincidir todos los pods con app=demo y component=users. El pod de cliente no coincide exactamente con ninguno de los dos selectores de servicio, por lo que no forma parte de ninguno de los servicios. Sin embargo, el pod de cliente puede comunicarse con cualquiera de los servicios porque se ejecuta en el mismo clúster.

Diagrama de dos servicios independientes, como se describe en el párrafo anterior

Kubernetes asigna una dirección IP estable y confiable a cada servicio recientemente creado (el ClusterIP) del grupo de direcciones IP disponibles del servicio del clúster. Kubernetes también asigna un nombre de host al ClusterIP mediante la adición de una entrada de DNS. El ClusterIP y el nombre de host son únicos dentro del clúster y no cambian a lo largo del ciclo de vida del servicio. Kubernetes solo libera el ClusterIP y el nombre de host si el servicio se borra de la configuración del clúster. Puedes acceder a un pod en buen estado que esté ejecutando tu aplicación con ClusterIP o el nombre de host del servicio.

A primera vista, un servicio podría parecer un punto único de falla para tus aplicaciones. Sin embargo, Kubernetes distribuye tráfico de la manera más equitativa posible en todo el conjunto de pods que se ejecuta en muchos nodos. Por esto, un clúster puede resistir una interrupción que afecta a uno o más nodos (pero no a todos).

Kubernetes administra la conectividad entre pods y servicios con el componente kube-proxy, que se ejecuta en cada nodo kube-proxy, que no es un proxy en línea, sino que un controlador de balanceo de cargas basado en salida, mira el servidor de API de Kubernetes y asigna de manera continua el ClusterIP a pods en buen estado. Para esto, agrega y quita reglas NAT de destino (DNAT) al subsistema iptables del nodo. Cuando un contenedor que se ejecuta en un pod envía tráfico a un ClusterIP de servicio, el nodo selecciona un pod de manera aleatoria y direcciona el tráfico a ese pod.

Cuando configuras un servicio, puedes optar por volver a asignar el puerto de escucha mediante la definición de valores para port y targetPort.

  • El port es por donde los clientes llegan a la aplicación.
  • El targetPort es el puerto en el que la aplicación realmente está escuchando el tráfico dentro del pod.

Para administrar la reasignación de este puerto, kube-proxy agrega y quita reglas de iptables en el nodo.

En este diagrama se muestra el flujo de tráfico desde un pod de cliente a un pod de servidor en un nodo diferente. El cliente se conecta al servicio en 172.16.12.100:80. El servidor de API de Kubernetes mantiene una lista de pods que ejecutan la aplicación. El proceso kube-proxy en cada nodo usa esta lista para crear una regla iptables a fin de direccionar el tráfico a un pod adecuado (como 10.255.255.202:8080). El pod de cliente no necesita conocer la topología del clúster ni ningún detalle sobre pods individuales o contenedores dentro de ellos.

Diagrama que muestra a un cliente que se conecta a un servicio y se direcciona a un pod, como se describe en el párrafo anterior

Herramientas de redes fuera del clúster

En esta sección se explica cómo el tráfico desde fuera del clúster llega a las aplicaciones que se ejecutan dentro de un clúster de Kubernetes. Esta información es importante a la hora de diseñar las cargas de trabajo y las aplicaciones de tu clúster.

Ya leíste sobre cómo Kubernetes utiliza los servicios para proporcionar direcciones IP estables a aplicaciones que se ejecutan dentro de pods. De manera predeterminada, los pods no exponen una dirección IP externa, porque kube-proxy administra todo el tráfico en cada nodo. Los pods y sus contenedores pueden comunicarse libremente, pero las conexiones fuera del clúster no pueden acceder al servicio. Por ejemplo, en la ilustración anterior, los clientes fuera del clúster no pueden acceder al servicio frontend a través de su ClusterIP.

GKE proporciona tres tipos diferentes de balanceadores de cargas para controlar el acceso y distribuir el tráfico entrante en tu clúster de la manera más equitativa posible. Puedes configurar un servicio para usar varios tipos de balanceadores de cargas simultáneamente.

  • Los balanceadores de cargas externos administran el tráfico que viene desde fuera del clúster y fuera de tu red de nube privada virtual (VPC) de GCP. Utilizan las reglas de reenvío relacionadas con la red de GCP para direccionar el tráfico a un nodo de Kubernetes.
  • Los balanceadores de cargas internos administran el tráfico que viene de la misma red de VPC. Al igual que los balanceadores de cargas externos, usan reglas de reenvío relacionadas con la red de GCP para direccionar el tráfico a un nodo de Kubernetes.
  • Los balanceadores de cargas de HTTP(S) son balanceadores de cargas externos especializados que se utilizan para el tráfico de HTTP(S). Usan un recurso Ingress en lugar de una regla de reenvío para direccionar el tráfico a un nodo de Kubernetes.

Cuando el tráfico llega a un nodo de Kubernetes, se maneja de la misma manera, independientemente del tipo de balanceador de cargas. El balanceador de cargas no tiene conocimiento sobre qué nodos del clúster están ejecutando pods para su servicio. En cambio, equilibra el tráfico en todos los nodos del clúster, incluso en los que no ejecutan el pod relevante. En un clúster regional, la carga se distribuye en todos los nodos, en todas las zonas para la región del clúster. Cuando el tráfico se direcciona a un nodo, el nodo direcciona el tráfico a un pod, que puede estar ejecutándose en el mismo nodo o en uno diferente. El nodo desvía el tráfico a un pod elegido de manera aleatoria mediante el uso de las reglas de iptables que kube-proxy administra en el nodo.

En el diagrama siguiente, el balanceador de cargas de la red dirige el tráfico al nodo central, y el tráfico se redirecciona a un pod en el primer nodo.

Diagrama que muestra el tráfico que se direcciona desde un nodo a un pod en otro nodo, como se describe en el párrafo anterior

Cuando un balanceador de cargas envía tráfico a un nodo, el tráfico podría desviarse hacia un pod en un nodo diferente. Esto requiere saltos de red adicionales. Si deseas evitar los saltos adicionales, puedes especificar que el tráfico debe ir a un pod que se encuentra en el mismo nodo que inicialmente recibe el tráfico.

Para especificar que el tráfico debe ir a un pod en el mismo nodo, establece externalTrafficPolicy en Local en tu manifiesto de servicio:

apiVersion: v1
kind: Service
metadata:
  name: my-lb-service
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  selector:
    app: demo
    component: users
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

Cuando estableces externalTrafficPolicy en Local, el balanceador de cargas envía el tráfico solo a los nodos que tienen un pod en buen estado que pertenece al servicio. El balanceador de cargas utiliza una verificación de estado para determinar qué nodos tienen los pods adecuados.

Balanceador de cargas externo

Si tu servicio necesita ser accesible desde fuera del clúster y fuera de tu red de VPC, puedes configurar tu servicio como un LoadBalancer. Para ello, establece el campo type del servicio en LoadBalancer en el momento de definir el servicio. Luego, GKE aprovisiona un balanceador de cargas de red frente al servicio. El balanceador de cargas de red conoce todos los nodos de tu clúster y configura las reglas de firewall de tu red de VPC para permitir conexiones al servicio desde fuera de la red VPC, mediante el uso de la dirección IP externa del servicio. Puedes asignar una dirección IP externa estática al servicio. Para obtener más información, visita Cómo configurar nombres de dominio con direcciones IP estáticas.

Detalles técnicos

Cuando se utiliza el balanceador de cargas externo, el tráfico que llega inicialmente se direcciona a un nodo mediante una regla de reenvío relacionada con la red de GCP. Una vez que el tráfico llega al nodo, el nodo utiliza su tabla de NAT iptables para elegir un pod. kube-proxy administra las reglas iptables en el nodo.

Balanceador de cargas interno

Para el tráfico que necesita llegar a tu clúster desde dentro de la misma red de VPC, puedes configurar tu servicio, de manera que aprovisione un balanceador de cargas interno. El balanceador de cargas interno elige una dirección IP de la subred de VPC de tu clúster en lugar de una dirección IP externa. Las aplicaciones o los servicios dentro de la red de VPC pueden usar esta dirección IP para comunicarse con servicios dentro del clúster.

Detalles técnicos

GCP proporciona la funcionalidad de balanceo de cargas interno. Cuando el tráfico llega a un nodo determinado, ese nodo usa su tabla de NAT iptables para elegir un pod, incluso si el pod está en un nodo diferente. kube-proxy administra las reglas de iptables en el nodo.

Para obtener más información sobre los balanceadores de cargas internos, visita la documentación del balanceador de cargas interno.

Balanceador de cargas de HTTP(S)

Muchas aplicaciones, como las API de servicios web RESTful, se comunican mediante HTTP(S). Puedes permitir que clientes externos a tu red de VPC accedan a este tipo de aplicación con un recurso Ingress de Kubernetes. Un recurso Ingress te permite asignar nombres de host y rutas de URL a servicios dentro del clúster. Cuando usas un balanceador de cargas de HTTP(S), debes configurar el servicio a fin de usar un NodePort, así como un ClusterIP. Cuando el tráfico accede al servicio en una IP de nodo en el NodePort, GKE direcciona el tráfico a un pod en buen estado para el servicio. Puedes especificar un NodePort o permitir que GKE asigne de manera aleatoria un puerto sin usar.

Cuando creas el recurso Ingress, GKE aprovisiona un balanceador de cargas de HTTP(S) en el proyecto de GCP. El balanceador de cargas envía una solicitud a la dirección IP de un nodo en el NodePort. Una vez que la solicitud llega al nodo, el nodo utiliza su tabla de NAT iptables para elegir un pod. kube-proxy administra las reglas iptables en el nodo.

Esta definición de Ingress direcciona tráfico para demo.example.com a un servicio llamado frontend en el puerto 80, y demo-backend.example.com a un servicio llamado users en el puerto 8080.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: demo
spec:
  rules:
  - host: demo.example.com
    http:
      paths:
      - backend:
          serviceName: frontend
          servicePort: 80
  - host: demo-backend.example.com
    http:
      paths:
      - backend:
          serviceName: users
          servicePort: 8080

Para obtener más información, visita Ingress en Google Cloud Platform.

Detalles técnicos

Cuando creas un objeto Ingress, el controlador de Ingress de GKE configura un balanceador de cargas de HTTP(S) de GCP de acuerdo con las reglas del manifiesto de Ingress y los manifiestos de servicio asociados. El cliente envía una solicitud al balanceador de cargas de HTTP(S). El balanceador de cargas es un proxy real; elige un nodo y desvía la solicitud a la combinación NodeIP:NodePort de ese nodo. Este nodo usa su tabla de NAT iptables para elegir un pod. kube-proxy administra las reglas de iptables en el nodo.

Cómo limitar la conectividad a pods y servicios

De manera predeterminada, todos los pods que se ejecutan dentro del mismo clúster pueden comunicarse libremente. Sin embargo, puedes limitar la conectividad dentro de un clúster de diferentes maneras, según lo que necesites.

Cómo limitar el acceso entre pods

Puedes limitar el acceso entre pods con una política de red. Las definiciones de políticas de red te permiten restringir la entrada y la salida de pods según una combinación arbitraria de etiquetas, rangos de IP y números de puerto. De manera predeterminada, no hay una política de red, por lo que se permite todo el tráfico entre pods en el clúster. Tan pronto creas la primera política de red en un espacio de nombres, se deniega todo el resto del tráfico.

Visita Políticas de red para obtener más detalles sobre cómo especificar la política.

Después de crear una política de red, debes habilitarla explícitamente para el clúster. Si deseas obtener más información, visita Cómo configurar políticas de red para aplicaciones.

Cómo limitar el acceso a un balanceador de cargas externo

Si tu servicio utiliza un balanceador de cargas externo, el tráfico desde cualquier dirección IP externa puede acceder a tu servicio de manera predeterminada. Para restringir qué rangos de direcciones IP pueden acceder a los extremos dentro de tu clúster, debes configurar la opción loadBalancerSourceRanges cuando configuras el servicio. Puedes especificar varios rangos y actualizar la configuración de un servicio en ejecución en cualquier momento. La instancia de kube-proxy que se ejecuta en cada nodo configura las reglas de iptables de ese nodo para denegar todo el tráfico que no coincide con el loadBalancerSourceRanges especificado. No se crea ninguna regla de firewall de VPC.

Cómo limitar el acceso a un balanceador de cargas de HTTP(S)

Si tu servicio utiliza el balanceador de cargas de HTTP(S), puedes usar una política de seguridad de Cloud Armor para limitar las direcciones IP externas que pueden acceder a tu servicio y las respuestas que se mostrarán cuando se deniega el acceso debido a la política de seguridad. Puedes configurar el Stackdriver Logging para registrar información sobre estas interacciones.

Si una política de seguridad de Cloud Armor no es lo suficientemente precisa, puedes habilitar el Cloud Identity-Aware Proxy en tus extremos a fin de implementar autenticación y autorización basadas en el usuario para tu aplicación. Si deseas obtener más información, visita el instructivo detallado para configurar Cloud IAP.

Qué sigue

¿Te ha resultado útil esta página? Enviar comentarios:

Enviar comentarios sobre...