Ingress vs Load Balancer

213

Estoy bastante confundido acerca de los roles de Ingress y Load Balancer en Kubernetes.

Según tengo entendido, Ingress se usa para asignar el tráfico entrante de Internet a los servicios que se ejecutan en el clúster.

La función del equilibrador de carga es reenviar el tráfico a un host. En ese sentido, ¿cómo difiere el ingreso del balanceador de carga? Además, ¿cuál es el concepto de equilibrador de carga dentro de kubernetes en comparación con Amazon ELB y ALB?

arunkjn
fuente

Respuestas:

183

Balanceador de carga: un servicio de Kubernetes LoadBalancer es un servicio que apunta a equilibradores de carga externos que NO están en su clúster de kubernetes, pero existen en otros lugares. Pueden trabajar con sus pods, suponiendo que sus pods sean enrutables externamente. Google y AWS proporcionan esta capacidad de forma nativa. En términos de Amazon, este mapa directamente con ELB y kubernetes cuando se ejecuta en AWS puede aprovisionar y configurar automáticamente una instancia de ELB para cada servicio LoadBalancer implementado.

Ingreso: Una entrada es realmente solo un conjunto de reglas para pasar a un controlador que las está escuchando. Puede implementar un montón de reglas de ingreso, pero no pasará nada a menos que tenga un controlador que pueda procesarlas. Un servicio LoadBalancer podría escuchar las reglas de ingreso, si está configurado para hacerlo.

También puede crear un servicio NodePort , que tiene una IP enrutable externamente fuera del clúster, pero apunta a un pod que existe dentro de su clúster. Esto podría ser un controlador de entrada.

Un controlador de ingreso es simplemente un pod que está configurado para interpretar las reglas de ingreso. Uno de los controladores de ingreso más populares soportados por kubernetes es nginx. En términos de Amazon, ALB puede usarse como un controlador de ingreso.

Por ejemplo, este controlador nginx puede ingerir las reglas de ingreso que ha definido y traducirlas a un archivo nginx.conf que carga y comienza en su pod.

Digamos, por ejemplo, que definió un ingreso de la siguiente manera:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
   ingress.kubernetes.io/rewrite-target: /
 name: web-ingress
spec:
  rules:
  - host: kubernetes.foo.bar
    http:
      paths:
      - backend:
          serviceName: appsvc
          servicePort: 80
        path: /app

Si luego inspecciona su dispositivo controlador nginx, verá la siguiente regla definida en /etc/nginx.conf:

server {
    server_name kubernetes.foo.bar;
    listen 80;
    listen [::]:80;
    set $proxy_upstream_name "-";
    location ~* ^/web2\/?(?<baseuri>.*) {
        set $proxy_upstream_name "apps-web2svc-8080";
        port_in_redirect off;

        client_max_body_size                    "1m";

        proxy_set_header Host                   $best_http_host;

        # Pass the extracted client certificate to the backend

        # Allow websocket connections
        proxy_set_header                        Upgrade           $http_upgrade;
        proxy_set_header                        Connection        $connection_upgrade;

        proxy_set_header X-Real-IP              $the_real_ip;
        proxy_set_header X-Forwarded-For        $the_x_forwarded_for;
        proxy_set_header X-Forwarded-Host       $best_http_host;
        proxy_set_header X-Forwarded-Port       $pass_port;
        proxy_set_header X-Forwarded-Proto      $pass_access_scheme;
        proxy_set_header X-Original-URI         $request_uri;
        proxy_set_header X-Scheme               $pass_access_scheme;

        # mitigate HTTPoxy Vulnerability
        # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
        proxy_set_header Proxy                  "";

        # Custom headers

        proxy_connect_timeout                   5s;
        proxy_send_timeout                      60s;
        proxy_read_timeout                      60s;

        proxy_redirect                          off;
        proxy_buffering                         off;
        proxy_buffer_size                       "4k";
        proxy_buffers                           4 "4k";

        proxy_http_version                      1.1;

        proxy_cookie_domain                     off;
        proxy_cookie_path                       off;

    rewrite /app/(.*) /$1 break;
    rewrite /app / break;
    proxy_pass http://apps-appsvc-8080;

    }

Nginx acaba de crear una regla para enrutar http://kubernetes.foo.bar/apppara apuntar al servicio appsvcen su clúster.

Aquí hay un ejemplo de cómo implementar un clúster de kubernetes con un controlador de ingreso nginx. ¡Espero que esto ayude!

Lindsay Landry
fuente
1
Obtengo la diferencia entre el ingreso y el controlador de ingreso y sus respectivos roles. En efecto, el equilibrador de carga también es responsable de dirigir el tráfico a mis pods kubernetes a través de un conjunto de reglas definidas. ¿Podría por favor arrojar más luz sobre cómo el controlador de ingreso difiere con el balanceador de carga en ese sentido? Quizás un ejemplo en el que se use tanto el ingreso como el balanceador de carga debería ayudar.
arunkjn
Un controlador de ingreso no es un tipo oficial de kubernetes, es solo un despliegue de una imagen LB (nginx es solo un ejemplo) que puede interpretar las reglas de ingreso. Creo que la mayoría de la gente supone que un controlador de ingreso es también un LB interno que vive dentro del clúster. En realidad no he intentado hacer un balanceador de carga externo que interprete las reglas de ingreso. Me imagino que es posible, pero podría estar completamente equivocada :)
Lindsay Landry
66
En mi aplicación actual, he expuesto la implementación de nginx como servicio LoadBalancer en GKE y haciendo proxy inverso de nginx a todos los demás servicios que se ejecutan en el clúster. ¿Debo usar el ingreso en lugar del enfoque anterior?
Rígido
hola @rigal en tu proxy nginx, ¿cómo son las reglas del proxy? ¿Se resuelven por kube-dns?
arunkjn
@arunkjn sí. Las reglas se ven así: location / api / url / {nombre_servicio proxy_pass : 80 / api / url ; }
rígido
59

