EnvoyFilter CustomResourceDefinition(CRD)を使用して、リクエストヘッダーとレスポンスヘッダーをカスタマイズできます。 EnvoyFilter CRD を使用すると、Istio プロキシ(Envoy)の構成を直接変更できます。 この方法で、リクエストまたはレスポンスがプロキシを通過するときに、リクエストヘッダーまたはレスポンスヘッダーを追加、削除、または変更できます。
手順 1:Envoy フィルターテンプレートを定義する
ASM を使用すると、Envoy フィルターテンプレートを使用して Envoy フィルターを作成できます。 同じ Envoy フィルターテンプレートを使用して複数の Envoy フィルターを作成でき、これらの Envoy フィルターを異なるワークロードと名前空間に適用できます。 これにより、構成を再利用でき、管理効率が向上します。
次の YAML コードは、Envoy フィルターテンプレートの例を示しています。 詳細については、Envoy Filterをご参照ください。
展開して Envoy フィルターテンプレートの YAML コードを表示する
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: custom-header-filter
namespace: my-namespace
spec:
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
-- Otel 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)
-- 動的メタデータから Otel Baggage を取得します。
local metadata = response_handle:streamInfo():dynamicMetadata():get("envoy.filters.http.lua") or {}
local baggage = metadata["otel.baggage"]
if baggage then
-- Otel Baggage を別のヘッダーに書き込みます。
local new_header_key = "x-custom-response-header" -- 新しいレスポンスヘッダーのキー
response_handle:headers():add(new_header_key, baggage)
end
end
workloadSelector:
labels:
app: httpbin
version: v1
Istio 1.9 以降を使用している場合は、proxyVersion フィールドの値を Istio のバージョンに置き換えます。
Istio 1.8 以前のバージョンを使用している場合は、proxyVersion フィールドの値を Istio のバージョンに置き換えます。 さらに、上記の YAML コードで、envoy.filters.network.http_connection_manager を envoy.http_connection_manager に、envoy.filters.http.router を envoy.router に、type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua を type.googleapis.com/envoy.config.filter.http.lua.v2.Lua に置き換えます。
手順 2:Envoy フィルターテンプレートを使用して Envoy フィルターを作成する
Envoy フィルターテンプレートを作成したら、Envoy フィルターテンプレートをワークロードまたは名前空間にバインドする必要があります。 このようにして、このテンプレートに基づいて作成された Envoy フィルターは、指定されたワークロードまたは名前空間に対してのみ有効になります。 Envoy フィルターテンプレートをワークロードまたは名前空間にバインドすると、ASM はテンプレートを使用して Envoy フィルターを自動的に作成します。
作成された Envoy フィルターは、ワークロードに入るリクエストにカスタムリクエストヘッダーを追加し、ワークロードによって送信されるレスポンスにカスタムレスポンスヘッダーを追加します。 次の例では、custom-header-filter という名前の Envoy フィルターを作成し、リクエストヘッダーとレスポンスヘッダーを追加する Lua フィルターを構成します。 Envoy フィルターは、app: my-app ラベルが付いたすべてのワークロードに対して有効になります。
展開して Envoy フィルターの YAML コードを表示する
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: custom-header-filter
namespace: my-namespace
spec:
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
-- データを Otel 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)
-- 動的メタデータから Otel Baggage を取得します。
local metadata = response_handle:streamInfo():dynamicMetadata():get("envoy.filters.http.lua") or {}
local baggage = metadata["otel.baggage"]
if baggage then
-- Otel Baggage を別のヘッダーに書き込みます。
local new_header_key = "x-custom-response-header" -- 新しいレスポンスヘッダーのキー
response_handle:headers():add(new_header_key, baggage)
end
end
workloadSelector:
labels:
app: httpbin
version: v1
重要 EnvoyFilter は強力ですが複雑な構成方法です。 基礎となる Envoy 構成を直接変更します。 したがって、EnvoyFilter を使用する場合は、Envoy の構成モデルをよく理解し、潜在的なエラーを回避するために注意深く変更することをお勧めします。 また、EnvoyFilter の構成は、Istio バージョンのアップグレードに伴って変更される場合があります。 互換性の問題に注意してください。
手順 3:アクセスログでカスタムリクエストヘッダーとカスタムレスポンスヘッダーを表示する
ASM を使用すると、ログ形式をカスタマイズできます。 アクセスログのカスタム式は、リクエストヘッダー、レスポンスヘッダー、および Envoy の組み込み値から値を取得できます。 詳細については、アクセスログの形式のカスタマイズをご参照ください。
次の表に、アクセスログにコンテンツを表示するために使用される 3 つの新しいフィールドを示します。
フィールド | タイプ | 値 |
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 ポッドのアクセスログを確認すると、次のようなコンテンツが表示されます。
{
"bytes_received": "0",
"bytes_sent": "490",
"duration": "1",
"istio_policy_status": "-",
"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",
}