Envoy External Processing is a feature that allows you to connect an external processing service to the Envoy filter chain. You can use this external service to process HTTP requests and responses, rather than writing a Wasm plug-in or additional post-processing scripts for an Envoy. This helps ensure flexibility and scalability. This topic describes how to configure and use External Processing in an Envoy proxy.
Prerequisites
HTTPBin application is deployed and can be accessed. A sleep application is deployed as outlined in Related operations.
Mechanism
The following diagram illustrates how an Envoy external processing service manages requests from downstream services and responses from upstream services:
The downstream service ①sends a request to the upstream service. Envoy blocks the request and ②sends it to the external processing service for processing.
The external processing service processes the request and ③returns the result to Envoy.
Envoy processes the request based on the result and ④forwards the request to the upstream service.
The upstream service processes the request and ⑤returns a response to the downstream service. Envoy blocks the response and ⑥forwards it to the external processing server.
The external processing server ⑦processes the response and ⑧returns it to Envoy.
Envoy processes the response based on the results and ⑨forwards the processed response to the downstream service.
Step 1: Write a processing logic for the external processing service
The following code block is a snippet of the core logic code. For the complete sample code, see ext-proc-demo. For more information, see Envoy documentation.
You must write a Dockerfile to package the code of external processing service into an image and upload the image to the image repository before deployment.
Step 2: Deploy the external processing service
In this example, the sample image of the external processing service provided by ASM is used. The service will add the request header x-ext-proc-header: hello-to-asm to the received requests and append the response header x-ext-proc-header: hello-from-asm to the received responses.
Create a file named ext.yaml with the following content.
apiVersion: v1 kind: Service metadata: name: ext-proc labels: app: ext-proc service: ext-proc spec: ports: # The listener ports of the external processing service. - name: grpc port: 9002 targetPort: 9002 selector: app: ext-proc --- apiVersion: apps/v1 kind: Deployment metadata: name: ext-proc spec: replicas: 1 selector: matchLabels: app: ext-proc version: v1 template: metadata: labels: app: ext-proc version: v1 spec: containers: - image: registry-cn-hangzhou.ack.aliyuncs.com/ack-demo/ext-proc:v0.2 imagePullPolicy: IfNotPresent name: ext-proc ports: - containerPort: 9002Run the following command to view the log of the pod and verify whether the external processing service is operational.
kubectl logs ext-proc-64c8xxxxx-xxxxxExpected output:
I1126 06:41:25.467033 1 main.go:52] Starting gRPC server on port :9002The log as shown above indicates that the external processing service is running as expected.
Step 3: Configure the Envoy Filter
Log on to the ASM console. In the left-side navigation pane, choose .
On the Mesh Management page, click the name of the ASM instance. In the left-side navigation pane, choose .
Create an Envoy Filter named httpbin-ext-proc with the following content.
apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter spec: configPatches: - applyTo: HTTP_FILTER match: context: SIDECAR_INBOUND listener: portNumber: 80 filterChain: filter: name: envoy.filters.network.http_connection_manager proxy: proxyVersion: ^MIN_VERSION-MAX_VERSION.* patch: operation: INSERT_BEFORE value: name: envoy.filters.http.ext_proc typed_config: '@type': >- type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor grpc_service: envoy_grpc: cluster_name: outbound|9002||ext-proc.default.svc.cluster.local authority: ext-proc.default.svc.cluster.local processing_mode: request_header_mode: SEND response_header_mode: SEND
Step 4: Access the HTTPBin application for verification
Run the following command to access the HTTPBin application and check the response header.
kubectl exec -it deploy/sleep -- curl httpbin:8000/headers -iExpected output:
HTTP/1.1 200 OK
server: envoy
date: Wed, 11 Dec 2024 06:47:59 GMT
content-type: application/json
content-length: 564
access-control-allow-origin: *
access-control-allow-credentials: true
x-envoy-upstream-service-time: 3
x-ext-proc-header: hello-from-asm
{
"headers": {
"Accept": "*/*",
"Host": "httpbin:8000",
"User-Agent": "curl/8.1.2",
"X-B3-Parentspanid": "5c6dd2cc9312d6bb",
"X-B3-Sampled": "1",
"X-B3-Spanid": "1153a2737cee4434",
"X-B3-Traceid": "baba86b696edc75a5c6dd2cc9312d6bb",
"X-Envoy-Attempt-Count": "1",
"X-Ext-Proc-Header": "hello-to-asm",
"X-Forwarded-Client-Cert": "By=spiffe://cluster.local/ns/default/sa/httpbin;Hash=69d8f267c3c00b4396a83e12d14520acc9dadb1492d660e10f77e94dcad7cb06;Subject=\"\";URI=spiffe://cluster.local/ns/default/sa/sleep"
}
}The output shows that the request header x-ext-proc-header: hello-to-asm is added before the request was forwarded, and the response header x-ext-proc-header: hello-from-asm is added before the response was returned.