注意:本文基于 Envoy Gateway v1.3.2。
Envoy Gateway 构建在 Envoy Proxy 之上,提供了一套丰富的功能。然而,在某些情况下,你可能希望使用 Envoy Proxy 的一些功能,而这些功能并未通过 Envoy Gateway 的 API 暴露出来。这时就可以使用从 Envoy Gateway v0.5.0 引入的 EnvoyPatchPolicy API。它允许你自定义 Envoy Gateway 生成的 xDS 资源。本文将指导你如何启用该 API,并实现一个非常实用的功能 —— 本地响应修改(Local Reply Modification)。
我们将从前置条件开始介绍,然后讲解如何启用 EnvoyPatchPolicy、如何编写自定义响应逻辑,并最终验证效果。
在开始之前,请确保你已正确安装 Envoy Gateway 和示例资源清单。运行以下命令完成环境准备并确保可以通过 HTTP 访问示例 backend:
# 安装 Envoy Gateway 和示例清单
helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.3.2 -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/v1.3.2/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 &
默认情况下,EnvoyPatchPolicy 是关闭的。启用该功能需要创建一个配置文件 ConfigMap,并将其挂载到 Envoy Gateway。执行以下命令:
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
使用 EnvoyPatchPolicy API,你可以修改 Envoy Gateway 生成的 xDS 资源。目前仅支持 JSONPatch 类型。
Envoy 提供了修改本地响应内容的能力,你可以通过配置 mappers 来指定需要变更的响应内容。每个 mapper 包含一个 filter 和多个改写规则,例如:
Envoy 会按顺序处理这些 mapper,匹配成功后即应用对应改写规则。
我们来构建一个案例:当后端返回 404 时,Envoy Gateway 将其替换为 406,并附带一段自定义文本提示。
下面是该案例的架构图:
执行以下配置:
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
type: JSONPatch
jsonPatches:
- type: "type.googleapis.com/envoy.config.listener.v3.Listener"
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
然后我们需要修改示例中的 HTTPRoute,仅匹配 /get
路径:
kubectl patch httproute backend --type=json -n default --patch '[{
"op": "add",
"path": "/spec/rules/0/matches/0/path/value",
"value": "/get",
}]'
接下来我们访问 /find
路径进行验证:
curl --header "Host: www.example.com" http://localhost:8888/find
你将看到如下响应:
could not find what you are looking for
如前所述,由于 EnvoyPatchPolicy 依赖底层的 Envoy 和 Gateway API 结构,未来版本可能存在差异,请关注官方文档并做好兼容性准备。
尽情探索这个强大的扩展机制,让你的 Envoy Gateway 实现更强的可编程能力吧!
最后更新于 2025/04/23