由于 Istio VirtualService,有没有办法代理对 ExternalName 服务的调用?
Is there a way to proxy calls to an ExternalName service thanks to an Istio VirtualService?
在我目前正在进行的项目中,我想为位于另一个命名空间中的 Kubernetes 服务创建一个 DNS 别名。为此,我创建了一个 ExternalName 服务,如下所示:
kind: Service
apiVersion: v1
metadata:
name: connector
namespace: test
spec:
type: ExternalName
externalName: gateway.eventing.svc.cluster.local
到目前为止,还不错。当我请求 'connector' DNS 时,我成功命中了外部名称,即 gateway.eventing.svc.cluster.local.
现在,我想将 headers 添加到发送到连接器 ExternalName 服务的所有 http 请求,因此我创建了一个 Istio VirtualService 来执行此操作:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: connector
namespace: test
spec:
hosts:
- connector
- connector.test.svc.cluster.local
http:
- match:
- uri:
prefix: /
route:
- destination:
host: connector
port:
number: 80
#headers config ignored for brevity
问题是从未调用 VirtualService。它似乎没有拦截对连接器 DNS 或其完全限定名称的请求,即 connector.test.svc.cluster.local.
我在阅读文档后认为,这是因为 Istio VirtualService 检查服务注册表,而 ExternalName 服务不是其中的一部分,它只是某种 DNS 别名。
因此,我尝试创建一个 Istio ServiceEntry,如下所示:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: connector
namespace: test
spec:
hosts:
- connector
endpoints:
- address: gateway.eventing.svc.cluster.local
ports:
- number: 80
name: http
protocol: HTTP
location: MESH_INTERNAL
resolution: DNS
它有效,我可以在 Kiali 中看到,在请求连接器时没有调用 PassthroughCluster,而是调用了连接器 ServiceEntry,据我所知应该发生什么。
但是,我的连接器 VirtualService 仍然没有被调用。这是为什么?有办法实现吗?
如果没有,我能做些什么来在给定的命名空间中别名(即测试)位于另一个(即事件)中的服务并通过 Istio VirtualService 代理 http 请求?
在此先感谢您的帮助!
编辑:
Sidecar 注入已启用namespace-wide(即测试)
更新
我没有看到缺少端口列表,我不确定如何应用 yml,因为应该需要该列表。
无论如何,我留下我的答案。也许它会进一步帮助其他人。
原文Post(略有修改)
文档不清楚,但我认为 header 操作可以由接收侧车完成。据我了解您的设置,ServiceEntry 背后的资源没有 sidecar,因此如果这是真的,则操作将不起作用。
为了添加自定义 header,您可以使用类型为 lua
的 EnvoyFilter
,它应用于发件人的 sidecar,并且可以即时操纵流量。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: add-custom-header-filter
namespace: test
spec:
configPatches:
- applyTo: CLUSTER
match:
context: SIDECAR_OUTBOUND
cluster:
service: connector
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.config.filter.http.lua.v2.Lua"
inlineCode: |
function envoy_on_request(request_handle)
response_handle:logInfo("adding custom headers..."");
response_handle:headers():add("X-User-Header", "worked");
end
此过滤器在出站时应用于命名空间 test
中的每个 sidecar 对服务入口连接器的每个请求,并在完成任何其他操作之前添加自定义 header。
因此,事实证明,使它正常工作所缺少的只是在 ExternalName 服务上指定和命名端口。
这是更新后的 yaml:
kind: Service
apiVersion: v1
metadata:
name: connector
namespace: test
spec:
type: ExternalName
externalName: gateway.eventing.svc.cluster.local
ports:
- name: http
port: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: connector
namespace: test
spec:
hosts:
- connector
- connector.test.svc.cluster.local
http:
- match:
- uri:
prefix: /
route:
- destination:
host: connector
port:
number: 80
#headers config ignored for brevity
命名端口是绝对需要,因为它让 Istio 知道要使用的应用程序协议,由 VirtualService 定义。
无需添加ServiceEntry,它将与VirtualService中指定的BYON主机一起工作。
请注意,@Christoph Raab 提供的答案也有效,但不幸的是过于冗长,无法标记为我的首选答案。
在我目前正在进行的项目中,我想为位于另一个命名空间中的 Kubernetes 服务创建一个 DNS 别名。为此,我创建了一个 ExternalName 服务,如下所示:
kind: Service
apiVersion: v1
metadata:
name: connector
namespace: test
spec:
type: ExternalName
externalName: gateway.eventing.svc.cluster.local
到目前为止,还不错。当我请求 'connector' DNS 时,我成功命中了外部名称,即 gateway.eventing.svc.cluster.local.
现在,我想将 headers 添加到发送到连接器 ExternalName 服务的所有 http 请求,因此我创建了一个 Istio VirtualService 来执行此操作:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: connector
namespace: test
spec:
hosts:
- connector
- connector.test.svc.cluster.local
http:
- match:
- uri:
prefix: /
route:
- destination:
host: connector
port:
number: 80
#headers config ignored for brevity
问题是从未调用 VirtualService。它似乎没有拦截对连接器 DNS 或其完全限定名称的请求,即 connector.test.svc.cluster.local.
我在阅读文档后认为,这是因为 Istio VirtualService 检查服务注册表,而 ExternalName 服务不是其中的一部分,它只是某种 DNS 别名。
因此,我尝试创建一个 Istio ServiceEntry,如下所示:
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: connector
namespace: test
spec:
hosts:
- connector
endpoints:
- address: gateway.eventing.svc.cluster.local
ports:
- number: 80
name: http
protocol: HTTP
location: MESH_INTERNAL
resolution: DNS
它有效,我可以在 Kiali 中看到,在请求连接器时没有调用 PassthroughCluster,而是调用了连接器 ServiceEntry,据我所知应该发生什么。
但是,我的连接器 VirtualService 仍然没有被调用。这是为什么?有办法实现吗?
如果没有,我能做些什么来在给定的命名空间中别名(即测试)位于另一个(即事件)中的服务并通过 Istio VirtualService 代理 http 请求?
在此先感谢您的帮助!
编辑:
Sidecar 注入已启用namespace-wide(即测试)
更新
我没有看到缺少端口列表,我不确定如何应用 yml,因为应该需要该列表。
无论如何,我留下我的答案。也许它会进一步帮助其他人。
原文Post(略有修改)
文档不清楚,但我认为 header 操作可以由接收侧车完成。据我了解您的设置,ServiceEntry 背后的资源没有 sidecar,因此如果这是真的,则操作将不起作用。
为了添加自定义 header,您可以使用类型为 lua
的 EnvoyFilter
,它应用于发件人的 sidecar,并且可以即时操纵流量。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: add-custom-header-filter
namespace: test
spec:
configPatches:
- applyTo: CLUSTER
match:
context: SIDECAR_OUTBOUND
cluster:
service: connector
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
"@type": "type.googleapis.com/envoy.config.filter.http.lua.v2.Lua"
inlineCode: |
function envoy_on_request(request_handle)
response_handle:logInfo("adding custom headers..."");
response_handle:headers():add("X-User-Header", "worked");
end
此过滤器在出站时应用于命名空间 test
中的每个 sidecar 对服务入口连接器的每个请求,并在完成任何其他操作之前添加自定义 header。
因此,事实证明,使它正常工作所缺少的只是在 ExternalName 服务上指定和命名端口。
这是更新后的 yaml:
kind: Service
apiVersion: v1
metadata:
name: connector
namespace: test
spec:
type: ExternalName
externalName: gateway.eventing.svc.cluster.local
ports:
- name: http
port: 80
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: connector
namespace: test
spec:
hosts:
- connector
- connector.test.svc.cluster.local
http:
- match:
- uri:
prefix: /
route:
- destination:
host: connector
port:
number: 80
#headers config ignored for brevity
命名端口是绝对需要,因为它让 Istio 知道要使用的应用程序协议,由 VirtualService 定义。
无需添加ServiceEntry,它将与VirtualService中指定的BYON主机一起工作。
请注意,@Christoph Raab 提供的答案也有效,但不幸的是过于冗长,无法标记为我的首选答案。