Envoy 作为 gRPC 外部网关时,TLS 必须在 Envoy 边界终止(推荐),配置 tls_context 并启用 http_connection_manager 的 AUTO 编解码;需显式启用 grpc_web filter 支持前端调用;deadline 需通过 max_stream_duration 和 grpc_timeout_header_max_allowed 透传;健康检查必须使用 grpc.health.v1.Health/Check 接口。

Envoy 作为 gRPC 外部网关时,TLS 终止位置必须明确
gRPC 流量默认走 HTTP/2,而 Envoy 要正确透传或终止 TLS,取决于你希望加密链路在哪断开——是在 Envoy 边界终止(推荐),还是直通后端(不推荐)。多数安全场景下,你应该让 Envoy 做 TLS 终止,后端服务用明文 gRPC 通信,既降低后端复杂度,又便于 Envoy 插入 mTLS、限流、日志等能力。
常见错误现象:grpc-status: 14(UNAVAILABLE)+ transport is closing,往往是因为客户端发的是 HTTPS/gRPC over TLS,但 Envoy 的 listener 没配 tls_context,或者配了却没挂证书;又或者客户端用 https:// 连接,但 Envoy route 指向了 http 后端,导致 ALPN 协商失败。
- Listener 必须启用
http_connection_manager并设置codec_type: AUTO(自动识别 HTTP/1.1 和 HTTP/2) - 若做 TLS 终止,
filter_chains中需包含完整tls_context,且certificates和private_key路径必须可读(如/etc/envoy/certs/tls.crt) - 后端 cluster 的
transport_socket通常设为name: "raw_buffer"(即不加密),除非你真要 Envoy 与后端再套一层 mTLS
gRPC Web 支持不是开箱即用,需显式启用
浏览器原生不支持 HTTP/2,所以前端 JS 调用 gRPC 必须走 gRPC-Web 协议(HTTP/1.1 封装),而 Envoy 默认不处理这种转换。如果你看到 503 NO ROUTE MATCHES 或浏览器控制台报 Failed to fetch,大概率是漏了 gRPC-Web 编码器配置。
使用场景:Vue/React 前端通过 @grpc/grpc-js 或 grpc-web 客户端调用后端 gRPC 服务。
- Envoy 的
http_connection_manager需启用grpc_webfilter:name: envoy.filters.http.grpc_web - route 匹配必须带
grpc: true,否则 Envoy 不会触发解包逻辑 - 后端 cluster 不需要改,但要注意:gRPC-Web 请求头里带
x-grpc-web: 1,而普通 gRPC 不带,别用同一 route 混合处理 - 开发阶段可先用
envoyproxy/go-grpc-web的 proxy 做临时转换,但生产务必由 Envoy 统一承载
gRPC 超时和 deadline 传递容易被 Envoy 截断
gRPC 客户端设置的 deadline(比如 5s)默认不会透传到后端服务——Envoy 的路由级超时(timeout)和重试策略(retry_policy)会覆盖它。结果就是客户端以为等了 5s,其实 Envoy 在 3s 就返回了 DEADLINE_EXCEEDED,而后端根本没收到请求。
性能影响:过度宽松的 timeout 会导致连接堆积;过度激进则引发误判失败。
- 在 route 配置中显式设置
max_stream_duration,并开启grpc_timeout_header_max_allowed,允许客户端通过grpc-timeoutheader 控制实际 deadline - 避免在 cluster 层设
per_connection_buffer_limit_bytes过小,否则大 payload 流水线会被中断,表现为RESOURCE_EXHAUSTED - 如果后端是 Go gRPC server,注意它默认从
grpc-timeoutheader 解析 deadline,而非 Envoy 的 route timeout 字段
健康检查与 gRPC 探针需用专用接口
Envoy 对 upstream 的健康检查(health_check)不能直接用 HTTP GET /health,因为 gRPC 服务不响应非 gRPC 协议的请求。若只配了 HTTP 探针,你会看到 cluster 状态长期为 FAILED_ACTIVE_HC,即使后端进程活着。
兼容性影响:Kubernetes 的 readinessProbe 若仍走 HTTP,会误判服务不可用,触发滚动更新失败。
- 必须启用
envoy.health_checkers.grpc,并在 cluster 中配置grpc_health_check,指向后端实现的grpc.health.v1.Health/Check方法 - 确保后端服务已注册 health check 服务(如 Go 用
grpc-health-probe或内置grpclb插件) - Envoy 的
health_checks下要设timeout: 1s和interval: 5s,避免探针本身成为压力源 - 不要复用同一个 gRPC port 做业务 + 健康检查流量,尤其当启用了 mTLS 时,健康检查 client cert 往往不同
最常被忽略的是:gRPC health check 的请求 body 必须为空(不是 {}),否则某些语言 SDK 会拒绝解析;Envoy 生成的 probe 请求符合规范,但自定义脚本容易栽在这里。










