Ingress x Balanceador de Carga

212

Estou bastante confuso sobre os papéis do Ingress e do Load Balancer no Kubernetes.

Tanto quanto eu entendo, o Ingress é usado para mapear o tráfego de entrada da Internet para os serviços em execução no cluster.

A função do balanceador de carga é encaminhar o tráfego para um host. Nesse sentido, como a entrada difere do balanceador de carga? Além disso, qual é o conceito de balanceador de carga dentro dos kubernetes em comparação ao Amazon ELB e ALB?

arunkjn
fonte

Respostas:

183

Balanceador de carga: Um serviço kubernetes LoadBalancer é um serviço que aponta para balanceadores de carga externos que NÃO estão no cluster kubernetes, mas existem em outros lugares. Eles podem trabalhar com seus pods, assumindo que eles possam ser roteados externamente. O Google e a AWS fornecem esse recurso nativamente. Em termos de Amazon, esse mapeamento diretamente com ELB e kubernetes ao executar na AWS pode provisionar e configurar automaticamente uma instância ELB para cada serviço LoadBalancer implantado.

Ingresso: Uma entrada é realmente apenas um conjunto de regras a serem passadas para um controlador que as está ouvindo. Você pode implantar várias regras de entrada, mas nada acontecerá a menos que você tenha um controlador que possa processá-las. Um serviço LoadBalancer pode escutar regras de entrada, se estiver configurado para fazer isso.

Você também pode criar um serviço NodePort , que possui um IP roteável externamente fora do cluster, mas aponta para um pod que existe dentro do cluster. Este poderia ser um controlador de ingresso.

Um Controlador de ingresso é simplesmente um pod configurado para interpretar regras de entrada. Um dos controladores de ingresso mais populares suportados pelo kubernetes é o nginx. Em termos de Amazon, o ALB pode ser usado como um controlador de entrada.

Por exemplo, este controlador nginx é capaz de ingerir regras de entrada definidas e convertê-las em um arquivo nginx.conf que ele carrega e inicia em seu pod.

Digamos, por exemplo, que você definiu uma entrada da seguinte maneira:

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

Se você inspecionar seu pod do controlador nginx, verá a seguinte regra definida em /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;

    }

O Nginx acabou de criar uma regra para rotear http://kubernetes.foo.bar/apppara apontar para o serviço appsvcno seu cluster.

Aqui está um exemplo de como implementar um cluster kubernetes com um controlador de entrada nginx. Espero que isto ajude!

Lindsay Landry
fonte
1
Eu entendo a diferença entre o controlador de ingresso e ingresso e seus respectivos papéis. De fato, o balanceador de carga também é responsável por direcionar o tráfego para meus pods do kubernetes por meio de um conjunto de regras definidas. Você poderia esclarecer como o controlador de ingresso difere do balanceador de carga nesse aspecto? Talvez um exemplo em que o ingresso e o balanceador de carga seja usado deva ajudar.
Arunjn
Um controlador de entrada não é um tipo oficial de kubernetes, é apenas uma implantação de uma imagem LB (nginx é apenas um exemplo) que pode interpretar regras de entrada. Eu acredito que a maioria das pessoas assume que um controlador de ingresso também é um LB interno que vive dentro do cluster. Na verdade, não tentei criar um balanceador de carga externo que interprete as regras de entrada. Imagino que é possível, mas eu poderia estar completamente errado :)
Lindsay Landry
6
No meu aplicativo atual, expus a implantação do nginx como serviço LoadBalancer no GKE e fiz proxy reverso do nginx para todos os outros serviços em execução no cluster. Devo usar ingresso em vez da abordagem acima?
Rigal
oi @rigal no seu proxy nginx como são as regras do proxy? Eles são resolvidos pelo kube-dns?
Arunkjn 23/11
@arunkjn yes. As regras são assim: location / api / url / {proxy_pass service-name: 80 / api / url ; }
rigal
59

Encontrei este artigo muito interessante que explica as diferenças entre NodePort, LoadBalancer e Ingress.

A partir do conteúdo presente no artigo:

Balanceador de carga:

Um serviço LoadBalancer é a maneira padrão de expor um serviço à Internet. No GKE, isso ativará um Balanceador de Carga de Rede que fornecerá um único endereço IP que encaminhará todo o tráfego para o seu serviço.

Se você deseja expor diretamente um serviço, este é o método padrão. Todo o tráfego na porta que você especificar será encaminhado para o serviço. Não há filtragem, roteamento etc. Isso significa que você pode enviar quase todo tipo de tráfego para ele, como HTTP, TCP, UDP, Websockets, gRPC ou qualquer outra coisa.

A grande desvantagem é que cada serviço que você expõe com um LoadBalancer terá seu próprio endereço IP e você precisará pagar por um LoadBalancer por serviço exposto, o que pode ficar caro!

Entrada:

O Ingress não é realmente um tipo de serviço. Em vez disso, fica na frente de vários serviços e atua como um "roteador inteligente" ou ponto de entrada no seu cluster.

Você pode fazer muitas coisas diferentes com um Ingress, e existem muitos tipos de controladores do Ingress que possuem recursos diferentes.

