我可以为 Istio 预置的经典 AWS ELB 定义子域吗?

Posted

技术标签:

【中文标题】我可以为 Istio 预置的经典 AWS ELB 定义子域吗?【英文标题】:Can I define subdomains for a classic AWS ELB that was provisioned by Istio? 【发布时间】:2021-01-10 05:24:55 【问题描述】:

我在 AWS EKS 中托管的 Kubernetes 集群中部署了 Istio。这创建了一个名为 istio-ingressgateway 的 LoadBalancer 类型的 Kubernetes 服务,外部主机名为 [redacted]-redacted.us-west-2.elb.amazonaws.com,并自动预置了一个 AWS ELB,类型为 classic。那太棒了。 (注意:在 AWS 控制台中,我没有看到此 elb 主机名的托管区域,看起来我无法配置别名或其他东西)

我已经能够通过定义一个打开端口 80 到host:"*" 的 istio 网关,并定义一个路由端口 80 的 istio 虚拟服务,将运行在集群外的 gRPC 客户端连接到运行在集群中的 gRPC 服务器到我的目的地(某些 kubernetes 服务的某个端口)。到目前为止一切顺利。

现在我想为集群中的第二个 gRPC 端点执行此操作。据我所知,我的选择是:通过在入口上打开第二个端口(比如 81)来路由(我现在选择不这样做)。或者通过定义[redacted]-redacted.us-west-2.elb.amazonaws.com 的子域进行路由,或者通过实现“虚拟主机”进行路由,即客户端在标头中发送host:"svc1" 的同一域上的两个服务。

这就是我卡住的地方。不知道怎么给这个ELB域名定义子域,也不知道能不能用TLS做虚拟主机,如果能,还能不能用Istio的“直通”tls模式以免网关上的 TLS 终止。

1- 使用子域: 在我的开发人员机器上尝试getent hosts svc1.[redacted]-redacted.us-west-2.elb.amazonaws.com 时,它不会映射到 IP,而如果删除 svc1 前缀 DNS 会返回 3 个 IP(猜测 3 个可用性us-west-2 中的区域)。所以我不能在没有工作的情况下为域添加前缀 svc1。

我能否为由经典 AWS ELB 创建的域定义子域 svc1svc2,通过部署 Istio 自动预置,如果可以,如何?我可以使用 kubectl/istioctl 来配置 Istio,还是需要使用 AWS CLI 来执行此操作?这可以在不注册域的情况下完成吗,我可以接受用户不友好的 elb.amazonaws.com 主机名吗?

2- 虚拟主机: 或者,我可以在 gRPC 元数据中添加 host=svc1。我尝试将 ctx := metadata.AppendToOutgoingContext(context.Background(), "Host", "svc1") 添加到我的 Go 客户端,但没有成功。

一些指导会很棒。

更新 1,以及一种纯文本解决方案 我正在阅读List of HTTP header fields 上的“主机”标头不应在 HTTP2 中使用。鉴于这是 gRPC,它是 HTTP2,因此我不应该在我的 gRPC 客户端请求中将其添加为自定义标头。做虚拟主机时的解决方案,在gRPC客户端中不是发送“host”头,而是发送“:Authority”头,该值必须对应于istio的gateway+virtualservice中指定的主机。这对我有用。在我的 Go 客户端中,我必须添加 dialOptions = append(dialOptions, grpc.WithAuthority("[my-service-1]"))

根据GoDoc grpc.WithAuthority,该解决方案不适用于 TLS。所以我仍然需要找到如何在使用 TLS 时从相同的外部 IP 和端口路由 2 个服务。

更新 1.1: 在虚拟主机中,当使用 TLS 时,SNI 可以在 CLIENT HELLO 消息中传递,而不是像明文那样作为 gRPC 标头。根据您的语言,确切的 API 会有所不同,但在 Go 中,我可以通过在 tls.Config 中设置 ServerName 字段来传递主机名。然后,您可以在您的 istio 网关配置中对该主机名进行门控,并根据您的 istio 虚拟服务中的该值进行路由。

