如何在Istio中设置含动态UUID或复用已有头部值的自定义请求头部?
Istio中设置动态/复用请求头的解决方案
一、复用已有请求头的值
Istio的VirtualService不支持直接引用其他请求头变量来拼接新头部,需要通过EnvoyFilter配置Envoy的Lua脚本实现类似Nginx的变量拼接逻辑。
比如要实现proxy_set_header x-custom-header $connection:$connection_requests的效果,可以用以下EnvoyFilter:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: add-custom-header namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway # 针对网关配置,若要给边车生效则修改为对应工作负载标签 configPatches: - applyTo: HTTP_FILTER match: context: GATEWAY # 可选值:GATEWAY/SIDECAR_INBOUND/SIDECAR_OUTBOUND listener: filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inline_code: | function envoy_on_request(request_handle) -- 获取连接ID和该连接的请求计数 local connection_id = request_handle:streamInfo():downstreamConnectionId() local conn_request_count = request_handle:streamInfo():downstreamConnectionRequestCount() -- 拼接后添加自定义请求头 request_handle:headers():add("x-custom-header", connection_id .. ":" .. conn_request_count) end
二、动态生成UUID作为请求头值
VirtualService不支持动态生成UUID,必须通过EnvoyFilter实现,有两种便捷方式:
方式1:Lua脚本生成UUID
通过Lua内置函数生成UUID并注入请求头:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: add-uuid-header namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway configPatches: - applyTo: HTTP_FILTER match: context: GATEWAY listener: filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.lua typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua" inline_code: | -- 生成UUIDv4的Lua函数 function generate_uuid() local template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' return string.gsub(template, '[xy]', function(c) local v = (c == 'x') and math.random(0, 0xf) or math.random(8, 0xb) return string.format('%x', v) end) end function envoy_on_request(request_handle) request_handle:headers():add("x-custom-header", generate_uuid()) end
方式2:使用Envoy内置UUID过滤器
Envoy提供了专门的UUID过滤器,无需编写脚本即可生成UUID:
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: add-uuid-header namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway configPatches: - applyTo: HTTP_FILTER match: context: GATEWAY listener: filterChain: filter: name: "envoy.filters.network.http_connection_manager" subFilter: name: "envoy.filters.http.router" patch: operation: INSERT_BEFORE value: name: envoy.filters.http.uuid typed_config: "@type": "type.googleapis.com/envoy.extensions.filters.http.uuid.v3.UuidConfig" request_header_name: "x-custom-header" # 指定要添加的请求头名称 generate_request_id: true # 启用UUID生成
为什么VirtualService中的{{ uuid() }}不生效?
Istio的VirtualService配置里,请求头的值仅支持静态字符串,不支持模板函数或动态变量解析,所以你输入的'{{ uuid() }}'会被当作字面量直接传递给后端服务,无法生成动态UUID。
内容的提问来源于stack exchange,提问作者aayush kumar
相关产品推荐
相关产品推荐