O controlador de entrada GKE padrão gerará um balanceador de carga HTTP (S) para você. Isso permitirá que você faça o roteamento com base no caminho e no subdomínio para serviços de back-end. Por exemplo, você pode enviar tudo em foo.seudominio.com para o serviço foo e tudo sob o caminho seudominio.com/bar/ para o serviço de barras.

O Ingress é provavelmente a maneira mais poderosa de expor seus serviços, mas também pode ser a mais complicada. Existem muitos tipos de controladores do Ingress, do Google Cloud Load Balancer, Nginx, Contour, Istio e muito mais. Também existem plugins para controladores do Ingress, como o gerenciador de certificação, que podem provisionar automaticamente certificados SSL para seus serviços.

O ingresso é o mais útil se você deseja expor vários serviços no mesmo endereço IP, e todos esses serviços usam o mesmo protocolo L7 (normalmente HTTP). Você paga apenas por um balanceador de carga se estiver usando a integração nativa do GCP e, como o Ingress é "inteligente", você pode obter muitos recursos prontos para uso (como SSL, Auth, Routing etc.)

Ankit Agrawal
fonte
2
Certifique-se de não infringir os direitos autorais de ninguém ao citar vários parágrafos literalmente. Eu não sou especialista nisso, este caso pode ser bom, mas é definitivamente algo para estar ciente.
Outronode 11/0518
14

TL: DR

  1. O Ingress fica entre a rede pública (Internet) e os serviços Kubernetes que expõem publicamente a implementação da nossa API.
  2. O Ingress é capaz de fornecer balanceamento de carga, terminação SSL e hospedagem virtual baseada em nome.
  3. Os recursos do Ingress permitem expor com segurança várias APIs ou aplicativos a partir de um único nome de domínio.

Vamos começar com um caso de uso prático: você tem vários Apis suportados por pacotes de implementação de serviços (ASIP para clariy e brevity) para implantar sob um único nome de domínio. Como você é um desenvolvedor de ponta, implementou uma arquitetura de microsserviços que requer implantações separadas para cada ASIP para que elas possam ser atualizadas ou dimensionadas individualmente. Obviamente, esses ASIPs são encapsulados em contêiner de docker individual e disponíveis para Kubernetes (K8s) no repositório de contêineres.

Digamos agora que você deseja implantar isso nos GKE K8s do Google. Para implementar a disponibilidade sustentada, cada instância ASIP (réplica) é implantada em diferentes nós (VM), nos quais cada VM possui seu próprio endereço IP interno na nuvem. Cada implantação ASIP é configurada em um arquivo apropriadamente "deployment.yaml", no qual você especifica declarativamente, entre outras coisas, o número de réplicas dos AS8 K8s fornecidos.

A próxima etapa é expor a API ao mundo externo e canalizar solicitações para uma das instâncias ASIP implantadas. Como temos muitas réplicas do mesmo ASIP em execução em nós diferentes, precisamos de algo que distribua a solicitação entre essas réplicas. Para resolver isso, podemos criar e aplicar um arquivo "service.yaml" que configurará um serviço K8s (KServ) que será exposto externamente e acessível por meio de um endereço IP. Este KServ se encarregará da distribuição de solicitações da API entre seus ASIPs configurados. Observe que um KServ será reconfigurado automaticamente pelo mestre do K8s quando um nó do ASIP falhar e for reiniciado. Nesse caso, o endereço IP interno nunca é reutilizado e o KServ deve ser avisado sobre o novo local de implantação do ASIP.

Mas temos outros pacotes de serviços da API que devem ser expostos no mesmo nome de domínio. Girar um novo KServ criará um novo endereço IP externo e não poderemos expô-lo no mesmo nome de domínio. Bem, é aqui que o Ingress entra.

O Ingress fica entre a Internet e todos os KServices aos quais expomos para o mundo exterior. O Ingress é capaz de fornecer balanceamento de carga, terminação SSL e hospedagem virtual baseada em nome. A última capacidade é capaz de rotear uma solicitação recebida para o serviço certo, analisando sua URL. Obviamente, o Ingress deve ser configurado e aplicado com um arquivo ... "ingress.yaml" que especificará as reescritas e as rotas necessárias para enviar uma solicitação ao KServ correto.

Internet -> Ingresso -> Serviços K8s -> Réplicas

Portanto, com a configuração correta de entrada, KServices e ASIPs, podemos expor com segurança muitas APIs usando o mesmo nome de domínio.

softjake
fonte
9
internet -> loadbalancer -> controlador de entrada -> regras de entrada -> k8s-services -> réplicas
c4f4t0r
@ c4f4t0r De Kubernetes documentação kubernetes.io/docs/concepts/services-networking/ingress/...
softjake
@sofjake, o que gostaria de dizer?
C4f4t0r 19/03/19
9