Encontré este artículo muy interesante que explica las diferencias entre NodePort, LoadBalancer e Ingress.

Del contenido presente en el artículo:

LoadBalancer:

Un servicio LoadBalancer es la forma estándar de exponer un servicio a Internet. En GKE, esto activará un Network Load Balancer que le dará una sola dirección IP que reenviará todo el tráfico a su servicio.

Si desea exponer directamente un servicio, este es el método predeterminado. Todo el tráfico en el puerto que especifique se reenviará al servicio. No hay filtrado, ni enrutamiento, etc. Esto significa que puede enviarle casi cualquier tipo de tráfico, como HTTP, TCP, UDP, Websockets, gRPC o lo que sea.

El gran inconveniente es que cada servicio que exponga con un LoadBalancer tendrá su propia dirección IP, y tendrá que pagar un LoadBalancer por servicio expuesto, ¡lo cual puede ser costoso!

Ingreso:

Ingress en realidad NO es un tipo de servicio. En cambio, se ubica frente a múltiples servicios y actúa como un "enrutador inteligente" o punto de entrada a su clúster.

Puede hacer muchas cosas diferentes con un Ingress, y hay muchos tipos de controladores de Ingress que tienen capacidades diferentes.

El controlador de entrada GKE predeterminado activará un HTTP (S) Load Balancer para usted. Esto le permitirá realizar enrutamientos basados ​​en rutas y subdominios para servicios de back-end. Por ejemplo, puede enviar todo en foo.yourdomain.com al servicio foo, y todo lo que esté debajo de yourdomain.com/bar/ ruta al servicio de barra.

Ingress es probablemente la forma más poderosa de exponer sus servicios, pero también puede ser la más complicada. Hay muchos tipos de controladores de Ingress, desde Google Cloud Load Balancer, Nginx, Contour, Istio y más. También hay complementos para los controladores Ingress, como el cert-manager, que pueden proporcionar automáticamente certificados SSL para sus servicios.

Ingress es el más útil si desea exponer múltiples servicios bajo la misma dirección IP, y todos estos servicios usan el mismo protocolo L7 (generalmente HTTP). Solo paga por un equilibrador de carga si está utilizando la integración nativa de GCP, y dado que Ingress es "inteligente", puede obtener muchas funciones de fábrica (como SSL, Auth, Routing, etc.)

Ankit Agrawal
fuente
2
Asegúrese de no infringir los derechos de autor de nadie al citar textualmente varios párrafos. No soy un experto en esto, este caso podría estar bien, pero definitivamente es algo a tener en cuenta.
Anothernode
14

TL: DR

  1. Ingress se encuentra entre la red pública (Internet) y los servicios de Kubernetes que exponen públicamente la implementación de nuestra API.
  2. Ingress es capaz de proporcionar Equilibrio de carga, terminación SSL y alojamiento virtual basado en nombres.
  3. Las capacidades de ingreso permiten exponer de forma segura múltiples API o aplicaciones de un solo nombre de dominio.

