为什么我们需要一个负载均衡器来使用入口暴露 kubernetes 服务?

Why do we need a load balancer to expose kubernetes services using ingress?

对于部署在 Google kubernetes 引擎上的示例微服务架构,我需要帮助来验证我的理解:

  1. 我们知道服务应该为 pod 副本集负载平衡流量。
  2. 当我们创建一个 nginx 入口控制器和入口定义以路由到每个服务时,也会自动设置一个负载均衡器。
  3. 在某处读到创建 nginx 入口控制器意味着在后台创建一个 nginx 控制器(部署)和一个负载均衡器类型的服务。我不确定这是不是真的。

It seems loadbalancing is being done by services. URL based routing is being done by ingress controller.

Why do we need a loadbalancer? It is not meant to load balance across multiple instances. It will just forward all the traffic to nginx reverse proxy created and it will route requests based on URL.

如有理解错误请指正

入口控制器(例如 nginx)pods 需要暴露在 kubernetes 集群之外,作为所有进入 kubernetes 集群的南北流量的入口点。一种方法是通过 LoadBalancer。您也可以使用 NodePort,但不建议将其用于生产,或者您可以直接在具有 public ip 的主机上的主机网络上部署入口控制器。拥有负载均衡器还可以在入口控制器 pods.

的多个副本之间对流量进行负载均衡

当您使用入口控制器时,流量来自负载均衡器到入口控制器,然后根据入口资源中定义的规则到达后端 POD IP。这绕过了 kubernetes service.Internally 提供的 kubernetes 服务和负载平衡(通过第 4 层的 kube-proxy),入口控制器从 kubernetes 服务的端点发现所有 POD IP,并直接将流量路由到 pods。

It seems loadbalancing is being done by services. URL based routing is being done by ingress controller.

服务会平衡 pods 之间的流量。但是默认情况下,Google Kubernetes Engine(ClusterIP 类型)中的 kubernetes 之外无法访问它们。您可以创建具有 LoadBalancer 类型的服务,但每个服务都将获得自己的 IP 地址(网络负载均衡器),因此它可能会变得昂贵。此外,如果您的一个应用程序具有不同的服务,那么使用提供单一入口点的 Ingress 对象会更好。当您创建 Ingress 对象时,Ingress 控制器(例如 nginx 控制器)会创建一个 Google Cloud HTTP(S) 负载均衡器。 Ingress 对象又可以与一个或多个服务对象相关联。

然后您可以从入口对象获取分配的负载均衡器 IP:

kubectl get ingress ingress-name --output yaml

因此,您在 pods 中的应用程序可以在 kubernetes 集群之外访问:

LoadBalancerIP/url1 -> 服务 1 -> pods

LoadBalancerIP/url2 -> 服务 2 -> pods

服务类型 LoadBalancerIngress 是从外部访问您的应用程序的方式,尽管它们以不同的方式工作。

Service:

In Kubernetes, a Service is an abstraction which defines a logical set of Pods and a policy by which to access them (sometimes this pattern is called a micro-service). The set of Pods targeted by a Service is usually determined by a selector (see below for why you might want a Service without a selector).

有一些类型的服务,其中 LoadBalancer 类型允许您在外部公开您的应用程序,为您的服务分配外部 IP。对于每个 LoadBalancer 服务,都会为其分配一个新的外部 IP。 负载平衡将由 kube-proxy.

处理

Ingress:

An API object that manages external access to the services in a cluster, typically HTTP. Ingress may provide load balancing, SSL termination and name-based virtual hosting.

当您设置入口(即:nginx-ingress)时,会为 ingress-controller pods 创建一个服务类型 LoadBalancer 并在您的云提供商中创建一个负载均衡器将自动创建并为 nginx-ingress 服务分配 public IP。

此负载 balancer/public ip 将用于您所有服务的传入连接,nginx-ingress 将负责处理传入连接。

例如:

假设您有 10 个 LoadBalancer 类型的服务:这将导致创建 10 个新的 publics ip,您需要为要访问的服务使用对应的 ip。

但是如果您使用入口,则只会创建 1 个 IP,入口将负责根据您在入口配置中定义的 PATH/URL 处理正确服务的传入连接。使用入口,您可以:

  • path 中使用正则表达式来定义要重定向的服务;
  • 使用SSL/TLS
  • 注入自定义 headers;
  • 如果其中一项服务失败,则重定向对默认服务的请求 (default-backend);
  • 根据 IP 创建白名单
  • 等等...

关于 Ingress 中的 Ingress 负载平衡的重要 note

GCE/AWS load balancers do not provide weights for their target pools. This was not an issue with the old LB kube-proxy rules which would correctly balance across all endpoints.

With the new functionality, the external traffic is not equally load balanced across pods, but rather equally balanced at the node level (because GCE/AWS and other external LB implementations do not have the ability for specifying the weight per node, they balance equally across all target nodes, disregarding the number of pods on each node).