(使用 Istio 0.5.1,kubectl 1.9.1/1.9.0 用于客户端/服务器,minikube 0.25.0)
我正在尝试让 Istio EgressRules 与 Kubernetes 服务一起使用,但遇到了一些麻烦。
我尝试通过 3 种方式设置 EgressRules:
www.google.com)
端点对象(用于具有 IP 地址但没有 DNS 的服务
姓名)
我想我可以使用 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 并获取了 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 页面(有时响应似乎是空的,不知道如何具体复制一个或另一个)这有时也会给出空洞的回应。
我想使用 Kubernetes 服务(即使它用于外部流量)有几个原因:
使用
https://
在应用程序代码中不是一个选项,因为这样请求将不得不禁用 TLS 验证,因为 kube-dns 名称与证书上的任何名称都不匹配。它也不会被观察到。如果我使用以下 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 block 指定规则。来自 TCP Egress :“在 TCP 导出规则中,与基于 HTTP 的导出规则相反,目的地由 IP 或 CIDR 表示法中的 IP block 指定。”。
此外,我仍然希望来自 L7 而不是 L4 的基于 HTTP 的可观察性,所以我更喜欢基于 HTTP 的导出。 (使用 TCP Egresses,“应用程序产生的 HTTPS 流量将被 Istio 视为不透明的 TCP”)。
任何帮助将 Kubernetes 服务作为 EgressRule 的“目标服务”(或帮助理解为什么在这种情况下这不是必需的)都将受到赞赏。谢谢!
最佳答案
解决方案是:
在您的情况下,使用端口和协议(protocol)定义一个 ExternalName 服务:
kind: Service
apiVersion: v1
metadata:
name: ext-service
spec:
type: ExternalName
externalName: www.google.com
ports:
- port: 80
# important to set protocol name
name: http
---
定义一个 HTTP 重写路由规则来设置 Host 头:
apiVersion: config.istio.io/v1alpha2
kind: RouteRule
metadata:
name: externalgoogle-rewrite-rule
#namespace: default
spec:
destination:
name: ext-service
rewrite:
authority: www.google.com
---
然后使用
curl
访问它,例如:curl ext-service
如果没有路由规则,请求将到达 google.com,Host header 为
ext-service
.由于 google.com 没有这样的虚拟主机,因此 Web 服务器不知道将此类请求转发到何处。这是你所经历的:it brought me to Google's 404 page
关于kubernetes - 使用 Kubernetes 服务的 Istio 导出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49268369/