无法通过Envoy实现gRPC转HTTP/JSON,连接请求遭拒绝
Envoy代理gRPC转REST连接拒绝问题排查
我尝试通过REST访问gRPC服务,已搭建Envoy服务器,但既无法访问Envoy管理控制台,也无法通过REST调用gRPC服务,请求连接被拒绝。相关配置及运行信息如下:
Envoy配置文件
admin: access_log_path: /tmp/admin_access.log address: socket_address: { address: 0.0.0.0, port_value: 9901 } #1 static_resources: listeners: - name: main-listener address: socket_address: { address: 0.0.0.0, port_value: 51051 } #2 filter_chains: - filters: - name: envoy.http_connection_manager typed_config: "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager stat_prefix: grpc_json codec_type: AUTO route_config: name: local_route virtual_hosts: - name: local_service domains: [ "*" ] routes: - match: { prefix: "/" , grpc: { } } # 仅转发匹配gRPC服务定义的请求,其他返回404 route: { cluster: grpc-backend-services, timeout: { seconds: 60 } } #3b http_filters: - name: envoy.grpc_json_transcoder typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.grpc_json_transcoder.v3.GrpcJsonTranscoder proto_descriptor: "/data/reservation_service_definition.pb" #4 services: [ "reservations.v1.ReservationService" ] #5 print_options: add_whitespace: true always_print_primitive_fields: true always_print_enums_as_ints: false preserve_proto_field_names: false #6 - name: envoy.filters.http.router typed_config: "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router clusters: - name: grpc-backend-services type: LOGICAL_DNS lb_policy: ROUND_ROBIN dns_lookup_family: V4_ONLY typed_extension_protocol_options: envoy.extensions.upstreams.http.v3.HttpProtocolOptions: "@type": type.googleapis.com/envoy.extensions.upstreams.http.v3.HttpProtocolOptions explicit_http_config: http2_protocol_options: { } load_assignment: cluster_name: grpc endpoints: - lb_endpoints: - endpoint: address: socket_address: address: host.docker.internal port_value: 9091
运行环境信息
- gRPC服务运行在9091端口
- Envoy容器运行状态:
pushpak.mittal@BLRJPT121327LT grpc-server % docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5a2ec1db0b54 envoyproxy/envoy:dev-6c702f45fadf4abd2f24605e3d9e81c748b13f85 "/docker-entrypoint.…" 42 minutes ago Up 42 minutes envoy
- Docker启动命令:
docker run -it --rm --name envoy --network="host"\ -v "$(pwd)/reservation_service_definition.pb:/data/reservation_service_definition.pb:ro" \ -v "$(pwd)/envoy-config.yml:/etc/envoy/envoy.yaml:ro" \ envoyproxy/envoy:dev-6c702f45fadf4abd2f24605e3d9e81c748b13f85
请求与响应
POST请求:
curl -X POST \ http://localhost:51051/v1/reservations \ -H 'Content-Type: application/json' \ -d '{ "title": "Lunchmeeting2", "venue": "JDriven Coltbaan 3", "room": "atrium", "timestamp": "2018-10-10T11:12:13", "attendees": [ { "ssn": "1234567890", "firstName": "Jimmy", "lastName": "Jones" }, { "ssn": "9999999999", "firstName": "Dennis", "lastName": "Richie" } ] }'
响应结果:
curl: (7) Failed to connect to localhost port 51051 after 8 ms: Connection refused
问题排查与修复
1. Docker网络模式不兼容(Mac环境)
你使用了--network="host"启动Envoy,但MacOS上Docker的host网络模式无法让宿主机直接访问容器内的端口,这是导致连接被拒绝的核心原因。
修复方案:
移除--network="host"参数,改用端口映射将容器内的端口暴露到宿主机:
docker run -it --rm --name envoy \ -p 9901:9901 -p 51051:51051 \ -v "$(pwd)/reservation_service_definition.pb:/data/reservation_service_definition.pb:ro" \ -v "$(pwd)/envoy-config.yml:/etc/envoy/envoy.yaml:ro" \ envoyproxy/envoy:dev-6c702f45fadf4abd2f24605e3d9e81c748b13f85
2. Envoy集群配置不匹配
配置文件中clusters的load_assignment字段里,cluster_name值为grpc,但对应的集群实际名称是grpc-backend-services,两者不匹配会导致Envoy无法正确识别后端服务配置。
修复方案:
修改配置文件中load_assignment的cluster_name为集群实际名称:
clusters: - name: grpc-backend-services # ... 其他配置保持不变 load_assignment: cluster_name: grpc-backend-services # 修改此处与集群名称一致 endpoints: - lb_endpoints: - endpoint: address: socket_address: address: host.docker.internal port_value: 9091
3. 验证修复效果
重新启动Envoy后,执行docker ps查看端口映射状态:
pushpak.mittal@BLRJPT121327LT grpc-server % docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES xxxxxxxxx envoyproxy/envoy:dev-6c702f45fadf4abd2f24605e3d9e81c748b13f85 "/docker-entrypoint.…" 1 minute ago Up 1 minute 0.0.0.0:51051->51051/tcp, 0.0.0.0:9901->9901/tcp, 10000/tcp envoy
确认PORTS列显示正确的端口映射后,先测试管理控制台:
curl http://localhost:9901
再重新发送POST请求验证gRPC转REST功能。
内容的提问来源于stack exchange,提问作者Pushpak
相关产品推荐
相关产品推荐

