Как сделать запрос gRP C через Traefik из внешней сети (вне контейнера docker)? - PullRequest
2 голосов
/ 02 апреля 2020

Я реализовал конфигурацию в docker -компонентном файле, который выглядит следующим образом (все контейнеры находятся в общедоступных c репозиториях, так что вы можете попробовать эту конфигурацию самостоятельно):

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"

В в этой конфигурации у нас есть служба whoami, которая обслуживает запросы http, с правилом префикса пути: /foo и моя собственная служба gRP C, написанная на C# (. NET Core), с правилом префикса маршрута: /ping. gRP C Сервер реализует предварительный контракт, который указан ниже:

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);
}

Когда я делаю запрос "GET" со следующей ссылкой (в веб-браузере, например): http://<my.server.ip.here>/foo все идет хорошо, и я получаю whoami response;

Но когда я связываю доступ gRP C через C# клиента:

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());
}

Я получил ошибку (404, страница не найдена). И я получил ту же ошибку для HTTP-запроса «GET», используя http://<my.server.ip.here>/ping url.

Но когда я делаю запрос gRP C на незащищенный порт 81, используя url: http://<my.server.ip.here>:81, все работает нормально.

Что я делаю не так? Как я могу получить доступ к услуге gRP C через traefik вне сети docker, без сертификата SSL (для целей отладки) или даже с SSL?

PS Спасибо, что дочитали мой вопрос до конца.

1 Ответ

0 голосов
/ 06 апреля 2020

Итак, после нескольких дней «отладки» библиотеки gRP C мы обнаруживаем, что клиент gRP C делает запрос на URL, связанный с пространством имен в протоконтракте, поэтому для моего примера:

http://<my.server.ip.here>/com.example.grpc/greetingNew

Таким образом, мы должны установить PathPrefix для этого типа запросов равным PathPrefix (/com.example.grpc), и все начнет работать.

...