У меня есть сервер gRPC, который отлично работает на моей локальной машине.Я могу отправлять запросы grpc из приложения python и получать правильные ответы.
Я поместил сервер в кластер GKE (только с одним узлом).У меня был обычный балансировщик нагрузки TCP перед кластером.В этой настройке мой локальный клиент смог получить правильный ответ на некоторые запросы, но не другие.Я думаю, что потоковая передача gRPC не сработала.
Я предположил, что это связано с тем, что для потоковой передачи требуется соединение HTTP / 2, для которого требуется SSL.
Стандартный балансировщик нагрузки, который я получилGKE, похоже, не поддерживает SSL, поэтому я следовал документации, чтобы настроить балансировщик входной нагрузки, который это делает.Я использую сертификат Lets-Encrypt с ним.
Теперь все запросы gRPC возвращают
status = StatusCode.UNAVAILABLE
details = "Сокет закрыт"
debug_error_string = "{" созданный ":" @ 1556172211.931158414 "," description ":" Ошибка получена от узла ipv4: ip.of.ingress.service: 443 "," file ":" src / core / lib/surface/call.cc "," file_line ": 1041," grpc_message ":" Socket closed "," grpc_status ": 14}"
IP-адрес - это внешний IP-адрес моего входаоказание услуг.Входной yaml выглядит следующим образом:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: rev79-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: "rev79-ip"
ingress.gcp.kubernetes.io/pre-shared-cert: "lets-encrypt-rev79"
kubernetes.io/ingress.allow-http: "false" # disable HTTP
spec:
rules:
- host: sub-domain.domain.app
http:
paths:
- path: /*
backend:
serviceName: sandbox-nodes
servicePort: 60000
Субдомен и домен запроса из моего приложения python соответствуют хосту во входном правиле.
Он подключается к узлу-порту, который выглядитнапример:
apiVersion: v1
kind: Service
metadata:
name: sandbox-nodes
spec:
type: NodePort
selector:
app: rev79
environment: sandbox
ports:
- protocol: TCP
port: 60000
targetPort: 9000
Сам узел имеет два контейнера и выглядит следующим образом:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: rev79-sandbox
labels:
app: rev79
environment: sandbox
spec:
replicas: 1
template:
metadata:
labels:
app: rev79
environment: sandbox
spec:
containers:
- name: esp
image: gcr.io/endpoints-release/endpoints-runtime:1.31
args: [
"--http2_port=9000",
"--service=rev79.endpoints.rev79-232812.cloud.goog",
"--rollout_strategy=managed",
"--backend=grpc://0.0.0.0:3011"
]
ports:
- containerPort: 9000
- name: rev79-uac-sandbox
image: gcr.io/rev79-232812/uac:latest
imagePullPolicy: Always
ports:
- containerPort: 3011
env:
- name: RAILS_MASTER_KEY
valueFrom:
secretKeyRef:
name: rev79-secrets
key: rails-master-key
Целевым узлом порта является контейнер ESP, который подключается к службе gRPC, развернутой воблако и серверная часть, которая является приложением Rails, которое реализует серверную часть API.Это приложение rails не запускает сервер rails, а специализированный сервер gRPC, который поставляется с grpc_for_rails
gem
. Grpc_server в приложении Rails не записывает никаких действий в журналах, поэтому я неНе думаю, что запрос зашёл так далеко.
kubectl get ingress
сообщает об этом:
NAME HOSTS ADDRESS PORTS AGE
rev79-ingress sub-domain.domain.app my.static.ip.addr 80 7h
, показывая порт 80, даже если он настроен с SSL.Это похоже на ошибку.Когда я проверяю с curl -kv https://sub-domain.domain.app
, входной сервер обрабатывает запрос нормально и использует HTTP / 2.Он возвращает ошибку сервера в формате HTML, но я не уверен, что это генерирует.
Для API требуется ключ API, который клиент python вставляет в метаданные каждого запроса.
КогдаЯ перехожу на страницу конечных точек моей консоли GCP и вижу, что API не регистрирует никаких запросов с момента ввода входного loadbalancer, поэтому похоже, что запросы не достигают контейнера EPS.
Так почему яполучать ошибки "закрыто гнездо" с помощью gRPC?