更新 2: 我尝试在 AWS Route53 上创建子域,但失败了。首先,我为域创建一个公共托管区域:[redacted]-redacted.us-west-2.elb.amazonaws.com。接下来,在该托管区域中,我创建一个 A 记录,名称为=svc1.[redacted]-redacted.us-west-2.elb.amazonaws.com,route=Alias to Classic Load Balancer,region=us-west-2 , load balancer=dualstack.[redacted]-redacted.us-west-2.elb.amazonaws.com.

我稍后测试了 svc1.[redacted]-redacted.us-west-2.elb.amazonaws.com 存在dig 的记录,它没有返回答案。但是 dig 确实返回了 [redacted]-redacted.us-west-2.elb.amazonaws.com 的 3 个 A 记录(不带 svc1 前缀),带有 3 个负载均衡器的 IP。

【问题讨论】:

您的配置看起来如何?你能提供你的网关/虚拟服务 yamls 吗? AFAIK 你可以做类似this 的事情,另一种方法是使用端口 80 为第一个 grpc 服务和端口 31400 为第二个服务。我的最后一个想法是为您的 grpc 服务添加自定义端口,就像我在您之前的 question 中已经提到的那样。如果这能回答您的问题,请告诉我。 我的网关 yaml 很简单,它只是打开了 80 端口。我的虚拟服务 yaml 在同一个网关上定义了 2 个虚拟服务,第一个用于 host=svc1,路由到 service1,第二个用于 host =svc2,带有到 service2 的路由。这行得通。但它需要客户端发送“:Authority=svcX”标头,这在使用 TLS 时无法解决。我想知道如何更新它以使用 TLS。在我看来,拥有 ELB 主机名的 2 个子域会更“干净”。这样我可以更轻松地升级到使用 TLS。但我不知道如何子域 ELB 主机名。 我有类似的情况,但使用 https。两个服务接受路径/ 上的流量,而我只能使用端口443。我通过使用两个带有子域abc.example.comdef.example.com 指向负载均衡器外部IP 的DNS 条目解决了这个问题。网关接受这两个条目作为主机。对于每个子域,我都有一个VirtualService 转发到/ 上的正确服务。如果你愿意,我可以发布我的配置作为答案。 谢谢@ChristophRaab。我很想学习如何为域“[redacted]-[redacted].us-west-2.elb.amazonaws.com”创建 2 个子域“abc”和“def”,而无需创建自定义域名“ example.com”,或者被告知这是不可能的,我必须创建一个自定义域名来定义“abc”和“def”子域。 抱歉,但我不知道如何仅使用 istio 执行此操作,除非可能创建两个入口网关。我来自 Azure,在那里我使用私有 DNS 区域解决了子域部分,以在我的网络中解析 DNS,但没有注册公共域。 AWS 也应该有一些东西。 【参考方案1】:

Istio

我能否为由经典 AWS ELB 创建的域定义子域 svc1 和 svc2,通过部署 Istio 自动预置,如果可以,如何?

你不能用 istio 来做,你必须在云中配置它,在你的情况下你必须在 aws 上配置它。

在 istio 上,您只能指定主机,即在 aws 上配置的子域。

虚拟服务如下所示:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: mipnw-vs1
spec:
  hosts:
  - svc1.example.com
  http:
  - name: "svc1-route"
    match:
    - uri:
        prefix: /
    route:
    - destination:
        host: svc1.default.svc.cluster.local

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: mipnw-vs2
spec:
  hosts:
  - svc2.example.com
  http:
  - name: "svc2-route"
    match:
    - uri:
        prefix: /
    route:
    - destination:
        host: svc2.default.svc.cluster.local

AWS

我很想学习如何为域“[redacted]-[redacted].us-west-2.elb.amazonaws.com”创建 2 个子域“abc”和“def”