Comencemos con un caso de uso práctico: tiene múltiples Apis respaldados por paquetes de implementación de servicios (ASIP para mayor claridad y brevedad) para implementar bajo un solo nombre de dominio. Como es un desarrollador de vanguardia, implementó una arquitectura de microservicios que requiere implementaciones separadas para cada ASIP para que puedan actualizarse o escalarse individualmente. Por supuesto, estos ASIP están encapsulados en un contenedor acoplable individual y están disponibles para Kubernetes (K8) desde el repositorio del contenedor.

Digamos ahora que desea implementar esto en los GKE K8 de Google. Para implementar una disponibilidad sostenida, cada instancia de ASIP (réplica) se implementa en diferentes nodos (VM) donde cada VM tiene su propia dirección IP interna en la nube. Cada implementación de ASIP se configura en un archivo apropiado llamado "implement.yaml" en el que se especifica, entre otras cosas, la cantidad de réplicas de los AS8 K8 dados que se deben implementar.

El siguiente paso es exponer la API al mundo exterior y canalizar solicitudes a una de las instancias ASIP implementadas. Como tenemos muchas réplicas del mismo ASIP ejecutándose en diferentes nodos, necesitamos algo que distribuya la solicitud entre esas réplicas. Para resolver esto, podemos crear y aplicar un archivo "service.yaml" que configurará un servicio K8s (KServ) que estará expuesto externamente y será accesible a través de una dirección IP. Este KServ se encargará de la distribución de solicitudes de la API entre sus ASIP configurados. Tenga en cuenta que un KServ será reconfigurado automáticamente por el maestro K8s cuando un nodo de ASIP falla y se reinicia. La dirección IP interna nunca se reutiliza en tal caso y se debe informar al KServ de la ubicación de implementación del nuevo ASIP.

Pero tenemos otros paquetes de servicio Api que se expondrán en el mismo nombre de dominio. Girar un nuevo KServ creará una nueva dirección IP externa y no podremos exponerla en el mismo nombre de dominio. Bueno, aquí es donde entra Ingress.

El ingreso se encuentra entre Internet y todos los KServices a los que exponemos en el mundo exterior. Ingress es capaz de proporcionar equilibrio de carga, terminación SSL y alojamiento virtual basado en nombres. La última capacidad es capaz de enrutar una solicitud entrante al servicio correcto mediante el análisis de su URL. Por supuesto, Ingress debe configurarse y aplicarse con un archivo ... "ingress.yaml" que especificará las reescrituras y las rutas necesarias para enviar una solicitud al KServ correcto.

Internet -> Ingress -> Servicios K8s -> Réplicas

Entonces, con la entrada correcta, la configuración de KServices y ASIP, podemos exponer de forma segura muchas API que usan el mismo nombre de dominio.

softjake
fuente
9
internet -> loadbalancer -> controlador de ingreso -> reglas de ingreso -> k8s-services -> Réplicas
c4f4t0r
@sofjake, ¿qué le gustaría decir?
c4f4t0r
9

Hay 4 formas de permitir que los pods en su clúster reciban tráfico externo:
1.) Pod usando HostNetworking: verdadero y (Permite que 1 pod por nodo escuche directamente los puertos en el nodo host. Minikube, metal desnudo y rasberry pi a veces funcionan Esta ruta, que puede permitir que el nodo host escuche en el puerto 80/443, permite no usar un equilibrador de carga o configuraciones avanzadas de equilibrador de carga en la nube, también omite los servicios de Kubernetes que pueden ser útiles para evitar SNAT / lograr un efecto similar de externalTrafficPolicy: Local en escenarios donde no es compatible como en AWS.)
2.) Servicio NodePort
3.) Servicio LoadBalancer (que se basa en el Servicio NodePort)
4.) Controlador de entrada + Objetos de entrada (que se basa en lo anterior)

Supongamos que tiene 10 sitios web alojados en su clúster y desea exponerlos a todos al tráfico externo.
* Si usa el tipo de servicio LoadBalancer, generará 10 equilibradores de carga de la nube de HA (cada uno cuesta dinero)
* Si usa el controlador de tipo de ingreso generará 1 equilibrador de carga de la nube de HA (ahorrará dinero), y apuntará a un ingreso Controlador ejecutándose en su clúster.