Existem quatro maneiras de permitir que os pods em seu cluster recebam tráfego externo:
1.) Pod usando HostNetworking: true e (Permite que 1 pod por nó escute diretamente as portas no nó host. Às vezes, o Minikube, o bare metal e o rasberry pi essa rota que pode permitir que o nó do host escute na porta 80/443 não permite usar um balanceador de carga ou configurações avançadas do balanceador de carga na nuvem, também ignora os Serviços Kubernetes, que podem ser úteis para evitar o SNAT / obter efeito semelhante do externalTrafficPolicy: Local em cenários onde não é suportado, como na AWS.)
2.) Serviço NodePort
3.) Serviço LoadBalancer (que se baseia no serviço NodePort)
4.) Controlador de ingresso + objetos de ingresso (que se baseia no exposto acima)

Digamos que você tenha 10 sites hospedados no seu cluster e queira expô-los todos ao tráfego externo.
* Se você usar o Serviço LoadBalancer do tipo, gerará 10 balanceadores de carga em nuvem de HA (cada um custa dinheiro)
* Se você usar o Controlador de entrada do tipo, gerará 1 balanceador de carga em nuvem HA (economizando dinheiro) e apontará para um Ingress Controlador em execução no seu cluster.

Um controlador de ingresso é:

  • Um serviço do tipo Load Balancer apoiado por uma implantação de pods em execução no seu cluster.
  • Cada pod faz duas coisas:
    1. Atua como um balanceador de carga da camada 7 em execução no seu cluster. (Vem em muitos sabores Nginx é popular)
    2. Configura-se dinamicamente com base nos Objetos do Ingress em seu cluster
      (os Objetos do Ingress podem ser considerados como fragmentos de configuração declarativa de um Balanceador de Carga da Camada 7).

O controlador L7 LB / Ingress dentro do seu cluster Balanceamento de carga / tráfego de proxies reversos para os Serviços de IP do cluster no seu cluster, também pode encerrar o HTTPS se você tiver um Kubernetes Secret do tipo TLS cert e um objeto do Ingress que o referencie.)

insira a descrição da imagem aqui

neokyle
fonte
1
Se alguém está buscando
neokyle
qual seria a diferença entre o metallb e o controlador de entrada?
ImranRazaKhan 8/03
1
A idéia do controlador de entrada é um pod L7 LB em execução na sua rede interna de cluster. E geralmente é exposto à LAN através de um LB existente na rede LAN. O MetalLB é um software que você pode instalar nos nós do Kube que podem dar a ilusão de ser uma LAN enfrentando um endereço IP virtual / VIP acessível na LAN, para desempenhar o papel do LB existente na LAN.
neokyle 9/03
6

Ingress: Objeto do Ingress + Controlador do Ingress

Objeto de entrada:

Assim como um Objeto de Serviço, exceto que ele não faz nada por si só. Um Objeto do Ingress apenas descreve uma maneira de rotear o tráfego da Camada 7 para o cluster, especificando coisas como o caminho da solicitação, o domínio da solicitação e o serviço kubernetes de destino, enquanto um objeto de serviço realmente cria serviços

Controlador de ingresso:

Um serviço 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 exemplo, o Nginx Ingress Controller, poderia usar um serviço para escutar nas portas 80 e 443 e, em seguida, ler novos objetos do Ingress e analisá-los em novas seções do servidor {} que ele coloca dinamicamente no nginx.conf

LoadBalancer: provedor de balanceador de carga externo + tipo de serviço

Provedor de balanceador de carga externo:

Os provedores de balanceador de carga externo geralmente são configurados em nuvens como AWS e GKE e fornecem uma maneira de atribuir IPs externos por meio da criação de balanceadores de carga externos. Essa funcionalidade pode ser usada designando um serviço como o tipo "LoadBalancer".

Tipo de serviço:

Quando o tipo de serviço é definido como LoadBalancer, o Kubernetes tenta criar e programar um balanceador de carga externo com entradas para os pods do Kubernetes, atribuindo-lhes IPs externos.

O controlador de serviço Kubernetes automatiza a criação do balanceador de carga externo, verificações de integridade (se necessário), regras de firewall (se necessário) e recupera o IP externo do LoadBalancer recém-criado ou configurado que foi alocado pelo provedor de nuvem e o preenche no diretório objeto de serviço.

Relacionamentos:

Os serviços do controlador de ingresso geralmente são provisionados como tipo LoadBalancer, para que solicitações http e https possam ser enviadas por proxy / roteadas para serviços internos específicos por meio de um ip externo.

No entanto, um LoadBalancer não é estritamente necessário para isso. Como, através do uso de hostNetwork ou hostPort, é possível vincular tecnicamente uma porta no host a um serviço (permitindo visitá-la através dos hosts ip: port externos). Embora oficialmente isso não seja recomendado, pois utiliza portas no nó real.

Referências:

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
fonte
3

Em palavras simples, o balanceador de carga distribui as solicitações entre vários serviços de back-end (do mesmo tipo), enquanto a entrada é mais como um gateway de API (proxy reverso) que roteia a solicitação para um serviço de back-end específico com base, por exemplo, na URL.

pr-pal
fonte
Para seguir sua resposta, no caso em que o controlador de equilíbrio de carga e o ingresso estão separados, em todos os casos, o controlador de ingresso fica atrás do balanceador de carga.
AQuirky