在 Kubernetes 中路由内部流量?

Bru*_*e L 2 kubernetes istio envoyproxy

我们目前有一个设置,我们的 mesos/marathon 集群中的应用程序希望访问可能驻留在或不驻留在我们的 mesos/marathon 集群中的服务。外部流量进入集群是通过位于 Traefik 实例集群前面的 Amazon ELB 完成的,然后与本质上多对多的情况相比,Traefik 实例集群选择适当的一组容器实例来通过传入的 HTTP 主机标头进行负载平衡- 配置的主机标头与特定容器实例的一个关联。内部到内部的流量实际上也是通过相同的路由处理的,因为与给定服务关联的 DNS 记录被映射到我们的 mesos/marathon 集群内部和外部的同一个 ELB。我们还提供了让多个 DNS 记录指向同一容器集的能力。

此设置有效,但会导致我们的 ELB 以及 Traefik 集群看似不必要的网络流量和负载,就好像容器或其他组件中的应用程序能够自行确定它们希望调用的服务位于它们所在的特定 mesos/marathon 集群,并对容器组前面的集群内部的某些内容进行适当的调用,或者直接对特定容器本身进行调用。

根据我对 Kubernetes 的理解,Kubernetes 提供了服务的概念,它本质上可以充当一组 pod 的前端,基于服务应该匹配哪些 pod 的配置。然而,我并不完全确定我们可以让 Kubernetes 集群中的应用程序透明地知道将网络流量引导到服务 IP 的机制。我认为<application-name>.<cluster-name>.company.com,通过使用 Envoy 代理流量(例如服务名称)可以对此有所帮助,但如果我们有一个映射到先前 DNS 条目(例如, <application-name>.company.com)的 CNAME,我不完全确定我们如何可以避免退出集群。

对于这两种情况有没有好的解决办法呢?我们试图避免让应用程序的逻辑必须了解它位于特定的集群中,并且更喜欢应用程序外部的组件来适当地执行路由。

如果我从根本上误解了某个特定组件,我将很乐意纠正!

Ant*_*nko 6

当您在集群内使用服务到服务通信时,您正在使用Service抽象,它类似于静态点,它将把流量传送到正确的 Pod。

服务端点仅可通过内部 Kubernetes DNS 服务器提供的 IP 或内部 DNS 名称在集群内部使用。因此,为了在集群内部进行通信,您可以使用 DNS 名称,例如<servicename>.<namespace>.svc.cluster.local.

但是,更重要的是,Service 有一个静态 IP 地址

因此,现在您可以将该静态 IP 作为hosts记录添加到集群内的 Pod,以确保它们能够在集群内相互通信。

为此,您可以使用HostAlias功能。下面是一个配置示例:

apiVersion: v1
kind: Pod
metadata:
  name: hostaliases-pod
spec:
  restartPolicy: Never
  hostAliases:
  - ip: "10.0.1.23"
    hostnames:
    - "my.first.internal.service.example.com"
  - ip: "10.1.2.3"
    hostnames:
    - "my.second.internal.service.example.com"
  containers:
  - name: cat-hosts
    image: busybox
    command:
    - cat
    args:
    - "/etc/hosts"
Run Code Online (Sandbox Code Playgroud)

因此,如果您将内部服务 IP 与服务的公共 FQDN 结合使用,则来自 pod 的所有流量都将 100% 在集群内,因为应用程序将使用内部 IP 地址。

另外,您可以使用包含相同别名的上游 DNS服务器,但想法是相同的。对于单独区域的上游 DNS,解析将像这样工作: 使用上游 DNS 解析区域

有了新版本的 Kubernetes,它使用 Core DSN 来提供 DNS 服务,并且具有更多功能,它会更简单一些。