Un controlador de ingreso es:

  • Un servicio de tipo Load Balancer respaldado por una implementación de pods que se ejecutan en su clúster.
  • Cada pod hace 2 cosas:
    1. Actúa como un equilibrador de carga de capa 7 que se ejecuta dentro de su clúster. (Viene en muchos sabores Nginx es popular)
    2. Se configura dinámicamente en función de los objetos de Ingress en su clúster
      (los objetos de Ingress pueden considerarse fragmentos de configuración declarativos de un equilibrador de carga de capa 7).

El L7 LB / Ingress Controller dentro de su clúster Balanzas de carga / tráfico de proxy inverso a los Servicios IP del clúster dentro de su Clúster, también puede terminar HTTPS si tiene un Kubernetes Secret de tipo TLS cert y un objeto Ingress que lo hace referencia).

ingrese la descripción de la imagen aquí

Neokyle
fuente
1
Si alguien busca
neokyle
¿Cuál sería la diferencia entre metallb y el controlador de ingreso?
ImranRazaKhan
1
La idea del controlador de ingreso es que es un pod L7 LB que se ejecuta en su red de clúster interna. Y generalmente está expuesto a la LAN a través de un LB que existe en la red LAN. MetalLB es un software que puede instalar en los nodos de Kube que puede dar la ilusión de ser una LAN que enfrenta una dirección IP VIP / virtual a la que se puede acceder en la LAN, para cumplir con el papel de LB que existe en la LAN.
Neokyle
6

Ingress: Ingress Object + Ingress Controller

Objeto de entrada:

Al igual que un objeto de servicio, excepto que no hace nada por sí solo. Un objeto de ingreso solo describe una forma de enrutar el tráfico de la capa 7 a su clúster, especificando cosas como la ruta de solicitud, el dominio de solicitud y el servicio kubernetes de destino, mientras que un objeto de servicio realmente crea servicios

Controlador de entrada:

Un servicio que:

  1. listens on specific ports (usually 80 and 443) for web traffic
  2. Listens for the creation, modification, or deletion of Ingress Objects
  3. Creates internal L7 routing rules based on these Ingress Objects

Por ejemplo, el controlador de ingreso Nginx, podría usar un servicio para escuchar en los puertos 80 y 443 y luego leer nuevos objetos de ingreso y analizarlos en nuevas secciones del servidor {} que coloca dinámicamente en su nginx.conf

LoadBalancer: proveedor de equilibrador de carga externo + tipo de servicio

Proveedor externo de equilibrador de carga:

Los proveedores de equilibradores de carga externos generalmente se configuran en nubes como AWS y GKE y proporcionan una forma de asignar IP externas a través de la creación de equilibradores de carga externos. Esta funcionalidad se puede utilizar designando un servicio como tipo "LoadBalancer".

Tipo de servicio:

Cuando el tipo de servicio se establece en LoadBalancer, Kubernetes intenta crear y luego programar un equilibrador de carga externo con entradas para los pods de Kubernetes, asignándoles así direcciones IP externas.

El controlador de servicio de Kubernetes automatiza la creación del equilibrador de carga externo, las comprobaciones de estado (si es necesario), las reglas de firewall (si es necesario) y recupera la IP externa del LoadBalancer recién creado o configurado que fue asignado por el proveedor de la nube y lo completa en el objeto de servicio

Relaciones:

Los servicios de Ingress Controller a menudo se aprovisionan como el tipo LoadBalancer, de modo que las solicitudes http y https se pueden enviar / enrutar a servicios internos específicos a través de una IP externa.

Sin embargo, un LoadBalancer no es estrictamente necesario para esto. Dado que, mediante el uso de hostNetwork o hostPort, técnicamente puede vincular un puerto en el host a un servicio (lo que le permite visitarlo a través de la IP externa: puerto de los hosts). Aunque oficialmente esto no se recomienda, ya que utiliza puertos en el nodo real.

Referencias

https://kubernetes.io/docs/concepts/configuration/overview/#services

https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/

https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/#external-load-balancer-providers

https://kubernetes.io/docs/concepts/services-networking/ingress/

Yosefrow
fuente
3

En palabras simples, el equilibrador de carga distribuye las solicitudes entre múltiples servicios de back-end (del mismo tipo), mientras que la entrada es más como una puerta de enlace API (proxy inverso) que enruta la solicitud a un servicio de back-end específico basado, por ejemplo, en la URL.

pr-pal
fuente
Para seguir su respuesta, en el caso en que el balance de carga y el controlador de ingreso estén separados, el controlador de ingreso en todos los casos se ubica detrás del balanceador de carga.
AQuirky