【问题标题】:gRPC & HTTP servers on GKE Ingress failing healthcheck for gRPC backendGKE Ingress 上的 gRPC 和 HTTP 服务器未能对 gRPC 后端进行健康检查
【发布时间】:2019-10-10 04:32:28
【问题描述】:

我想使用 HTTP/2 和双向 TLS 在 GKE 上部署 gRPC + HTTP 服务器。我的部署具有自定义路径的就绪探针和活性探针。我通过 Ingress 公开 gRPC 和 HTTP 服务器。

部署的探针和暴露的端口:

    livenessProbe:
      failureThreshold: 3
      httpGet:
        path: /_ah/health
        port: 8443
        scheme: HTTPS
      periodSeconds: 10
      successThreshold: 1
      timeoutSeconds: 1
    readinessProbe:
      failureThreshold: 3
      httpGet:
        path: /_ah/health
        port: 8443
        scheme: HTTPS
    name: grpc-gke
    ports:
    - containerPort: 8443
      protocol: TCP
    - containerPort: 50052
      protocol: TCP

NodePort 服务:

apiVersion: v1
kind: Service
metadata:
  name: grpc-gke-nodeport
  labels:
    app: grpc-gke
  annotations:
    cloud.google.com/app-protocols: '{"grpc":"HTTP2","http":"HTTP2"}'
    service.alpha.kubernetes.io/app-protocols: '{"grpc":"HTTP2", "http": "HTTP2"}'
spec:
  type: NodePort
  ports:
  - name: grpc
    port: 50052
    protocol: TCP
    targetPort: 50052
  - name: http
    port: 443
    protocol: TCP
    targetPort: 8443
  selector:
    app: grpc-gke

入口:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: grpc-gke-ingress
  annotations:
    kubernetes.io/ingress.allow-http: "false"
    #kubernetes.io/ingress.global-static-ip-name: "grpc-gke-ip"
  labels:
    app: grpc-gke