我不确定这就是您要查找的内容,但我在 aws 文档中进行了一些研究,发现您可以使用 Amazon Route 53 来满足您的需求。

Amazon Route 53 是一种高度可用且可扩展的云域名系统 (DNS) Web 服务。它旨在通过将 www.example.com 之类的名称转换为 192.0.2.1 之类的数字 IP 地址,为开发人员和企业提供一种极其可靠且经济高效的方式来将最终用户路由到 Internet 应用程序

以下信息收集自:

https://aws.amazon.com/route53/faqs/ https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html

如果您在多个 Amazon EC2 实例上托管网站,则可以使用 Elastic Load Balancing (ELB) 负载均衡器跨实例将流量分配到您的网站。随着您网站的流量随时间变化,ELB 服务会自动扩展负载均衡器。负载均衡器还可以监控其注册实例的运行状况,并将域流量仅路由到运行状况良好的实例。

要将域流量路由到 ELB 负载均衡器r,请使用 Amazon Route 53 创建指向您的负载均衡器的别名记录。别名记录是 DNS 的 Route 53 扩展。它类似于 CNAME 记录,但您可以为根域(例如 example.com)和子域(例如 www.example.com)创建别名记录。(您只能为子域。)

Amazon Route 53 还提供别名记录,这是 Amazon Route 53 特定的 DNS 扩展。您可以创建别名记录以将流量路由到选定的 AWS 资源,包括 Amazon Elastic Load Balancing 负载均衡器、Amazon CloudFront 分配、AWS Elastic Beanstalk 环境、API 网关、VPC 接口终端节点和 Amazon S3 存储桶配置为网站。别名记录通常具有 A 或 AAAA 类型,但它们的工作方式类似于 CNAME 记录。使用别名记录,您可以将记录名称 (example.com) 映射到 AWS 资源 (elb1234.elb.amazonaws.com) 的 DNS 名称。解析器会看到 A 或 AAAA 记录以及 AWS 资源的 IP 地址。

还有关于子域的问题

我可以在我的子域中使用“别名”记录吗?

是的。您还可以使用别名记录将您的子域(www.example.com、pictures.example.com 等)映射到您的 ELB 负载均衡器、CloudFront 分配或 S3 网站存储桶。

其他资源:

https://medium.com/cloud-native-the-gathering/istio-ingress-to-expose-your-k8s-services-via-individual-dns-2ec9c2717b81 https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/dns-routing-traffic-for-subdomains.html

【讨论】:

我尝试使用 AWS Route53 为 ELB 创建一条 A 记录。那是行不通的。我在问题中描述了 Update2 中的过程。 说清楚,问题是是否可以在不注册自定义域名的情况下创建子域。 如提到的hereFor example, if the name of the hosted zone is example.com and you want to use acme.example.com to route traffic to your load balancer, enter acme。您能否尝试只输入svc1 而不是svc1.[redacted]-redacted.us-west-2.elb.amazonaws.com?要回答您的问题,据我所知,它应该在没有自定义域的情况下工作,但我对先决条件A registered domain name. 和我检查的所有 *** 问题都有自己的私有域感到困惑。 我开始认为不可能为 AWS ELB 域创建子域。唯一的方法是注册一个自定义域名,在 Route53 上为其创建一个托管区域,然后在该托管区域中为子域创建一条 A 记录。

以上是关于我可以为 Istio 预置的经典 AWS ELB 定义子域吗?的主要内容,如果未能解决你的问题,请参考以下文章

为 AWS ELB 生成公有/后端密钥

如何在 AWS ELB 日志中获取完整的 POST 正文?

从客户端到 AWS ELB 的持久连接

如何将 AWS ELB 连接到运行 MS SQL 的 RDS?

使用 TCP TLS 到 Nginx 的 AWS 经典负载均衡器

将 aws ELB 用于另一个托管实例