Reputation: 41
I implemented configuration in docker-compose file which looks like this (all containers are in a public repositories, so you can try this config by you own):
version: '3'
services:
reverse-proxy:
# The official v2.0 Traefik docker image
image: traefik:v2.2
# Enables the web UI and tells Traefik to listen to docker
command: --api.insecure=true --providers.docker
depends_on:
- ping-service
- whoami
ports:
# The HTTP port
- "80:80"
# The Web UI (enabled by --api.insecure=true)
- "8080:8080"
volumes:
# So that Traefik can listen to the Docker events
- /var/run/docker.sock:/var/run/docker.sock
whoami:
# A container that exposes an API to show its IP address
image: containous/whoami
labels:
- "traefik.http.routers.whoami.rule=PathPrefix(`/foo`)"
ping-service:
image: deadok/vma:pingsvc1.1
environment:
- ms_GrpcServer__Port=80
- ms_GrpcServer__Hostname=0.0.0.0
- GRPC_TRACE=tcp,api,http
- GRPC_VERBOSITY=debug
ports:
- "81:80"
labels:
- "traefik.http.services.ping-service.loadbalancer.server.scheme=h2c"
- "traefik.http.routers.ping-service.rule=PathPrefix(`/ping`)"
rabbit-mq:
image: rabbitmq:3.8.3-management
environment:
- RABBITMQ_DEFAULT_USER=rabbitmq
- RABBITMQ_DEFAULT_PASS=rabbitmq
- RABBITMQ_DEFAULT_VHOST=/
ports:
- "15672:15672"
- "5672:5672"
In this configuration we have whoami service that serves http requests, with path prefix rule: /foo
And my own gRPC service written on C# (.NET Core), with route prefix rule: /ping
.
gRPC Server implements proto contract that listed below:
syntax = "proto3";
package com.example.grpc;
option java_multiple_files = true;
enum Sentiment {
HAPPY = 0;
SLEEPY = 1;
ANGRY = 2;
}
message HelloRequest {
string name = 1;
int32 age = 2;
repeated string hobbies = 3;
map<string, string> bagOfTricks = 4;
Sentiment sentiment = 5;
}
message HelloResponse {
string greeting = 1;
}
message GreetingEmpty {}
// 4. service, unary request/response
service GreetingService {
rpc greeting(HelloRequest) returns (HelloResponse);
rpc greetingNew(GreetingEmpty) returns (HelloResponse);
}
When I make "GET" request with the following link (in web browser for example): http://<my.server.ip.here>/foo
everything goes fine, and i recive whoami response;
But when i tying access gRPC via C# client:
static void Main(string[] args)
{
AppContext.SetSwitch("System.Net.Http.SocketsHttpHandler. Http2UnencryptedSupport", true);
using var channel = GrpcChannel.ForAddress("http://<my.server.ip.here>/ping");
var svc = new Com.Example.Grpc.GreetingService.GreetingServiceClient(channel);
var reply = svc.greetingNew(new Com.Example.Grpc.GreetingEmpty());
}
I've got an error (404, page not found). And i got same error for HTTP "GET" request using http://<my.server.ip.here>/ping
url.
But when I make a gRPC request to exposed port 81, using url: http://<my.server.ip.here>:81
, everything works fine.
What i am doing wrong? How can i access gRPC service through traefik outside of docker network, without SSL cert (for debugging purposes) or even with SSL?
P.S. Thank you for reading my question to the end.
Upvotes: 2
Views: 1523
Reputation: 41
So, after a few day of "debugging" of gRPC library we discover, that gRPC client make request to url assosiated with name space in proto contract, so for my example:
http://<my.server.ip.here>/com.example.grpc/greetingNew
So we should set PathPrefix for this type of requests to PathPrefix(/com.example.grpc
) and everything start working.
Upvotes: 2