Контекст
Я разработал сервер gRP C в Java и соответствующий клиент gRP C в C#. Цель состоит в том, чтобы вызвать сервер gRP C с нескольких клиентов gRP C, развернутых на Windows машинах.
Посмотрев, как поддерживается gRP C в Azure, AWS, и Google Cloud Platform (GCP), я, скорее всего, буду размещать сервер gRP C в GCP. Поэтому в настоящее время я тестирую сценарий развертывания для сервера gRP C, как описано Google в руководстве по gRP C на Compute Engine . Короче говоря, это означает, что сервер gRP C работает в специально сконструированном контейнере Docker на виртуальной машине (ВМ) Google Compute Engine (GCE), рядом с прокси расширяемого сервиса (ESP), который работает в собственный предварительно сконфигурированный контейнер Docker на той же виртуальной машине.
Важным аспектом для использования в работе является возможность установить sh безопасный канал связи между клиентами gRP C и gRP * 1086. * сервер, использующий SSL / TSL. Вот где у меня возникают проблемы в сценарии облачного хостинга (но не в сценарии с автономным хостингом, где это прекрасно работает).
Что работает на данный момент? * Клиент gRP C, работающий на моем локальном компьютере Windows 10, успешно обменивается данными с сервером gRP C: через безопасный SSL / TLS канал , если я самостоятельно размещаю сервер на моей локальной Windows 10 машине; и через небезопасный канал в случае, если я размещаю сервер на GCE , как описано выше. Я выполнил следующие команды на виртуальной машине GCE для создания контейнеров docker для успешного взаимодействия клиент-сервер по небезопасному каналу . # Create the container network.
sudo docker network create --driver bridge esp_net
# Create dss-signer container from docker image.
# The Java gRPC service listens on port 50051 (see esp container below).
sudo docker run \
--detach \
--name=dss-signer \
--net=esp_net \
gcr.io/[my-project-name]/dss-signer:1.1
# Create Extensible Service Proxy (ESP) container from predefined docker image.
# The ESP container's port 9000 is published as port 80 on the host machine,
# meaning a client will have to connect to port 80 on the host machine.
sudo docker run \
--detach \
--name=esp \
--publish 80:9000 \
--net esp_net \
gcr.io/endpoints-release/endpoints-runtime:1 \
--service=signer.endpoints.[my-project-name].cloud.goog \
--rollout_strategy=managed \
--http2_port=9000 \
--backend=grpc://dss-signer:50051
Таким образом Я бы сказал, что это работает в целом, и нет никаких проблем в коде Java или C# как таковых (за исключением вопросов, связанных с настройкой, связанных с его работой через SSL / TLS). Что не работает?
Мне не удалось установить безопасный канал между клиентом и сервером gRP C, следуя описанию в Включение SSL . Мой C# клиент всегда выдает следующее исключение:
Grpc.Core.RpcException
HResult=0x80131500
Message=Status(StatusCode=Unavailable, Detail="failed to connect to all addresses")
Source=mscorlib
StackTrace:
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.ConfiguredTaskAwaitable.ConfiguredTaskAwaiter.GetResult()
at SignerClient.AbstractSignatureHandler.<InitiateCall>d__4.MoveNext()
[Rest of stack trace removed as it did not contain any helpful hints.]
Что я пробовал?
Вот команда openssl
, используемая для создания ключа и сертификата сервера. В качестве общего имени я использую IP-адрес виртуальной машины GCE, отображаемый в облачной консоли Google. Я скопировал ключ и сертификат в каталог /etc/nginx/ssl
.
openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ./nginx.key -out ./nginx.crt -subj "/O=[My Org]/OU=Servers/CN=[GCE VM IP Address]"
Вот команда docker
для создания и запуска контейнера ESP docker, которая, насколько я понимаю, нужна изменить для включения SSL / TLS. Это также означает, что я не изменил «бэкэнд» сервер gRP C по сравнению с тем, что я описал выше. Не уверен, что это правильно.
sudo docker run \
--detach \
--name=esp \
--publish 443:443 \
--net esp_net \
--volume=/etc/nginx/ssl:/etc/nginx/ssl \
gcr.io/endpoints-release/endpoints-runtime:1 \
--service=signer.endpoints.[my-project-name].cloud.goog \
--rollout_strategy=managed \
--ssl_port=443 \
--backend=grpc://dss-signer:50051
Вот код C#, используемый для настройки безопасного канала на стороне клиента:
const string host = "[GCE VM IP Address]";
const int port = 443;
// Create the SSL credentials.
string caCertPem = File.ReadAllText("Certs\\ca.cer");
string clientCertPem = File.ReadAllText("Certs\\client.cer");
string clientKeyPem = File.ReadAllText("Certs\\client.key");
var keyCertificatePair = new KeyCertificatePair(clientCertPem, clientKeyPem);
var sslCredentials = new SslCredentials(caCertPem, keyCertificatePair);
// Create a client that communicates over a secure channel.
var channel = new Channel(host, port, sslCredentials);
Я также пробовал варианты вышеуказанной команды docker
, например, с использованием другого порта SSL (8080) или с сохранением настройки http2_port
. К сожалению, ничего не помогло.
Таким образом, как мне настроить это так, чтобы клиент gRP C и сервер, размещенный на GCE, могли безопасно общаться по SSL / TSL? Нужно ли настраивать клиент C# и сервер Java по-разному? Как мне настроить контейнер ESP docker?