最近,有人问我 NodePort,LoadBalancer 和 Ingress 之间的区别是什么。 它们是将外部流量引入群集的不一样方式,而且实现方式不同。 咱们来看看它们是如何工做的,以及何时该用哪一种。node
注意:本文适用于 Google Kubernetes Engine。 若是你在其余公有云、混合云、minikube 等上运行,可能会略有不一样。 例如,您不能在 minikube 上使用 LoadBalancer。 我也没有深刻技术细节。 若是您有兴趣了解更多,官方文档是一个很好的资源!nginx
ClusterIP 服务是默认的 Kubernetes 服务。 它为您提供集群内部其余应用程序能够访问的服务, 外部没法访问。git
ClusterIP 服务的 YAML 相似这样:github
apiVersion: v1 kind: Service metadata: name: my-internal-service selector: app: my-app spec: type: ClusterIP ports: - name: http port: 80 targetPort: 80 protocol: TCP
若是你不能从集群外部上访问一个 ClusterIP 服务,我为何要谈论它? 由于你可使用 Kubernetes Proxy 来访问它!启动 Kubernetes Proxy:后端
$ kubectl proxy --port=8080
如今,你可使用以下的 Kubernetes API 访问服务:api
http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/
因此,若是要访问咱们刚刚定义的服务,可使用下面的地址:网络
http://localhost:8080/api/v1/proxy/namespaces/default/services/my-internal-service:http/
有几种状况可使用 Kubernetes Proxy 来访问您的服务:app
因为此方法要求您用已受权用户运行 kubectl ,所以您不该该使用此方法将您的服务公开到公网上或将其用于生产。负载均衡
NodePort 服务是暴露服务的最原始方式。 顾名思义,NodePort 会在全部节点(VM)上打开一个特定的端口,而且发送到此端口的任何流量都将转发到该服务。NodePort 服务的 YAML 相似这样:
apiVersion: v1 kind: Service metadata: name: my-nodeport-service selector: app: my-app spec: type: NodePort ports: - name: http port: 80 targetPort: 80 nodePort: 30036 protocol: TCP
基本上,NodePort 服务与普通的 “ClusterIP” 服务 YAML 定义有两点区别。 首先,type 是 “NodePort”。还有一个称为 nodePort 的附加端口,指定在节点上打开哪一个端口。 若是你不指定这个端口,它会选择一个随机端口。
这种方法有许多缺点:
因为这些缘由,我不建议在生产中使用这种方法。 若是您运行的服务没必要始终可用,或者您很是关注成本,则此方法适用于您,好比演示程序或临时应用。
LoadBalancer 服务暴露服务的标准方式。 在 GKE 上,这将启动一个网络负载平衡器,它将为您提供一个将全部流量转发到您的服务的IP地址。
若是你想直接暴露一个服务,这是默认的方法(GKE上)。 您指定的端口上的全部流量都将被转发到该服务, 没有过滤、路由等。这意味着您能够发送几乎任何类型的流量,如 HTTP,TCP,UDP,Websockets,gRPC 或其余。
最大的缺点是,您使用 LoadBalancer 公开的每项服务都将得到本身的 IP 地址,而且您必须为每一个暴露的服务使用一个 LoadBalancer,这可能会付出比较大的代价!
与以上全部例子不一样,Ingress 实际上不是一种服务。相反,它位于多个服务以前,充当集群中的“智能路由器”或入口点。
您可使用 Ingress 作不少不一样的事情,而且有许多类型的 Ingress 控制器,具备不一样的功能。
GKE 默认的 Ingress 控制器将为您启动一个 HTTP(S)负载均衡器。 这将使您能够执行基于路径和基于子域名的路由到后端服务。 例如,您能够将 foo.yourdomain.com 上的全部内容发送到 foo 服务,并将 yourdomain.com/bar/ 路径下全部内容发送到 bar 服务的。在 GKE 上的 七层 HTTP 负载均衡器 的 Ingress 对象 YAML 定义相似这样:
apiVersion: extensions/v1beta1 kind: Ingress metadata: name: my-ingress spec: backend: serviceName: other servicePort: 8080 rules: - host: foo.mydomain.com http: paths: - backend: serviceName: foo servicePort: 8080 - host: mydomain.com http: paths: - path: /bar/* backend: serviceName: bar servicePort: 8080
Ingress 多是暴露服务最强大的方式了,但也多是最复杂的。 来自 Google Cloud Load Balancer, Nginx, Contour, Istio 等的 Ingress 控制器类型不少。 还有用于 Ingress 控制器的插件,如 cert-manager,能够为您的服务自动提供 SSL 证书。
若是您但愿在相同的 IP 地址下暴露多个服务,而且这些服务都使用相同的L7协议(一般是HTTP),则 Ingress 是最有用的。 若是您使用原生 GCP 集成,您只需支付一个负载平衡器,因为 Ingress 很“智能”,您能够得到许多开箱即用的功能(如 SSL,Auth,路由等)