Envoy Gateway offers a rich set of functionalities built on top of Envoy Proxy. However, there may be instances where you need to leverage Envoy Proxy’s features that are not exposed in the Envoy Gateway API. Enter the EnvoyPatchPolicy API, introduced in Envoy Gateway 0.5.0, which allows you to customize xDS resources generated by Envoy Gateway. This blog will guide you through enabling the API and implementing a fascinating feature – local reply modification inspired by Envoy Proxy.
We’ll start by outlining the prerequisites before diving into the details of EnvoyPatchPolicy. Then we’ll walk you through enabling the API, customizing response rules, and testing your implementation.
Remember that the API might remain unstable across versions due to potential changes in the Envoy Proxy API or Envoy Gateway’s xDS translation. But with EnvoyPatchPolicy, you can dynamically shape your Envoy Gateway’s behavior, unlocking the platform’s full potential.
Prerequisites
Before diving into EnvoyPatchPolicy, ensure you have Envoy Gateway and the example manifest installed. To get started, you should be able to query the example backend using HTTP. Follow these commands:
# Install Envoy Gateway and the example manifest
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v0.5.0 -n envoy-gateway-system --create-namespace
kubectl wait --timeout=5m -n envoy-gateway-system deployment/envoy-gateway --for=condition=Available
kubectl apply -f <https://github.com/envoyproxy/gateway/releases/download/v0.5.0/quickstart.yaml> -n default
export ENVOY_SERVICE=$(kubectl get svc -n envoy-gateway-system --selector=gateway.envoyproxy.io/owning-gateway-namespace=default,gateway.envoyproxy.io/owning-gateway-name=eg -o jsonpath='{.items[0].metadata.name}')
kubectl -n envoy-gateway-system port-forward service/${ENVOY_SERVICE} 8888:80 &
Enabling EnvoyPatchPolicy
By default, EnvoyPatchPolicy is disabled. To enable it, you need to take a few manual steps. We’ll mount the envoy-gateway-config
ConfigMap in the previously created Envoy Gateway and execute the following commands:
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
name: envoy-gateway-config
namespace: envoy-gateway-system
data:
envoy-gateway.yaml: |
apiVersion: config.gateway.envoyproxy.io/v1alpha1
kind: EnvoyGateway
provider:
type: Kubernetes
gateway:
controllerName: gateway.envoyproxy.io/gatewayclass-controller
extensionApis:
enableEnvoyPatchPolicy: true
EOF
# Restart Envoy Gateway Pod to remount the ConfigMap
kubectl rollout restart deployment envoy-gateway -n envoy-gateway-system
Customizing Responses
You can use the EnvoyPolicyPatch API to modify the generated Envoy xDS resources by Envoy Gateway. But now it only supports the JSONPatch type.
Envoy allows you to customize the local response content it sends back. You can define a list of mappers to specify how these responses should be modified. Each mapper includes a filter and various rewrite rules, such as a status_code rule for altering response codes, a headers_to_add rule for manipulating HTTP headers, a body rule for changing the response body, and a body_format_override rule for specifying the response body format. Envoy processes these mappers in the order specified until the first match is found, applying all applicable rewrite rules.Let’s leverage Envoy Proxy’s Local Reply Modification feature to send a custom response to the client when the status code is 404. Apply the configuration as follows:
cat <<EOF | kubectl apply -f -
apiVersion: gateway.envoyproxy.io/v1alpha1
kind: EnvoyPatchPolicy
metadata:
name:
custom-response-patch-policy
namespace: default
spec:
targetRef:
group: gateway.networking.k8s.io
kind: Gateway
name: eg
namespace: default
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
# The listener name is of the form <GatewayNamespace>/<GatewayName>/<GatewayListenerName>
name: default/eg/http
operation:
op: add
path: "/default_filter_chain/filters/0/typed_config/local_reply_config"
value:
mappers:
- filter:
status_code_filter:
comparison:
op: EQ
value:
default_value: 404
runtime_key: key_b
status_code: 406
body:
inline_string: "could not find what you are looking for"
EOF
Let’s further edit the HTTPRoute resource from Quickstart to match only on paths with the value /get.
kubectl patch httproute backend --type=json -n default --patch '[{
"op": "add",
"path": "/spec/rules/0/matches/0/path/value",
"value": "/get",
}]'
Finally, let’s test it by specifying a path other than /get
.
curl --header "Host: www.example.com" <http://localhost:8888/find>
The response should be could not find what you are looking for
.
It’s essential to note that this API might remain unstable across versions due to potential changes in the Envoy Proxy API or Envoy Gateway’s xDS translation. Be prepared for variations in outcomes as the software evolves.
Enjoy exploring the powerful EnvoyPatchPolicy to shape your Envoy Gateway’s behavior dynamically!