I have a requirement where in multiple GRPC services are running on different ports of the same server.
For instance 50051 mapped to 8001, 50052 mapped to 8002, 50053 mapped to 8003 in the config file
I have created Traefik config files (entrypoint, dynamic) and using h2c in the services section.
When I call the Traefik proxy URL say http://1.1.1.1:8001//grpcFunction, I get an error 500 Internal Server Error error="unsupported protocol scheme "h2c""
Can someone please suggest what changes should I make in the config file to support web requests on these different ports
Great to have config files, how about you share them
traefik.yaml
entryPoints:
service1:
address: ":8001"
service2:
address: ":8002"
service3:
address: ":8003"
providers:
file:
filename: /etc/traefik/traefik_dynamic.yaml
api:
dashboard: true
log:
level: DEBUG
filePath: "/etc/traefik/log-file.log"
accessLog: {}
traefik_dynamic.yaml
http:
middlewares:
cors:
headers:
accessControlAllowMethods:
- "GET"
- "POST"
- "OPTIONS"
accessControlAllowHeaders: "*"
accessControlAllowOriginList: "*"
accessControlMaxAge: 100
routers:
service1-router:
entryPoints:
- service1
service: service1
rule: "PathPrefix(`/`)"
middlewares:
- cors
tls: false
service2-router:
entryPoints:
- service2
service: service2
rule: "PathPrefix(`/`)"
middlewares:
- cors
tls: false
service3-router:
entryPoints:
- service3
service: service3
rule: "PathPrefix(`/`)"
middlewares:
- cors
tls: false
services:
service1:
loadBalancer:
servers:
- url: "h2c://localhost:50051"
service2:
loadBalancer:
servers:
- url: "h2c://localhost:50052"
service3:
loadBalancer:
servers:
- url: "h2c://localhost:50053"
And to understand it better, you want protocol translation from external http to internal h2c?
What does Traefik debug log tell you?
So basically what I am expecting is that when a call from the JS web client is executed to the proxy i.e. 1.1.1.1:8001/, service1 should be invoked internally (i.e. 1.1.1.1:50051/)..
But it fails and in the traefik log files, I get the following:
DBG github.com/traefik/traefik/v3/pkg/server/service/proxy.go:100 > 500 Internal Server Error error="unsupported protocol scheme "h2c""
As you see in the dynamic config file, I have the endpoint as h2c and that's what's causing the failure.
Did you compare to the Traefik gRPC example?
I did take a look at the example as well as tried implementing the same but didn't work out for me..
I get 502 Bad Gateway or 404 Not Found error in some cases
Enable and check Traefik access log in JSON format to see if the error status comes from target service directly (OriginStatus
) or only from Traefik sent to browser/client (DownstreamStatus
).
When I set the url as h2c://localhost:50051, I get 500 for OriginStatus as well as DownstreamStatus and when I set the url as http://localhost:50051, I get both as 502
So the error is different now
Usually, when OriginStatus
is set, the error is coming from the target service itself, otherwise it would be empty.
Enable and check Traefik debug log.
Check the logs of your target service, if the requests arrive and what happens.
When using grpcurl to invoke the request directly i.e. 1.1.1.1:50051, it passes but when done via the proxy port i.e. 1.1.1.1:8001, it fails
One more thing I noticed is as per the log below:
{"level":"debug","error":"stream error: stream ID 3; INTERNAL_ERROR; received from peer","time":"2024-09-04T06:18:08Z","caller":"github.com/traefik/traefik/v3/pkg/server/service/proxy.go:100","message":"500 Internal Server Error"}
{"ClientAddr":"10.222.0.93:61664","ClientHost":"10.222.0.93","ClientPort":"61664","ClientUsername":"-","DownstreamContentSize":21,"DownstreamStatus":500,"Duration":40965220,"OriginContentSize":21,"OriginDuration":36731078,"OriginStatus":500,"Overhead":4234142,"RequestAddr":"192.168.121.105:8001","RequestContentSize":40,"RequestCount":1,"RequestHost":"192.168.121.105","RequestMethod":"POST","RequestPath":"/service1/function","RequestPort":"8001","RequestProtocol":"HTTP/1.1","RequestScheme":"http","RetryAttempts":0,"RouterName":"router1@file","ServiceAddr":"localhost:50051","ServiceName":"service1@file","ServiceURL":"h2c://localhost:50051","StartLocal":"2024-09-04T06:18:08.121138138Z","StartUTC":"2024-09-04T06:18:08.121138138Z","entryPointName":"service1","level":"info","msg":"","time":"2024-09-04T06:18:08Z"}
So basically I get STREAM error with curl command
What is happening in your gRPC services? Do they receive something? Is it http or h2c? Is it correctly TLS encrypted? Do requests have the right /package/function path?
In my experience from this forum, h2c is a really complicated beast. People had to write dedicated clients to test it, not just use curl
.
I dont have the service logs. Encryption is disabled.. I have been trying with http as well as h2c.. As I said grpcurl works but unable to invoke via Javascript Web Client