公众号: 尹安灿 欢迎关注交流
因为种种原因,我们需要实现一个将服务名和subset携带在http请求的header里面,根据这个来实现将服务转发去特定的istio的服务的subset。
比如以下example:
-
携带
service: msg-group
tag: gray
的话,将其路由去msg-group 的gray subset。该版本返回数据:
Call Read from msg-group,By New version!!!!
-
携带
service: msg-group
tag: default
的话,将其路由去msg-group 的default subset。改版本返回数据:
Call Read from msg-group
用istio的Virtual Service来实现
大概如下:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: onroute-com
namespace: develop
spec:
gateways:
- msggroup-gateway # 这个gateway - '*'
hosts:
- onroute.com
http:
- match:
- headers:
service:
exact: msg-group
tag:
exact: gray
route:
- destination:
host: msg-group.develop.svc.cluster.local
subset: gray
headers:
response:
set:
test: This value added By static route to gray
- match:
- headers:
service:
exact: msg-group
route:
- destination:
host: msg-group.develop.svc.cluster.local
subset: default
headers:
response:
set:
test: This value added By static route default
请求构造及结果如下:
注:10.99.20.74
是istio-ingressgateway的IP
请求 msg-group 的 gray
版本
# curl -v -H "Host: onroute.com" -H "service: msg-group" -H "tag: gray" 10.99.20.74/read
* Trying 10.99.20.74:80...
* Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
> GET /read HTTP/1.1
> Host: onroute.com
> User-Agent: curl/7.77.0
> Accept: */*
> service: msg-group
> tag: gray
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 43
< date: Fri, 16 Sep 2022 07:36:35 GMT
< x-envoy-upstream-service-time: 7
< server: istio-envoy
< test: This value added By static route to gray
<
* Connection #0 to host 10.99.20.74 left intact
Call Read from msg-group,By New version!!!!%
请求 msg-group 的 default
版本
curl -v -H "Host: onroute.com" -H "service: msg-group" -H "tag: default" 10.99.20.74/read
* Trying 10.99.20.74:80...
* Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
> GET /read HTTP/1.1
> Host: onroute.com
> User-Agent: curl/7.77.0
> Accept: */*
> service: msg-group
> tag: default
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 24
< date: Fri, 16 Sep 2022 07:38:41 GMT
< x-envoy-upstream-service-time: 12
< server: istio-envoy
< test: This value added By static route default
<
* Connection #0 to host 10.99.20.74 left intact
Call Read from msg-group%
能实现问题,但是有几个小问题
- 配置不够灵活,如果面对几百个服务,配置是个巨大的工作量。
- 不同的namespace要配置不同的规则。
用Envoy Filter + Lua来实现
针对上面提到的问题,如果用EnvoyFiltter来实现动态的路由的话,就可以解决这个问题。
解决思路都是围绕config.route.v3.RouteAction cluster_header 这个字段来的
(string) Envoy will determine the cluster to route to by reading the value of the HTTP header named by cluster_header from the request headers. If the header is not found or the referenced cluster does not exist, Envoy will return a 404 response.
- 设置route的cluster_header字段为
x-service
- 从header读取service和tag的值组合出upstream cluster格式,并将
x-service
头替换为它
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: onroute-routing
namespace: istio-system
spec:
workloadSelector:
labels:
istio: ingressgateway
configPatches:
- applyTo: VIRTUAL_HOST
match:
context: GATEWAY
patch:
operation: ADD
value:
name: dynamic_routing
domains:
- 'onroute.com'
- 'onroute.com:*'
routes:
- name: "path-matching"
match:
prefix: "/"
route:
cluster_header: "x-service"
- applyTo: HTTP_FILTER
match:
context: GATEWAY
listener:
filterChain:
filter:
name: "envoy.http_connection_manager"
subFilter:
name: "envoy.router"
patch:
operation: INSERT_BEFORE
value:
name: envoy.service-helper
typed_config:
"@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua"
inlineCode: |
function envoy_on_request(request_handle)
local headers = request_handle:headers()
local mesh_service = headers:get("service")
local tag = headers:get("tag")
if mesh_service ~= nil then
if tag ~= nil then
request_handle:headers():replace("x-service", "outbound|80|" .. tag .. "|" .. mesh_service .. ".svc.cluster.local")
end
end
end
function envoy_on_response(response_handle)
response_handle:headers():add("test", "from envoy filter response")
end
下面是测试结果:
请求 msg-group的 gray
版本
curl -v -H "Host: onroute.com" -H "service: msg-group.develop" -H "tag: gray" 10.99.20.74/read
* Trying 10.99.20.74:80...
* Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
> GET /read HTTP/1.1
> Host: onroute.com
> User-Agent: curl/7.77.0
> Accept: */*
> service: msg-group.develop
> tag: gray
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 43
< date: Fri, 16 Sep 2022 08:07:29 GMT
< x-envoy-upstream-service-time: 16
< server: istio-envoy
< test: from envoy filter response
<
* Connection #0 to host 10.99.20.74 left intact
Call Read from msg-group,By New version!!!!%
请求 msg-group的 default
版本
curl -v -H "Host: onroute.com" -H "service: msg-group.develop" -H "tag: default" 10.99.20.74/read
* Trying 10.99.20.74:80...
* Connected to 10.99.20.74 (10.99.20.74) port 80 (#0)
> GET /read HTTP/1.1
> Host: onroute.com
> User-Agent: curl/7.77.0
> Accept: */*
> service: msg-group.develop
> tag: default
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-type: text/plain;charset=UTF-8
< content-length: 24
< date: Fri, 16 Sep 2022 08:12:40 GMT
< x-envoy-upstream-service-time: 14
< server: istio-envoy
< test: from envoy filter response
<
* Connection #0 to host 10.99.20.74 left intact
Call Read from msg-group%