在Kubernetes上实现微服务之间跨集群通信的最佳方式是什么?

huangapple go评论86阅读模式
英文:

Best way for inter-cluster communication between microservices on Kubernetes?

问题

以下是翻译好的内容:

我刚接触微服务,并且想要了解如何在部署在 Kubernetes 上的微服务中实现以下行为的最佳方法:

有两个不同的 K8s 集群。微服务 B 部署在这两个集群中。

现在,如果微服务 A 调用微服务 B,而集群 1 中没有 B 的 pods 可用,那么调用应该转到集群 2 中的 B。

我本来可以想象使用 Netflix OSS 来实现这个功能,但这里我没有使用它。

此外,暂时不考虑集群间通信,我应该如何在微服务之间进行通信?

我知道的一种方法是为每个微服务创建 NodePort 类型的 Kubernetes Service,并在调用微服务中使用 IP 和 nodePort。

问题:如果有人删除目标微服务的 K8s Service 呢?K8s 在重新创建 K8s 服务时会随机分配新的 nodePort,然后我又必须返回我的调用微服务并更改目标微服务的 nodePort。如何与 nodePort 解耦?

我研究过 kubedns,但似乎它只在集群内部工作。

我对 Istio 和 Kubernetes Ingress 的了解非常有限。它们中的任何一个是否提供我所寻找的功能?

对于问题的长度我感到抱歉。任何形式的指导都将非常有帮助。

英文:

I am new to microservices and want to understand what is the best way I can implement below behaviour in microservices deployed on Kubernetes :

There are 2 different K8s clusters. Microservice B is deployed on both the clusters.

Now if a Microservice A calls Microservice B and B’s pods are not available in cluster 1, then the call should go to B of cluster 2.

I could have imagined to implement this functionality by using Netflix OSS but here I am not using it.

Also, keeping aside the inter-cluster communication aside for a second, how should I communicate between microservices ?

One way that I know is to create Kubernetes Service of type NodePort for each microservice and use the IP and the nodePort in the calling microservice.

Question : What if someone deletes the target microservice's K8s Service? A new nodePort will be randomly assigned by K8s while recreating the K8s service and then again I will have to go back to my calling microservice and change the nodePort of the target microservice. How can I decouple from the nodePort?

I researched about kubedns but seems like it only works within a cluster.

I have very limited knowledge about Istio and Kubernetes Ingress. Does any one of these provide something what I am looking for ?

Sorry for a long question. Any sort of guidance will be very helpful.

答案1

得分: 10

你可以使用服务来暴露你的应用程序,有几种类型的服务可以使用:

  • ClusterIP:在集群内部 IP 上暴露服务。选择此值使得服务仅能在集群内部访问。这是默认的 ServiceType
  • NodePort:在每个节点的 IP 上以静态端口(NodePort)暴露服务。自动创建一个 ClusterIP 服务,该服务路由到 NodePort 服务。你可以通过请求 <NodeIP>:<NodePort> 来从集群外部访问 NodePort 服务。
  • LoadBalancer:使用云提供商的负载均衡器在外部暴露服务。自动创建 NodePortClusterIP 服务,外部负载均衡器会路由到这些服务。
  • ExternalName:通过返回 CNAME 记录,将服务映射到 externalName 字段的内容(例如 foo.bar.example.com)。

对于内部通信,你可以使用服务类型 ClusterIP,并且可以为应用程序配置服务 DNS,而不是使用 IP 地址。例如:名为 my-app-1 的服务可以通过 DNS http://my-app-1 或 FQDN http://my-app-1.<namespace>.svc.cluster.local 在内部访问。

对于外部通信,你可以使用 NodePortLoadBalancer

NodePort 在你拥有少量节点并且知道它们所有的 IP 时是很好的选择。是的,根据服务文档,你可以指定一个特定的端口号:

如果你想要一个特定的端口号,可以在 nodePort 字段中指定一个值。控制平面将为你分配该端口,或者报告 API 事务失败。这意味着你需要自行处理可能的端口冲突。你还必须使用有效的端口号,即在为 NodePort 使用配置的范围内的端口号。

LoadBalancer 提供更多的灵活性,因为你不需要知道所有节点的 IP,只需要知道服务的 IP 和端口。但是 LoadBalancer 仅在云提供商中受支持,如果你想在裸金属集群中实现,我建议你看看 MetalLB

最后,还有另一种选项可以使用 ingress,在我看来,这是暴露外部 HTTP 应用程序的最佳方式,因为你可以根据路径和主机创建规则,它比服务提供更多的灵活性。但是仅支持 HTTP/HTTPS,如果需要 TCP,则转向服务。

我建议你查看以下链接,深入了解服务和 Ingress 的工作原理:

英文:

You can expose you application using services, there are some kind of services you can use:

