外部访问 K8S,知道这 3 种模式就够了
技术
作者:Sandeep Dinesh
译者:夏天
2018-03-26 06:20

最近,很多人问我 NodePorts,LoadBalancer 和 Ingress 之间的区别是什么?它们是将外部流量引入集群的不同方式,而且它们的运行形式各不相同。接下来,请你跟我一起,来看看他们是如何工作的,以及它们各自的适用情况。

注意:本文分析适用于 Google Kubernetes Engine。如果你正使用 minikube 运行或使用其他工具,在其他云上或内部部署软件上运行,那么请注意它们的使用方法会略有不同。我对这些技术性细节并没有特别深入的了解。如果你对此有兴趣,官方文档可以提供很好的参考。https://kubernetes.io/docs/concepts/services-networking/service/

ClusterIP

ClusterIP 是默认的 Kubernetes service 类型。有了它,集群内部的应用程序可以相互访问,但集群外部的应用程序不行。

ClusterIP service 的 YAML 如下图所示:

如果你都不能通过公网访问 ClusterIP service,那我为什么要提它呢?因为你可以使用 Kubernetes proxy 来访问它!

启动 Kubernetes proxy:

现在,您就可以使用下面这个scheme 通过 Kubernetes API 访问 service 了:http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
所以,你可以使用下面这个地址,访问我们上面定义的 service:
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
这种类型的 service 什么时候适用?我列出以下几种可以让你使用 Kubernetes proxy 来访问这个 service 的情况:

  • 调试你的 service,或直接从笔记本电脑连接到 service;
  • 允许内部流量访问,显示内部 dashboards 等。

由于此方法要求你将 kubectl 作为认证用户运行,因此你不能使用这个方法将你的 service 暴露在公网上或将其用于生产环境下。

NodePort 

NodePort 类型的 service 是让外部流量可以访问集群内部服务最基本的方式。NodePort, 顾名思义可以在所有 Node(VM)上打开一个特定的 port,任何发送到此 port 的流量都将转发到 service 上。

                     从技术上看,这也许不是最准确的图表,但它表明了 NodePort 的工作方式

NodePort 类型的 service 的 YAML 如下所示:

NodePort 类型的 service 与普通的 “ClusterIP” 类型的 service 有两点区别:

  1. 它的类型是 “NodePort”;
  2. 它有一个被称为 nodePort 的附加 port,可以在 node 上指定打开哪个 port 。如果你不指定一个 port,NodePort 类型的 service 就会随机选择一个。大多数时候你应该让 Kubernetes 来选择 port; 正如 thockin 所说:“有许多提示可以告诉你应该使用哪些 port。”

thockin twitter 地址:https://twitter.com/thockin

这种类型的 service 什么时候适用?这种方法有一些缺点:

  • 每个端口只能绑定一个 service;
  • 可使用端口号只能是 30000 到 32767;
  • 如果你的 Node/虚拟机 IP 地址发生更改,你必须自己处理。

由于上述原因,我不建议在生产中使用这种方法来直接暴露你的服务。如果你运行的服务不用保持始终可用,或者您非常关注成本,那么这个方法就适用于你。这样的应用程序在我看来只适用于一个演示应用程序或其他临时的东西。

LoadBalancer

LoadBalancer (负载均衡器)类型的 service 是在公网上暴露服务的标准方式。在 GKE 上,这将启动一个网络 LoadBalancer,该网络 LoadBalancer 将为你提供一个 IP 地址,用来将所有流量转发到你的 service 上。

这种类型的 service 什么时候适用?如果你想直接暴露一个 service,这是一种默认的方法。你指定的 port 上的所有流量都将被转发到这个 service 上,没有过滤,没有路由等。这意味着你几乎可以发送如 HTTP,TCP,UDP,Websockets,gRPC 等任何类型的流量。

最大的缺点就是:你使用 LoadBalancer 暴露的每个 service 都将获得自己的 IP 地址,而你必须为每个暴露的 service 配置一个 LoadBalancer,这成本就非常高了。

Ingress

与以上所有例子不同,Ingress 实际上不是 service 的一个类型。相反,它位于多个 service 之前,充当集群中的“智能路由器”或入口点。您可以使用 Ingress 做很多不同的事情。现在市面上有许多不同类型的 Ingress 控制器,他们具有不同的功能。

默认的 GKE ingress 控制器将为你启动一个 HTTP(S)LoadBalancer。帮助你用来执行基于路径和子域的路由到后端服务。例如,你可以将 foo.yourdomain.com 上的所有内容发送到 foo service 上,将 yourdomain.com/bar/ 路径下所有内容发送到 bar service 上。

GKE 上 Ingress 对象的 YAML 如下所示(带有 L7 HTTP LoadBalancer):

适用情况Ingress 可能是暴露 service 最强大的方式,但也可能是最复杂的。其实,Ingress 控制器有很多类型,像来自 Google Cloud 的 LoadBalancer,Nginx,Contour,Istio 等。还有用于 Ingress 控制器的插件,如 cert-manager,它可以为你的 service 自动提供 SSL 证书。

如果你希望在相同的 IP 地址下暴露多个 service,并且这些 service 都使用相同的 L7 协议(通常是 HTTP)。毫无疑问,Ingress 是最有用的。如果你使用本地 GCP 集成,那你只需使用一台负载均衡器。由于 Ingress 是“智能的”,您可以获得许多“开箱即用”的功能,如 SSL,Auth,路由等。

原文链接:https://medium.com/google-cloud/kubernetes-nodeport-vs-loadbalancer-vs-ingress-when-should-i-use-what-922f010849e0Twitter: https://twitter.com/search?q=Sandeep%20Dinesh&src=typd&lang=zh-cn

634 comCount 0