гнездо gRPC закрыто на кубернетес с входом - PullRequest
3 голосов
/ 25 апреля 2019

У меня есть сервер 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?

...