问题描述
我将Istio部署在AWS EKS托管的Kubernetes集群中.这样就创建了一个名为istio-ingressgateway的LoadBalancer类型的Kubernetes服务,其外部主机名为[redacted]-redacted.us-west-2.elb.amazonaws.com
,并自动配置了类型为AWS的AWS ELB.那太棒了. (注意:在AWS控制台中,我没有看到此Elb主机名的托管区域,它似乎无法配置别名或其他)
通过定义一个将端口80打开到host:"*"
的istio网关,并定义一个路由端口80的istio虚拟服务,我已经能够将在集群外部运行的gRPC客户端连接到在集群中运行的gRPC服务器.到我的目的地(一些kubernetes服务的某个端口).到目前为止一切顺利.
现在,我想对集群中的第二个gRPC端点执行此操作.据我所知,我的选择是:通过在入口处打开第二个端口(例如81)进行路由(我现在暂时不选择这样做).或通过定义[redacted]-redacted.us-west-2.elb.amazonaws.com
的子域进行路由,或通过实现虚拟主机"(即客户端在标头中发送host:"svc1"
的同一域上的两个服务)进行路由.
这就是我被困住的地方.我不知道如何为该ELB域名定义子域,也不知道我是否可以使用TLS进行虚拟托管,如果可以,我是否仍可以使用"passthrough"代理? 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前缀为域.
我可以为通过部署Istio自动置备的经典AWS ELB创建的域定义子域svc1
和svc2
吗?我可以使用kubectl/istioctl
来执行此操作以配置Istio,还是需要使用AWS CLI来执行此操作?可以在不注册域的情况下完成此操作,我可以使用不友好的elb.amazonaws.com主机名吗?
2-虚拟主机:或者,我可以在gRPC元数据中添加host = svc1.我尝试将ctx := metadata.AppendToOutgoingContext(context.Background(), "Host", "svc1")
添加到我的Go客户端中,但这没用.
一些指导会很棒.
更新1和一种用于纯文本的解决方案我正在阅读 HTTP标头字段列表主机"标头不应在HTTP2中使用.鉴于这是gRPC,它是HTTP2,因此我不应该在我的gRPC客户端请求中将其添加为自定义标头.在gRPC客户端中进行虚拟托管时(而不是发送主机")的解决方案是:标头中,您将发送":: Authority"标头,该值必须对应于istio的gateway + virtualservice中指定的主机.这对我有用.在我的Go客户端中,我必须添加dialOptions = append(dialOptions, grpc.WithAuthority("[my-service-1]"))
.
根据 GoDoc grpc.WithAuthority .因此,当使用TLS时,我仍然需要找到如何从相同的外部IP和端口路由2个服务.
更新1.1:在虚拟主机中,当使用TLS时,可以在CLIENT HELLO消息中传递SNI,而不是像纯文本中那样是gRPC头.取决于您的语言,确切的API会有所不同,但是在Go语言中,我可以通过在 tls.Config .然后,您可以在istio网关配置中选择该主机名,并在istio虚拟服务中基于该值进行路由.
更新2:我尝试但未能在AWS Route53上创建子域.首先,我为domain:[redacted] -redacted.us-west-2.elb.amazonaws.com创建一个公共托管区域.接下来,在该托管区域中,我创建一个名称为svc1.
[redacted] -redacted.us-west-2.elb.amazonaws.com的A记录,route = Alias到Classic Load Balancer,region = us-west-2 ,负载均衡器=双栈.[已编辑] -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(不带svc1前缀)返回3 A记录,并具有3个负载均衡器的IP.
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
我不确定您要寻找的是什么,但是我在aws文档中进行了一些研究,发现可以使用 Amazon Route 53 来实现您所需要的.
以下信息收集自:
- https://aws.amazon.com/route53/faqs/
- https://docs .aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html
还有关于子域的问题
其他资源:
- 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
I deployed Istio in a Kubernetes cluster hosted in AWS EKS. That created a Kubernetes service of type LoadBalancer named istio-ingressgateway with an external hostname of [redacted]-redacted.us-west-2.elb.amazonaws.com
, and automatically provisioned an AWS ELB, type classic. That's great. (Note: in AWS console I do not see a hosted zone for this elb hostname, it doesn't look like I can configure aliases or whatnot)
I've been able to connect a gRPC client running outside the cluster, to a gRPC server running in the cluster by defining an istio gateway which opens port 80 to host:"*"
, and defining an istio virtual service which routes port 80 to my destination (some port of some kubernetes service). So far so good.
Now I would like to do this for a second gRPC endpoint in the cluster. As far as I know, my choices are: either route by opening a second port (say 81) on the ingress (which I'm choosing not to do for now). Or route by defining subdomains of [redacted]-redacted.us-west-2.elb.amazonaws.com
, or route by implementing "virtual hosting", i.e. two services on the same domain where the client sends host:"svc1"
in a header.
This is where I'm stuck. I don't know how do define subdomains to this ELB domain name, and I don't know if I can do virtual hosting with TLS, and if so, can I still use the "passthrough" tls mode of Istio so as not to TLS-terminate on the gateway.
1- Using subdomains: When on my developer machine I try getent hosts svc1.[redacted]-redacted.us-west-2.elb.amazonaws.com
it does not map to an IP, whereas if remove the svc1
prefix DNS returns 3 IPs (guessing the 3 availability zones in us-west-2). So I can't prefix svc1 to the domain without some work.
Can I define subdomains svc1
and svc2
for a domain created by classic AWS ELB automatically provisioned by deploying Istio, and if so how? Can I do this with kubectl/istioctl
to configure Istio, or do I need to do this with the AWS CLI? Can this be done without registering a domain, i'm fine with that user-unfriendly elb.amazonaws.com hostname?
2- Virtual Hosting: Alternatively I could add a host=svc1 in the gRPC metadata. I tried adding ctx := metadata.AppendToOutgoingContext(context.Background(), "Host", "svc1")
to my Go client, that did not work.
Some guidance would be great.
Update 1, and one solution for plaintextI'm reading on List of HTTP header fields the "Host" header should not be used in HTTP2. Given this is gRPC it is HTTP2 and as such I should not add this as a custom header in my gRPC client requests. The solution when doing virtual hosting, in a gRPC client instead of sending a "host" header, you send an ":Authority" header, the value must correspond to the host specified in istio's gateway+virtualservice. This works for me. In my Go client I had to add dialOptions = append(dialOptions, grpc.WithAuthority("[my-service-1]"))
.
That solution won't work for TLS according to GoDoc grpc.WithAuthority. So I still need to find how to route 2 services from the same external IP and port when TLS is used.
Update 1.1:In virtual hosting, when TLS is used, the SNI can be passed in the CLIENT HELLO message, instead of being a gRPC header like in plaintext . Depending on your language the exact API is going to vary, but in Go I was able to pass the host name by setting the ServerName
field in tls.Config. You can then gate on that hostname in your istio gateway configuration, and route based on that value in your istio virtualservice.
Update 2: I tried, and failed, to create the subdomain on AWS Route53. First I create a public hosted zone for domain:[redacted]-redacted.us-west-2.elb.amazonaws.com. Next, in that hosted zone I create an A record with name=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.
I later test the svc1.[redacted]-redacted.us-west-2.elb.amazonaws.com A record exists with dig
, which does not return an answer. However dig does return 3 A records for [redacted]-redacted.us-west-2.elb.amazonaws.com (without the svc1 prefix),with the IPs of 3 load balancers.
Istio
You can't do it with istio, you have to configure that in the cloud, in your case you have to configure that on aws.
On istio you can only specify the hosts, which would be the subdomains configured on aws.
Virtual Services would look like this:
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
I'm not exactly sure that's what you're looking for, but I did some research in the aws documentation and I found that you could use Amazon Route 53 to achieve what you need.
The following informations are collected from:
- https://aws.amazon.com/route53/faqs/
- https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/routing-to-elb-load-balancer.html
And there is Question about the subdomains
Additional resources:
- 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
这篇关于我可以为Istio所配置的经典AWS ELB定义子域吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!