>- ClusterIP: Exposes the Service on a cluster-internal IP. Choosing this value makes the Service only reachable from within the cluster. This is the default ServiceType.
>
>- NodePort: Exposes the Service on each Node’s IP at a static port (the NodePort). A ClusterIP Service, to which the NodePort Service routes, is automatically created. You’ll be able to contact the NodePort Service, from outside the cluster, by requesting &lt;NodeIP&gt;:&lt;NodePort&gt;.
>
>- LoadBalancer: Exposes the Service externally using a cloud provider’s load balancer. NodePort and ClusterIP Services, to which the external load balancer routes, are automatically created.
>- ExternalName: Maps the Service to the contents of the externalName field (e.g. foo.bar.example.com), by returning a CNAME record

For internal communication you an use service type ClusterIP, and you could configure the service dns for your applications instead an IP.
I.e.: a service called my-app-1 could be reach internnaly using the dns http://my-app-1 or with fqdn http://my-app-1.&lt;namespace&gt;.svc.cluster.local.

For external communication, you can use NodePort or LoadBalancer.

NodePort is good when you have few nodes and know the ip of all of them. And yes, by the service docs you can specify a specific port number:

>If you want a specific port number, you can specify a value in the nodePort field. The control plane will either allocate you that port or report that the API transaction failed. This means that you need to take care of possible port collisions yourself. You also have to use a valid port number, one that’s inside the range configured for NodePort use.

LoadBalancer give you more flexibility, because you don't need to know all node ips, you just must to know the service IP and port. But LoadBalancer is only supported in cloudproviders, if you wan to implement in bare-metal cluster, I recomend you take a look in MetalLB.

Finally, there is another option that is use ingress, in my point of view is the best way to expose HTTP applications externally, because you can create rules by path and host, and it gives you much more flexibility than services. But only HTTP/HTTPS is supported, if you need TCP then go to Services.

I'd recommend you take a look in these links to understand in deep how services and ingress works:

Kubernetes Services

Kubernetes Ingress

NGINX Ingress

答案2

得分: 3

你的设计与Istio Multicluster示例非常接近。

通过按照Istio多集群实验室中的步骤,您将获得两个集群,其中一个Istio控制平面平衡位于两个独立Kubernetes集群中的两个ClusterIP服务之间的流量。

实验室的配置会监视流量负载,但通过重写控制器Pod的代码,您可以将其配置为在Cluster One的Service没有端点(某种类型的所有Pod都不处于Ready状态)时将流量切换到Second Cluster。

这只是一个示例,您可以更改istiowatcher.gocode以实现任何您想要的逻辑。


还有一个更高级的解决方案,使用Admiral作为Istio多集群管理自动化工具。

Admiral为跨多个集群跨足迹的Istio网格提供了自动配置,以便根据唯一的服务标识符将运行在多个集群上的工作负载关联到一个服务。它还提供了跨集群的Istio配置的自动配置和同步。这减轻了开发人员和网格操作员的负担,有助于超越少数集群的规模。

这个解决方案解决了现代Kubernetes基础架构的以下关键要求:

  • 创建与命名空间分离的服务DNS条目,如多网格部署的特性所述。
  • 跨多个集群进行服务发现。
  • 支持活动-活动和HA/DR部署。我们还必须支持在不同集群中部署在全球唯一命名空间中的服务的关键弹性模式。

在大规模情况下,这个解决方案可能会变得非常有用。

英文:

Your design is pretty close to Istio Multicluster example.

By following the steps in the Istio multicluster lab you'll get two clusters with one Istio control plane that balance the traffic between two ClusterIP Services located in two independent Kubernetes clusters.

The lab's configuration watches the traffic load, but rewriting the Controller Pod code you can configure it to switch the traffic to the Second Cluster if the Cluster One's Service has no endpoints ( all pods of the certain type are not in Ready state).

It's just an example, you can change istiowatcher.go code to implement any logic you want.


There is more advanced solution using Admiral as an Istio Multicluster management automation tool.

>Admiral provides automatic configuration for an Istio mesh spanning multiple clusters to work as a single mesh based on a unique service identifier that associates workloads running on multiple clusters to a service. It also provides automatic provisioning and syncing of Istio configuration across clusters. This removes the burden on developers and mesh operators, which helps scale beyond a few clusters.

This solution solves these key requirements for modern Kubernetes infrastructure:

  • Creation of service DNS entries decoupled from the namespace, as described in Features of multi-mesh deployments.
  • Service discovery across many clusters.
  • Supporting active-active & HA/DR deployments. We also had to support these crucial resiliency patterns with services being deployed in globally unique namespaces across discrete clusters.

This solution may become very useful in a full scale.

答案3

得分: 1

使用 Ingress 进行集群间通信,并且在两个微服务之间的集群内部通信时使用 Cluster IP 类型的服务。

英文:

Use ingress for inter cluster communication and use cluster ip type service for intra cluster communication between two micro services.

huangapple
  • 本文由 发表于 2020年4月9日 05:13:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/61110127.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定