TODO: 修改引用
通过使用 EnvoyFilter
自定义资源定义(CRD),你可以自定义请求头和响应头。EnvoyFilter
CRD 允许你直接修改 Istio 代理(Envoy)的配置,从而在请求或响应流经代理时添加、删除或修改其头信息。
前提条件
- 已部署 HTTPBin 应用程序。有关更多信息,请参见部署 HTTPBin 应用程序。
步骤 1:定义 EnvoyFilter 模板
Istio 允许你使用模板创建 EnvoyFilter。这个模板可以用于创建多个 EnvoyFilter,并应用于不同的工作负载和命名空间,提高配置的可重用性和管理效率。
以下是一个 EnvoyFilter 模板的示例。有关更多信息,请参见 EnvoyFilter 参考。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: custom-header-filter-template
namespace: istio-system
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: ANY
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
proxy:
proxyVersion: '^1\.20.*'
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
-- 从请求头中获取指定的键和值
local header_key = "x-custom-request-header" -- 你要获取的请求头的键
local header_value = request_handle:headers():get(header_key)
if header_value then
-- 将数据写入 OpenTelemetry Baggage
local baggage = header_key .. "=" .. header_value
request_handle:headers():add("baggage", baggage)
request_handle:streamInfo():dynamicMetadata():set("envoy.filters.http.lua", "otel.baggage", baggage)
end
end
function envoy_on_response(response_handle)
-- 从动态元数据中获取 OpenTelemetry Baggage
local metadata = response_handle:streamInfo():dynamicMetadata():get("envoy.filters.http.lua") or {}
local baggage = metadata["otel.baggage"]
if baggage then
-- 将 OpenTelemetry Baggage 写入新的响应头
local new_header_key = "x-custom-response-header" -- 新的响应头的键
response_handle:headers():add(new_header_key, baggage)
end
end
注意:
- 将
proxyVersion
字段的值替换为你的 Istio 代理版本(例如,Istio 1.18.x 对应^1\.18.*
)。 - Lua 过滤器中的代码通过添加自定义头信息,基于现有的头和动态元数据来修改请求和响应头。
步骤 2:使用模板创建 EnvoyFilter
定义 EnvoyFilter 模板后,你可以创建一个 EnvoyFilter,将模板应用于特定的工作负载或命名空间。这样,基于该模板创建的 EnvoyFilter 只会影响指定的工作负载或命名空间。
以下示例创建了一个名为 custom-header-filter
的 EnvoyFilter,将 Lua 过滤器应用于 default
命名空间中带有标签 app: httpbin
和 version: v1
的工作负载。
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: custom-header-filter
namespace: default
spec:
workloadSelector:
labels:
app: httpbin
version: v1
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_INBOUND
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
proxy:
proxyVersion: '^1\.20.*'
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
'@type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inlineCode: |
function envoy_on_request(request_handle)
-- 从请求头中获取指定的键和值
local header_key = "x-custom-request-header" -- 你要获取的请求头的键
local header_value = request_handle:headers():get(header_key)
if header_value then
-- 将数据写入 OpenTelemetry Baggage
local baggage = header_key .. "=" .. header_value
request_handle:headers():add("baggage", baggage)
request_handle:streamInfo():dynamicMetadata():set("envoy.filters.http.lua", "otel.baggage", baggage)
end
end
function envoy_on_response(response_handle)
-- 从动态元数据中获取 OpenTelemetry Baggage
local metadata = response_handle:streamInfo():dynamicMetadata():get("envoy.filters.http.lua") or {}
local baggage = metadata["otel.baggage"]
if baggage then
-- 将 OpenTelemetry Baggage 写入新的响应头
local new_header_key = "x-custom-response-header" -- 新的响应头的键
response_handle:headers():add(new_header_key, baggage)
end
end
解释:
workloadSelector
指定了 EnvoyFilter 适用的工作负载,这些工作负载具有标签app: httpbin
和version: v1
。configPatches
部分将模板中定义的 Lua 过滤器应用于指定的工作负载。- 确保元数据中的
namespace
字段与你的工作负载所在的命名空间一致。
重要提示:
EnvoyFilter
是一种强大但复杂的配置方法,它直接修改底层的 Envoy 配置。在使用 EnvoyFilter
时,建议你熟悉 Envoy 的配置模型,并谨慎修改以避免潜在错误。此外,随着 Istio 版本的升级,配置结构可能会发生变化,请注意兼容性问题。
步骤 3:在访问日志中查看自定义的请求头和响应头
Istio 允许你自定义日志格式。你可以在访问日志中获取请求头、响应头和 Envoy 内置变量的值。有关更多信息,请参见自定义访问日志的格式。
以下表格列出了在访问日志中显示内容的自定义字段:
字段 | 类型 | 日志格式表达式 |
---|---|---|
my-x-custom-request-header | 请求属性 | %REQ(x-custom-request-header)% |
baggage-from-request | 请求属性 | %REQ(baggage)% |
my-x-custom-response-header | 响应属性 | %RESP(x-custom-response-header)% |
你可以使用以下命令查看 httpbin
Pod 的访问日志:
kubectl logs -l app=httpbin -c istio-proxy
你将看到类似以下内容的日志:
{
"bytes_received": "0",
"bytes_sent": "490",
"duration": "1",
"method": "GET",
"path": "/headers",
"protocol": "HTTP/1.1",
"response_code": "200",
"response_flags": "-",
"my-x-custom-request-header": "xxx",
"baggage-from-request": "x-custom-request-header=xxx",
"my-x-custom-response-header": "x-custom-request-header=xxx"
}
在这个日志条目中:
my-x-custom-request-header
显示了自定义请求头x-custom-request-header
的值。baggage-from-request
显示了 Lua 过滤器添加的行李(Baggage)信息。my-x-custom-response-header
显示了自定义响应头x-custom-response-header
的值。