spec:
  rules:
  - http:
      paths:
      - path: /_ah/*
        backend:
          serviceName: grpc-gke-nodeport
          servicePort: 443
  backend:
    serviceName: grpc-gke-nodeport
    servicePort: 50052

在创建 liveness 和 readiness 探针之前,pod 确实存在,并且处于“绿色”状态。我在我的服务器上看到/_ah/live/_ah/ready 都被kube-probe 调用并且服务器以200 响应响应的常规日志。

我在负载平衡器 (LB) 上使用 Google 托管的 TLS 证书。我的 HTTP 服务器创建了一个自签名证书——灵感来自 this blog

我在开始查看探测日志后创建 Ingress。之后,它会创建一个具有两个后端的 LB,一个用于 HTTP,一个用于 gRPC。 HTTP 后端的运行状况检查正常,并且可以从 Internet 访问 HTTP 服务器。 gRPC 后端的健康检查失败,因此 LB 没有路由 gRPC 协议,我收到了502 错误响应。

这是 GKE 主控 1.12.7-gke.10。我还尝试了新的 1.13 和旧的 1.11 大师。集群启用了 HTTP 负载平衡并启用了 VPC-native。有防火墙规则允许从 LB 访问我的 pod(我什至尝试允许来自所有 IP 地址的所有端口)。延迟探测也无济于事。

有趣的是,我部署了几乎相同的设置,只是服务器的 Docker 映像不同,几个月前它运行没有任何问题。我什至可以部署服务器的新 Docker 映像,一切都很棒。我找不到这两者之间的任何区别。

还有一个问题,Ingress 卡在“Creating Ingress”状态好几天了。它永远不会结束,也永远不会看到 LB。 Ingress 的 LB 从来没有前端,我总是必须手动添加一个带有静态 IP 和 Google 管理的 TLS 证书的 HTTP/2 前端。这应该只发生在没有“HTTP 负载平衡”的情况下创建的集群上,但在我的情况下,每次我的所有“启用了 HTTP 负载平衡”的集群都会发生这种情况。工作部署已经处于这种状态数月了。

任何想法为什么 gRPC 后端的健康检查可能会失败,即使我看到了 kube-probe 调用就绪和活跃端点的日志?

编辑:

describe svc grpc-gke-nodeport

Name:                     grpc-gke-nodeport
Namespace:                default
Labels:                   app=grpc-gke
Annotations:              cloud.google.com/app-protocols: {"grpc":"HTTP2","http":"HTTP2"}
                        kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{"cloud.google.com/app-protocols":"{\"grpc\":\"HTTP2\",\"http\":\"HTTP2\"}",...
                        service.alpha.kubernetes.io/app-protocols: {"grpc":"HTTP2", "http": "HTTP2"}
Selector:                 app=grpc-gke
Type:                     NodePort
IP:                       10.4.8.188
Port:                     grpc  50052/TCP
TargetPort:               50052/TCP
NodePort:                 grpc  32148/TCP
Endpoints:                10.0.0.25:50052
Port:                     http  443/TCP
TargetPort:               8443/TCP
NodePort:                 http  30863/TCP
Endpoints:                10.0.0.25:8443
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

gRPC 后端的运行状况检查是 HTTP/2 GET,使用路径 / 在端口 32148 上。它的描述是“默认 kubernetes L7 负载平衡健康检查”。其中 HTTP 的后端健康检查的描述是“Kubernetes L7 健康检查生成与就绪探测设置。”。因此,gRPC 后端的运行状况检查不是从就绪探针创建的。

编辑运行状况检查以指向端口 30863 并更改准备就绪探测的路径可解决此问题。

【问题讨论】:

  • 我很好奇这是否可能是 LB 健康检查的限制。修改 gRPC HC 以匹配 HTTP 应该可以正常工作,因为我们知道该路径正在响应。我看看能不能找到什么
  • 我还注意到您的就绪和活跃度探测都检查端口 8443,而不是 gRPC。
  • @PatrickW 我需要两个探测器来检查端口 8443,因为我不知道在 gRPC 服务器正在侦听的端口上返回 HTTP/2 响应。我基本上有一个 HTTP 服务器在与 gRPC 服务器相同的二进制文件中侦听 8443,它会根据需要响应不同的运行状况检查。但是 gRPC 后端的 LB HC 忽略了就绪探测设置。
  • 好的,这就是问题所在,HC 不适用于 gRCP 端口。这就是对端口 32148 使用 LB HC 失败的原因。在上面的配置中,只有端口 30863 会产生一个健康的后端。 HTTP/2 仍处于测试阶段,正在努力让 gRPC 充分发挥作用。
  • @PatrickW 我认为应该将 LB HC 设置为就绪探测器的设置。我正在使用创建 LB 的 Ingress。 ...有趣的是,我们已经部署了类似的设置(几个月前,但每周更新)并且“坏”的 LB HC 工作正常。它设置为/ 和 gRPC 后端的 NodePort 端口。奇怪的测试版:)

标签: kubernetes google-kubernetes-engine grpc kubernetes-ingress kubernetes-health-check


【解决方案1】:

编辑健康检查以指向就绪探针的路径并将端口更改为 HTTP 后端之一修复了此问题(在 HTTP 后端的健康检查中查找端口。它是 NodePort 的。) .它运行起来没有任何问题。

对 gRPC 后端使用与 HTTP 后端相同的健康检查不起作用,它被重置为自己的健康检查。即使删除 gRPC 后端的健康检查也无济于事,它被重新创建了。只有编辑它以使用不同的端口和路径才有帮助。

【讨论】:

  • 你能提供更多细节吗?我有一个在 8080 上运行 GRPC 服务器的 go 服务和一个在 8081 上运行 gRPC 网关(我的 gRPC protobuf 定义的镜像 REST)。我目前正在研究 Ingress(GKE),我对访问我的 gRPC 端点有点卡住了
  • @Emixam23 有关在 GKE 中设置 gRPC + HTTP 服务的更多详细信息,请查看本文medium.com/mintensive/…
  • 我整天都在研究它,在过去的两周里,同样的问题..即使我实施了健康检查部分并且它实际上返回了 OK,仍然不起作用..当我与其他人一起工作时,我已经设置了一个公共仓库:github.com/Emixam23/GKE-gRPC-Service-Ingress 为了使它更容易,我删除了网关部分(gRPC Rest Gateway),所以现在我只运行 gRPC 后端
【解决方案2】:

GKE Ingress 最近才开始在测试版中支持完整的 gRPC 支持(而过去使用的是 HTTP2 ro HTTP1.1 转换)。但是,要使用 gRCP,您需要在入口“cloud.google.com/app-protocols: '{"http2-service":"HTTP2"}'" 中添加注释。 Refer to this how-to doc 了解更多详情。

【讨论】:

  • 我在 Ingress 中使用 HTTP2 注释,在旧部署中它可以工作,而在这个部署中它没有。
  • 您能否验证用于 gRPC 后端的运行状况检查是否与您的就绪探测相匹配?可能是 LB 健康检查创建不正确,或者它正在使用之前创建的健康检查。
  • 它与就绪探测不匹配。它从未匹配过它,即使在几个月前部署的工作 gRPC 服务中也是如此。它始终指向/,并使用 gRPC 服务的端口。 HTTP 后端的运行状况检查使用就绪探测。编辑运行状况检查以指向就绪探针的路径并将端口更改为 HTTP 后端之一修复了此问题。但不建议编辑自动生成的健康检查(来自 Ingress)......我从周五早上开始测试这个编辑过的健康检查,它仍在工作......
  • 它们不会完全匹配,就绪探测将是 443,因为您的 lB 的 HC 应该是节点端口(3xxxx)并且它应该使用后端服务的节点端口。它还应该设置为使用 HTTPS 而不是 http。你能用 kubectl describe svc grpc-gke-nodeport 和你的健康检查的定义来更新你的帖子吗
  • LB 的健康检查使用 NodePort 的服务端口作为 gRPC 服务的端口(在本例中为 32148),而不是 HTTP 端口。我切换到 HTTP 30863 的 NodePort 端口并更改了路径。我所有的健康检查都使用 HTTP/2。我已经用您要求的信息更新了问题。有一个有趣的模式,LB 每次在一秒钟内发出三个健康检查请求。
猜你喜欢
  • 2019-11-20
  • 1970-01-01
  • 2022-12-10
  • 2023-01-24
  • 1970-01-01
  • 2019-06-28
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多