(使用Istio 0.5.1,kubectl 1.9.1 / 1.9.0用于客户端/服务器,minikube 0.25.0)
我试图让Istio EgressRules与Kubernetes Services合作,但遇到了一些麻烦 .
我尝试设置EgressRules 3种方式:
-
指向其他域的ExternalName服务(如www.google.com)
-
没有选择器但关联的Endpoint对象的服务(对于具有IP地址但没有DNS名称的服务)
-
(用于比较)没有Kubernetes服务,只是一个EgressRule
我想我可以使用kubernetes服务的FQDN作为基于HTTP的EgressRule目标服务(如 ext-service.default.svc.cluster.local
),这就是我尝试的ExternalName服务以及没有选择器但只有关联的Endpoints对象的服务 .
对于前者,我创建了以下 yaml
文件:
kind: Service
apiVersion: v1
metadata:
name: ext-service
spec:
type: ExternalName
externalName: www.google.com
---
apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
name: ext-egress-rule
spec:
destination:
service: ext-service.default.svc.cluster.local
ports:
- port: 443
protocol: https
对于后者,我创建了这个 yaml
文件(我只是ping了google并 grab 了IP地址):
kind: Endpoints
apiVersion: v1
metadata:
name: ext-service
subsets:
- addresses:
- ip: 216.58.198.78
ports:
- port: 443
---
kind: Service
apiVersion: v1
metadata:
name: ext-service
spec:
ports:
- protocol: TCP
port: 443
targetPort: 443
---
apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
name: ext-service-egress-rule
spec:
destination:
service: ext-service.default.svc.cluster.local
ports:
- port: 443
protocol: https
在这两种情况下,在应用程序代码中,我访问:
http://ext-service.default.svc.cluster.local:443
我的假设是流量会像以下一样流动:
[[ app -> envoy proxy -> (tls origination) -> kubernetes service ]] -> external service
其中 [[ ... ]]
是服务网格的边界(以及Kubernetes集群)
结果:
-
ExternalName
服务几乎按预期工作,但它带我到谷歌的404页面(有时响应似乎是空的,不知道如何特别复制一个或另一个) -
使用Endpoint对象的服务不起作用,而是打印此消息(通过Golang发出请求时,但我认为不重要):
获取http://ext-service.default.svc.cluster.local:443:EOF
这有时也会给出空洞的回应 .
我想使用Kubernetes服务(即使它是针对外部流量)的原因有以下几点:
-
您可以't use an IP address for the EgressRule'的目的地服务 . 从Egress Rules configuration:"The destination of an egress rule ... can be either a fully qualified or wildcard domain name" .
-
对于不喜欢应用程序的外部服务,不能通过IP地址访问它们,而是通过kube-dns(或与Istio相关的类似名称)访问它们 .
-
(与之前相关)我喜欢Kubernetes服务提供的额外抽象层,因此我可以在不更改EgressRule的情况下更改基础目标(除非我正确地构建此框架) . EgressRule是否意味着完全取代Kubernetes服务以获得外部流量,而无需创建额外的Kubernetes服务?
在应用程序代码中使用 https://
与证书上的任何内容都不匹配 . 它也是不可观察的 .
如果我使用以下EgressRule(没有任何Kubernetes服务),通过 http://www.google.com:443
访问Google工作正常,获得我期望的确切html表示:
apiVersion: config.istio.io/v1alpha2
kind: EgressRule
metadata:
name: google-egress-rule
spec:
destination:
service: www.google.com
ports:
- port: 443
protocol: https
我看到有一个TCP EgressRule,但我宁愿不必为每个IP块指定规则 . 从TCP Egress:"In TCP egress rules as opposed to HTTP-based egress rules, the destinations are specified by IPs or by blocks of IPs in CIDR notation." .
此外,我仍然喜欢来自L7而不是L4的基于HTTP的可观察性,所以我更喜欢基于HTTP的出口 . (使用TCP Egresses,“由应用程序发起的HTTPS流量将被Istio视为不透明的TCP”) .
任何帮助获得Kubernetes服务作为EgressRule的“目的地服务”(或帮助理解为什么这不是必要的,如果是这种情况)的任何帮助表示赞赏 . 谢谢!
1 回答
解决方案是:
定义Kubernetes ExternalName服务以指向www.google.com
不要定义任何EgressRules
创建RouteRule以设置主机标头 .
在您的情况下,使用端口和协议定义ExternalName服务:
定义HTTP重写路由规则以设置主机头:
然后使用
curl
访问它,例如:curl ext-service
如果没有路由规则,请求将到达google.com,主机标头为
ext-service
. 由于google.com没有这样的虚拟主机,因此Web服务器不知道转发此类请求的位置 . 这是你经历的: