GKE Ingress 上的 gRPC 和 HTTP 服务器未能通过 gRPC 后端的健康检查
gRPC & HTTP servers on GKE Ingress failing healthcheck for gRPC backend
我想在 GKE 上使用 HTTP/2 和双向 TLS 部署一个 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
节点端口服务:
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
在创建活动性和就绪性探测之前,pod 确实存在,并且具有 "green" 状态。我在我的服务器上看到常规日志,其中 /_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 masters。集群启用了 HTTP 负载均衡和 VPC-native。有防火墙规则允许从 LB 访问我的 pods(我什至尝试允许来自所有 IP 地址的所有端口)。延迟探测也无济于事。
有趣的是我部署了几乎相同的设置,只是服务器的 Docker 映像不同,几个月前它是 运行 没有任何问题。我什至可以部署服务器的新 Docker 图像,一切都很棒。我找不到这两者之间的任何区别。
还有一个问题,Ingress 卡在 "Creating Ingress" 状态好几天了。它永远不会完成,也永远不会看到 LB。 Ingress 的 LB 从来没有前端,我总是必须手动添加具有静态 IP 和 Google 托管 TLS 证书的 HTTP/2 前端。这应该只发生在没有 "HTTP load balancing" 的情况下创建的集群,但在我的情况下,每次我的所有 "HTTP load balancing enabled" 集群都会发生。工作部署已处于此状态数月。
知道为什么 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
上的路径 /
。它的描述是 "Default kubernetes L7 Loadbalancing health check.",其中 HTTP 后端健康检查的描述是 "Kubernetes L7 health check generated with readiness probe settings."。因此,gRPC 后端的健康检查不是从就绪探测器创建的。
编辑运行状况检查以指向端口 30863
并更改就绪探测的路径可解决问题。
GKE ingress 最近刚刚开始在测试版中支持完整的 gRPC 支持(而过去使用 HTTP2 到 HTTP1.1 转换)。但是,要使用 gRCP,您需要向入口 "cloud.google.com/app-protocols: '{"http2-service":"HTTP2"}'" 添加注释。
Refer to this how-to doc 了解更多详情。
编辑运行状况检查以指向就绪探测的路径并将端口更改为 HTTP back-end 之一修复了此问题(在 HTTP back-end 的运行状况中查找端口检查。它是 NodePort 的。)。它可以毫无问题地运行。
对 gRPC back-end 使用与 HTTP back-end 相同的健康检查没有用,它被重置回它自己的健康检查。即使删除 gRPC back-end 的健康检查也无济于事,它被重新创建了。只有编辑它以使用不同的端口和路径才有帮助。
我想在 GKE 上使用 HTTP/2 和双向 TLS 部署一个 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
节点端口服务:
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
在创建活动性和就绪性探测之前,pod 确实存在,并且具有 "green" 状态。我在我的服务器上看到常规日志,其中 /_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 masters。集群启用了 HTTP 负载均衡和 VPC-native。有防火墙规则允许从 LB 访问我的 pods(我什至尝试允许来自所有 IP 地址的所有端口)。延迟探测也无济于事。
有趣的是我部署了几乎相同的设置,只是服务器的 Docker 映像不同,几个月前它是 运行 没有任何问题。我什至可以部署服务器的新 Docker 图像,一切都很棒。我找不到这两者之间的任何区别。
还有一个问题,Ingress 卡在 "Creating Ingress" 状态好几天了。它永远不会完成,也永远不会看到 LB。 Ingress 的 LB 从来没有前端,我总是必须手动添加具有静态 IP 和 Google 托管 TLS 证书的 HTTP/2 前端。这应该只发生在没有 "HTTP load balancing" 的情况下创建的集群,但在我的情况下,每次我的所有 "HTTP load balancing enabled" 集群都会发生。工作部署已处于此状态数月。
知道为什么 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
上的路径 /
。它的描述是 "Default kubernetes L7 Loadbalancing health check.",其中 HTTP 后端健康检查的描述是 "Kubernetes L7 health check generated with readiness probe settings."。因此,gRPC 后端的健康检查不是从就绪探测器创建的。
编辑运行状况检查以指向端口 30863
并更改就绪探测的路径可解决问题。
GKE ingress 最近刚刚开始在测试版中支持完整的 gRPC 支持(而过去使用 HTTP2 到 HTTP1.1 转换)。但是,要使用 gRCP,您需要向入口 "cloud.google.com/app-protocols: '{"http2-service":"HTTP2"}'" 添加注释。 Refer to this how-to doc 了解更多详情。
编辑运行状况检查以指向就绪探测的路径并将端口更改为 HTTP back-end 之一修复了此问题(在 HTTP back-end 的运行状况中查找端口检查。它是 NodePort 的。)。它可以毫无问题地运行。
对 gRPC back-end 使用与 HTTP back-end 相同的健康检查没有用,它被重置回它自己的健康检查。即使删除 gRPC back-end 的健康检查也无济于事,它被重新创建了。只有编辑它以使用不同的端口和路径才有帮助。